【问题标题】:HTTP request failing in AWS Lambda function for AlexaAlexa 的 AWS Lambda 函数中的 HTTP 请求失败
【发布时间】:2019-01-09 13:05:18
【问题描述】:

我试图在我的内联 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();
};

【问题讨论】:

  • “另外,由于我是从 aws 控制台执行此操作,我无法通过 Console.log 查看它实际返回的内容。” 为什么不呢?
  • 我不知道为什么,但即使我运行我知道有效的非常简单的代码,console.log 也不会出现在我的控制台中。
  • 这出乎意料。您的 Lambda 执行角色的权限可能存在问题。
  • 啊,我可以在日志文件中看到 console.log 输出
  • 我刚刚在这里回答了一个类似的问题stackoverflow.com/questions/51764274/…

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


【解决方案1】:

“请求的技能回复有问题”通常表示您的技能回复不符合预期格式。

您的 API 请求

例如:维多利亚

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

返回一个 JSON,你不能直接将它传递给 Alexa 作为响应。在您将其发送回 Alexa 之前,请取出您实际上希望 Alexa 发言的status。然后把它写成一个任何技能用户都能理解的有意义的句子,然后发回。

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

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 测试事件:您可以通过在内联编辑器的 Test 菜单下配置 Lambda Test Events 直接从内联编辑器测试您的 Lambda 代码。一个函数最多可以有 10 个测试事件。

【讨论】:

  • 谢谢,我试过了,但还是没有结果。这是我从日志中得到的: 2018-08-02T09:44:55.475Z b5e52be3-9638-11e8-bcc9-c3e178d35a1f TypeError: Cannot read property 'locale' of undefined at AlexaRequestEmitter.HandleLambdaEvent (/var/task/node_modules/ alexa-sdk/lib/alexa.js:112:38) 在 AlexaRequestEmitter.value (/var/task/node_modules/alexa-sdk/lib/alexa.js:100:31) 在exports.handler (/var/task/ index.js:80:11)
  • index.js 的第 80 行是什么?
  • 这是alexa.exeute();。上面代码的最后一行
  • 您使用的测试 JSON 是什么。
  • 它是这样的:{ "key3": "value3", "key2": "value2", "key1": "value1" } 不确定我是否需要在这里更改任何内容
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

    我得到的唯一响应是状态码 302,这是一个重定向,因为我调用的 api 将所有 http 请求更改为 https。

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

    【讨论】:

      猜你喜欢
      • 2019-09-30
      • 2015-10-27
      • 1970-01-01
      • 2015-07-04
      • 2021-02-22
      • 1970-01-01
      • 2018-05-04
      • 2019-03-31
      • 2020-09-14
      相关资源
      最近更新 更多