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 😊
Top comments (6)
it says 'logic is not defined' on mine
You need to import it
Hi, do you mean import it at the top of the file, like ‘const logic = ..’ how would I write it, thanks
const logic = require('./logic');
and place your logic.js file on the same directory
Hey my skill keeps crashing or saying 'There was a problem with the requested skill's response' since doing this but when I take it off
it doesnt say that, not sure if I've done something wrong