Node.js Lambda function returns "Response is not valid" back to Alexa Service Simulator from REST call
Are you having trouble making a REST call to an API between node.js lambda function and Alexa. I am using the request library to make calls with an account related skill. I just set up one example statement for intent and the simulator saw it perfectly.
Also, cloudwatch logs show the 200 response code from the api endpoint and any returned data from the API from console.logs in the CW.
'use strict';
var http = require('http');
var request = require('request');
var Alexa = require('alexa-sdk');
var APP_ID = "amzn1.ask.skill.XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX";
exports.handler = function(event, context, callback) {
var alexa = Alexa.handler(event, context);
alexa.appId = APP_ID;
alexa.registerHandlers(handlers);
alexa.execute();
};
var handlers = {
'LaunchRequest': function () {
this.emit(':tell', 'Hi!');
},
'ApiWelcomeIntent': function () {
request('https://some.web/api', function (error, response, body) {
if (!error && response.statusCode == 200) {
// from within the callback, write data to response, essentially returning it.
var speechOutput = JSON.stringify(body);
console.log(body + " :Raw output?");
console.log(speechOutput + ' :JSON stringified');
console.log(response.statusCode);
this.emit(':tell', speechOutput);
} else {
console.log(error + ' : ' + response.statusCode);
this.emit(':tell', 'There was an error');
}
});
},
'AMAZON.HelpIntent': function () {} //.........And other built in intents.
}
};
I'm guessing it has something to do with the speechOutput format I'm asking Alexa to "emit / tell"?
source to share
No, it has nothing to do with the speechOutput format. The problem is that when the method callback request
is executed, the reference to this
is lost. To solve this problem, keep a reference to this
before calling request
(for example, assign a this
variable with a name self
):
'use strict';
var http = require('http');
var request = require('request');
var Alexa = require('alexa-sdk');
var APP_ID = "amzn1.ask.skill.XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX";
exports.handler = function(event, context, callback) {
var alexa = Alexa.handler(event, context);
alexa.appId = APP_ID;
alexa.registerHandlers(handlers);
alexa.execute();
};
var handlers = {
'LaunchRequest': function () {
this.emit(':tell', 'Hi!');
},
'ApiWelcomeIntent': function () {
self = this
request('https://some.web/api', function (error, response, body) {
if (!error && response.statusCode == 200) {
// from within the callback, write data to response, essentially returning it.
var speechOutput = JSON.stringify(body);
console.log(body + " :Raw output?");
console.log(speechOutput + ' :JSON stringified');
console.log(response.statusCode);
self.emit(':tell', speechOutput); // USE SELF HERE
} else {
console.log(error + ' : ' + response.statusCode);
self.emit(':tell', 'There was an error'); // AND HERE AS WELL
}
});
},
'AMAZON.HelpIntent': function () {} //.........And other built in intents.
}
};
source to share