简体   繁体   English

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

[英]HTTP request failing in AWS Lambda function for Alexa

I am trying to return data from an external api in my inline Lambda function but when I test this in the developer console for Alexa, I get 'There was a problem with the requested skills response' and I can't work out why. 我试图在我的内联Lambda函数中从外部api返回数据,但是当我在Alexa的开发人员控制台中对其进行测试时,出现“请求的技能响应存在问题”,我无法弄清楚原因。 Also, as I am doing this from the AWS console, I can't console.log to see what it actually being returned. 另外,当我从AWS控制台执行此操作时,无法console.log查看它实际返回的内容。
(I have removed the default intents for the sake of the post) (为方便起见,我删除了默认意图)

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();
};

"There was a problem with the requested skills response" generally means that the response from your skill was not in the expected format. “请求的技能回复存在问题”通常表示您的技能所获得的回复不是预期的格式。

Your API request 您的API请求

Ex: vicotria 例如:维多利亚

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

returns a JSON, and you can't directly pass it Alexa as response. 返回一个JSON,您不能直接将其作为响应传递给Alexa。 Before you send it back to Alexa, take out status that you actually want Alexa to speak. 在您发回Alexa的统计,取出status ,你真正想要的Alexa说话。 Then put that into a meaningful sentence that any skill user will understand and send it back. 然后将其放入有意义的句子中,任何技能用户都将理解该句子并将其发送回去。

For example you can return something like: 例如,您可以返回以下内容:

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");

This is a sample JSON that I got 这是我得到的样本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 : Always make use of CloudWatch to see the logs of your Lambda function, you will get a link under Monitoring tab of your Lambda Function. CloudWatch :始终使用CloudWatch查看Lambda函数的日志,您会在Lambda函数的Monitoring选项卡下获得一个链接。

Configuring Lambda Test Events : You can test you Lambda code right from your inline editor by configuring Lambda Test Events under Test menu of your inline editor. 配置Lambda测试事件 :您可以通过在串联编辑器的“ Test菜单下配置Lambda Test Events在串联编辑器中测试Lambda代码。 A function can have up to 10 test events. 一个功能最多可以包含10个测试事件。

This is because your handler is returning before the callback is called. 这是因为您的handler在调用回调之前返回。 I strongly suggest to move away from callback based development in NodeJS and to use Promise instead. 我强烈建议不要在NodeJS中进行基于回调的开发,而应使用Promise

I just answered a similar question, and provided sample code with promises. 我刚刚回答了类似的问题,并提供了带有承诺的示例代码。 Check it here How to make an asynchronous api call for Alexa Skill application with a Lambda function? 在此处检查如何使用Lambda函数对Alexa Skill应用程序进行异步api调用?

The issue turned out to be with using http itself instead of https. 问题出在使用http本身而不是https。

The only response back that I was getting was a status code of 302 which is a redirection because the api I was calling changes all http requests to https. 我得到的唯一响应是状态代码302,这是重定向,因为我正在调用的api将所有http请求都更改为https。

Therefore, I changed my import to https and used the https.get method (instead of http.get) to call the api and the correct response was returned. 因此,我将导入更改为https,并使用https.get方法(而不是http.get)来调用api,并返回了正确的响应。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM