Node.js Lambda function returns “The response is invalid” back to Alexa Service Simulator from REST call

て烟熏妆下的殇ゞ 提交于 2019-12-18 09:14:03

问题


Having issues making a REST call to an API between a node.js Lambda function and Alexa. I'm using the request library to make the calls with an account linked skill. I've only set one sample utterance for the intent, and the simulator see this fine.

Also, the cloudwatch logs show a 200 response code from the api endpoint and any of the returned data from the API from console.logs to 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 its something to do with the format of speechOutput that I'm asking Alexa to "emit/tell"?


回答1:


No, it has nothing to do with the format of speechOutput. The issue is that when the callback of the request method is executed, the reference to this is lost. To solve that, keep a reference to this before you call request (e.g. assign this to a variable called 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.

    }
};



回答2:


You are facing issue only because of asynchronous call behavior of NodeJS and nothing to do with request call. You can solve this either by using promises or by using callback from method. Below is snippet.

'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 () {
        requestAPI( (message) => {
            this.emit(':tell', message);
        });
    },
    'AMAZON.HelpIntent': function () {} //.........And other built in intents.

    }
};

function requestAPI(callback) {
    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);
            callback(speechOutput);
        } else {
            console.log(error + ' : ' + response.statusCode);
            callback('There was an error');
        }
    });
}


来源:https://stackoverflow.com/questions/42704123/node-js-lambda-function-returns-the-response-is-invalid-back-to-alexa-service

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!