Let’s see how we can do API calls through Alexa, using the Axios library. Although this can be done using other libraries or even the build-in fetch API.
Axios is a promise-based HTTP client that works both in the browser and in a Node. js environment.
It provides a single API for dealing with XMLHttpRequests and node’s http interface.
First, we need an Intent to invoke our function. I Will call it FetchJokesIntent it will be added from the amazon developer console, & to make our example as simple as possible let's add one utterance “I want a joke” 😊
en-US.json:
{
"name": "FetchJokesIntent",
"slots": [],
"samples": [
"i want a joke"
]
}
Let’s see our API helper function, but before that, the Axios dependency will be added in the package.json file
package.json:
"dependencies": {
"ask-sdk-core": "^2.6.0",
"ask-sdk-model": "^1.18.0",
"aws-sdk": "^2.326.0",
"axios": "^0.21.1"
}
logic.js:
const axios = require('axios');
module.exports.fetchJokesApi = async function fetchJokesApi() {
let endpoint = 'http://api.icndb.com';
let url = endpoint + '/jokes/random';
let config = {
timeout: 6500
}
try {
let response = await axios.get(url, config);
return response.data;
} catch (error) {
console.log('ERROR', error);
return null;
}
}
We can log our API responses & view the logs on CloudWatch (Amazon CloudWatch is a monitoring and management service), this is an example of our response data:
An intent represents an action that fulfills a user’s spoken request.
Our intent function where we are calling the API:
index.js:
const FetchJokesHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === 'FetchJokesIntent';
},
async handle(handlerInput) {
let response = await logic.fetchJokesApi();
let speakOutput = response.value.joke;
return handlerInput.responseBuilder
.speak(speakOutput)
.getResponse();
}
};
The result 😁
Now to make our function a bit interesting let's try using more API filters, and a voice input that the user can enter. We will use the predefined slot value AMAZON.SearchQuery (for words and phrases that a customer might use when searching for information. Skills that incorporate short messages, comments, search queries, and other short free-form text can now leverage this phrase slot)
let's add first the utterance and the slot with its type
en-US.json:
{
"name": "FetchJokesIntent",
"slots": [
{
"name": "UserInput",
"type": "AMAZON.SearchQuery"
}
],
"samples": [
"I want a joke of {UserInput}",
"i want a joke"
]
}
Now our code looks like this, take the slot value, and split the text into two words (firstName & lastName) that will be passed as parameters to the API
index.js:
const FetchJokesHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === 'FetchJokesIntent';
},
async handle(handlerInput) {
const slotValue = handlerInput.requestEnvelope.request.intent.slots.UserInput.value;
let filterData = slotValue.split(" ");
let response = await logic.fetchJokesApi(filterData[0], filterData[1]);
let speakOutput = response.value.joke;
return handlerInput.responseBuilder
.speak(speakOutput)
.getResponse();
}
};
logic.js:
const axios = require('axios');
module.exports.fetchJokesApi = async function fetchJokesApi(first, last) {
let endpoint = 'http://api.icndb.com';
let resource = '/jokes/random';
let filter = `?firstName=${first}&lastName=${last}`;
let url = endpoint + resource + filter;
let config = {
timeout: 6500
}
try {
let response = await axios.get(url, config);
return response.data;
} catch (error) {
console.log('ERROR', error);
return null;
}
}
Hopefully, this article helps you to make API requests. Thank you 😊