HTTP请求在Alexa的AWS Lambda函数中失败

时间:2018-08-01 20:53:25

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

我试图在嵌入式Lambda函数中从外部api返回数据,但是当我在开发人员控制台中为Alexa测试时,我得到“请求的技能响应存在问题”,我无法解决为什么。 另外,当我从AWS控制台执行此操作时,无法console.log查看它实际返回的内容。
(为方便起见,我删除了默认意图)

const request = require('request');

const handlers = {
'LaunchRequest': function () {
    this.emit(':ask', 'Welcome');
},
'GiveUpdateIntent': function (){
    var slot = this.event.request.intent.slots.line.value;

    httpGet(slot, (theResult) => {
            this.response.speak(theResult);
            this.emit(':responseReady');
        });

}

};
function httpGet(query, callback) {
var options = {
    host: 'api.tfl.gov.uk',
    path: '/line/' + encodeURIComponent(query) + '/status',
    method: 'GET',
};

var req = http.request(options, res => {
    res.setEncoding('utf8');
    var responseString = "";

    //accept incoming data asynchronously
    res.on('data', chunk => {
        responseString += chunk;
    });

    //return the data when streaming is complete
    res.on('end', () => {
        console.log(responseString[0]);
        callback(responseString[0]);
    });

});
req.end();
}


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

3 个答案:

答案 0 :(得分:1)

“所请求的技能回答存在问题” 通常是指您技能的回答不是预期的格式。

您的API请求

例如:vicotria

https://api.tfl.gov.uk/Line/victoria/Status  

返回JSON,您不能直接将其作为响应传递给Alexa。在将其发送回Alexa之前,请取出status,您实际上希望Alexa讲话。然后将其放入有意义的句子中,任何熟练的技术人员都将理解该句子并将其发送回去。

例如,您可以返回以下内容:

var speech = "Status severity description for " + 
              this.event.request.intent.slots.line.value +
              " is "
              + responseBody[0].lineStatuses.statusSeverityDescription;
this.emit(':ask',speech, "your re-prompt here");

这是我得到的示例JSON

[
  {
    "$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities",
    "id": "victoria",
    "name": "Victoria",
    "modeName": "tube",
    "disruptions": [],
    "created": "2018-07-31T12:11:08.477Z",
    "modified": "2018-07-31T12:11:08.477Z",
    "lineStatuses": [
      {
        "$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities",
        "id": 0,
        "statusSeverity": 10,
        "statusSeverityDescription": "Good Service",
        "created": "0001-01-01T00:00:00",
        "validityPeriods": []
      }
    ],
    "routeSections": [],
    "serviceTypes": [
      {
        "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities",
        "name": "Regular",
        "uri": "/Line/Route?ids=Victoria&serviceTypes=Regular"
      },
      {
        "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities",
        "name": "Night",
        "uri": "/Line/Route?ids=Victoria&serviceTypes=Night"
      }
    ],
    "crowding": {
      "$type": "Tfl.Api.Presentation.Entities.Crowding, Tfl.Api.Presentation.Entities"
    }
  }
]

CloudWatch : 始终使用CloudWatch查看Lambda函数的日志,您会在Lambda函数的Monitoring标签下获得一个链接。

配置Lambda测试事件:您可以通过在串联编辑器的Lambda Test Events菜单下配置Test,直接从串联编辑器测试Lambda代码。一个功能最多可以包含10个测试事件。

答案 1 :(得分:1)

这是因为您的handler将在调用回调之前返回。我强烈建议不要在NodeJS中进行基于回调的开发,而应使用Promise

我刚刚回答了类似的问题,并提供了带有承诺的示例代码。在这里How to make an asynchronous api call for Alexa Skill application with a Lambda function?

进行检查

答案 2 :(得分:0)

原来,问题出在使用http本身而不是https。

我得到的唯一回复是状态代码302,这是重定向,因为我正在调用的api将所有http请求都更改为https。

因此,我将导入更改为https,并使用https.get方法(而不是http.get)调用api,并返回了正确的响应。