node.js - 亚马逊 AWS Lambda Alexa HTTP 获取问题

标签 node.js amazon-web-services aws-lambda alexa alexa-skills-kit

我一直在使用 Amazon Lambda 和 alexa 技能套件的以下代码时遇到问题。我在这上面花了无数个小时,但无法让它发挥作用。我不断收到此消息,但无法弄清楚 http get 失败的原因。 “请稍后再试”。它甚至不打印控制台消息。

var Alexa = require('alexa-sdk');
var http = require('http');
var APP_ID = "omitted";     
var SKILL_NAME = 'omitted';

var options = {
    host: 'api.forismatic.com',
    path: '/api/1.0/?method=getQuote&lang=en&format=text',
    method: 'GET'
};

exports.handler = function(event, context, callback) {
var alexa = Alexa.handler(event, context);
alexa.APP_ID = APP_ID;
alexa.registerHandlers(handlers);
alexa.execute();
};

var handlers = {
'LaunchRequest': function () {
    this.emit('Inspiration');
},
'IntentRequest': function() {
    this.emit('Inspiration');
},
'InspirationIntent': function () {
    this.emit('Inspiration');
},
'Inspiration': function () {
    var speechOutput = '';
    var text = '';
    http.get(options, function(res) {
        console.error("Got response: " + res.statusCode);
        res.on("data", function(chunk) {
        console.error("BODY: " + chunk);
        text = chunk;
    });
    }).on('error', function(e) {
        text = 'error' + e.message;
        console.error("Got error: " + e.message);
});
    if(text == ''){
    speechOutput = "Please try again later";
    }
    else{speechOutput = text;}
    this.emit(':tellWithCard', speechOutput, SKILL_NAME, text);
},
'AMAZON.HelpIntent': function () {
    var speechOutput = "You can ask Inspirational Quote for some advice.";
    var reprompt = "What would you like me to do?";
    this.emit(':ask', speechOutput, reprompt);
},
'AMAZON.CancelIntent': function () {
    this.emit(':tell', 'Goodbye!');
},
'AMAZON.StopIntent': function () {
    this.emit(':tell', 'Goodbye!');
},
'Unhandled': function() {
    this.emit('AMAZON.HelpIntent');
}
};

最佳答案

因为 java 脚本是异步的,所以这段代码:

if(text == ''){
speechOutput = "Please try again later";
}
else{speechOutput = text;}
this.emit(':tellWithCard', speechOutput, SKILL_NAME, text);

在调用 API 获得响应之前运行。

不幸的是,你不能将上面的代码移动到 http.get block 中,因为 'this.emit' 中的 'this' 将不再起作用,你会得到一个未定义的响应被发送回Alexa 技能。

我认为最简洁的解决方案是将 http 调用拉出到一个单独的函数中。调用该函数时,您将不得不使用回调来避免 lambda 在移动到下一个代码行之前不等待来自 http 调用的响应的相同问题。因此,通过函数调用传递一个函数并从那里发送您的响应。 注意 - 要使其正常工作,您必须在函数调用外部为“this”的值分配一个变量,并在函数调用内部使用该变量而不是“this”。

示例如下:

var Alexa = require('alexa-sdk');
var http = require('http');
var APP_ID = "omitted";     
var SKILL_NAME = 'omitted';

var options = {
    host: 'api.forismatic.com',
    path: '/api/1.0/?method=getQuote&lang=en&format=text',
    method: 'GET'
};

exports.handler = function(event, context, callback) {
    var alexa = Alexa.handler(event, context);
    alexa.APP_ID = APP_ID;
    alexa.registerHandlers(handlers);
    alexa.execute();
};

var handlers = {
    'LaunchRequest': function () {
        this.emit('Inspiration');
    },
    'IntentRequest': function() {
        this.emit('Inspiration');
    },
    'InspirationIntent': function () {
        this.emit('Inspiration');
    },
    'Inspiration': function () {
        var speechOutput = '';
        var text = '';
        var self = this;
        getQuote(options, function (quote){
            if(quote == ''){
            speechOutput = "Please try again later";
            }
            else{speechOutput = quote;}
            self.emit(':tellWithCard', speechOutput, SKILL_NAME, text);
        }
    )},
    'AMAZON.HelpIntent': function () {
        var speechOutput = "You can ask Inspirational Quote for some advice.";
        var reprompt = "What would you like me to do?";
        res(this.emit(':ask', speechOutput, reprompt));
    },
    'AMAZON.CancelIntent': function () {
        this.emit(':tell', 'Goodbye!');
    },
    'AMAZON.StopIntent': function () {
        this.emit(':tell', 'Goodbye!');
    },
    'Unhandled': function() {
        this.emit('AMAZON.HelpIntent');
    }
};

function getQuote(options, callback){
    http.get(options, function(res) {
        console.error("Got response: " + res.statusCode);
        res.on("data", function(chunk) {
        console.error("BODY: " + chunk);
        text = '' + chunk;
        return callback(text);
    });
    }).on('error', function(e) {
        text = 'error' + e.message;
        console.error("Got error: " + e.message);
});
}

关于node.js - 亚马逊 AWS Lambda Alexa HTTP 获取问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42354742/

相关文章:

node.js - sudo pm2 命令未找到 pm2 已安装

amazon-web-services - 删除通过 CloudFormation 包命令上传的旧版本 lambda 函数

amazon-web-services - 在清空或删除 S3 存储桶之前复制所有对象

amazon-web-services - AWS Lambda 容器镜像支持与 Fargate

aws-lambda - 如何在不更改任何内容的情况下重命名 aws lambda 函数

javascript - 附加带有固定行名称的文件 javascript

javascript - 如何在 passport-twitter 策略中使用 session 变量 req.user

node.js - Nodemon 在尝试使用 es6 模块时崩溃,但在 es5 上运行良好

amazon-web-services - 我应该使用 docker (nginx) 来提供 SPA 服务吗?

python - 如何为基于 docker 的 python3 lambda 函数配置入口点/cmd?