I have set up a simple intent
{
"interactionModel": {
"languageModel": {
"invocationName": "viva bank",
"intents": [
...builtin intents...{
"name": "ask",
"slots": [{
"name": "question",
"type": "AMAZON.SearchQuery"
}],
"samples": [
"when {question}",
"how to {question}",
"what {question}"
]
}
],
"types": []
}
}
}
But when I ask a question it gives me a generic error response like this:
Me: alexa ask viva bank when is the late fee charged
Alexa: Sorry, I don't know that.
Here is my lambda code, but I don't think it is getting that far.
'use strict';
const Alexa = require('ask-sdk-core');
var https = require('https');
var querystring = require('querystring');
const APP_ID = 'amzn1.ask.skill.1234';
const AskIntentHandler = {
canHandle(handlerInput) {
return !!handlerInput.requestEnvelope.request.intent.slots['question'].value;
},
handle(handlerInput) {
var question = handlerInput.requestEnvelope.request.intent.slots['question'].value;
console.log('mydata:', question);
var responseString = '';
const subscription_key = 'XXXX';
var data = {
simplequery: question,
channel: 'Alexa'
};
var get_options = {
headers: {
'Subscription-Key': subscription_key
}
};
https.get('https://fakeapi.com/' + querystring.stringify(data), get_options, (res) => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
res.on('data', (d) => {
responseString += d;
});
res.on('end', function(res) {
var json_hash = JSON.parse(responseString);
// grab the first answer returned as text and have Alexa read it
const speechOutput = json_hash['results'][0]['content']['text'];
console.log('==> Answering: ', speechOutput);
// speak the output
return handlerInput.responseBuilder.speak(speechOutput).getResponse();
});
}).on('error', (e) => {
console.error(e);
return handlerInput.responseBuilder.speak("I'm sorry I ran into an error").getResponse();
});
}
};
exports.handler = (event, context) => {
const alexa = Alexa.handler(event, context);
alexa.APP_ID = APP_ID;
alexa.registerHandlers(AskIntentHandler);
alexa.execute();
};
I'm really just looking to create a very simple pass through, where a question is asked to Alexa, and then I pipe that to an external API and have Alexa read the response.
You can make the question slot value as required if it is mandatory for the intent and you need to include the intent name. You can use async/await to handle the API.
const Alexa = require('ask-sdk-core');
const https = require('https');
const querystring = require('querystring');
const { getSlotValue } = Alexa;
const APP_ID = 'amzn1.ask.skill.1234';
const AskIntentHandler = {
canHandle(handlerInput) {
return (
handlerInput.requestEnvelope.request.type === "IntentRequest" &&
handlerInput.requestEnvelope.request.intent.name === "AskIntent"
);
},
async handle(handlerInput) {
const question = getSlotValue(handlerInput.requestEnvelope, "question");
console.log("question ", question);
const data = await getAnswer(question);
const speechText = data;
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.getResponse();
}
};
const getAnswer = question => {
const subscription_key = "XXXX";
let data = {
simplequery: question,
channel: "Alexa"
};
let get_options = {
headers: {
"Subscription-Key": subscription_key
}
};
return new Promise((resolve, reject) => {
https
.get(
"https://fakeapi.com/" + querystring.stringify(data),
get_options,
res => {
console.log("statusCode:", res.statusCode);
console.log("headers:", res.headers);
res.on("data", d => {
responseString += d;
});
res.on("end", function(res) {
var json_hash = JSON.parse(responseString);
// grab the first answer returned as text and have Alexa read it
const speechOutput = json_hash["results"][0]["content"]["text"];
console.log("==> Answering: ", speechOutput);
resolve(speechOutput);
});
}
)
.on("error", e => {
console.error(e);
resolve("I'm sorry I ran into an error");
});
});
};