Amazon Alexa技能Lambda节点JS-Http GET无法正常工作

时间:2018-10-13 08:50:09

标签: javascript get alexa alexa-skills-kit alexa-sdk-nodejs

我想知道有人能帮上忙吗?我一直在寻找答案,并尝试了各种方法,以下是我所获得的最接近的方法。

基本上,我正在家里建立个人使用的Alexa技能,以给儿子奖励积分,并且它会在我们的厨房仪表板上更新。我可以很好地发布积分,并更新仪表板(更新Firebase数据库),但是当我问alexa他有多少时,我无法获取积分。我的代码在下面。

prjroot/build/storybook/

当我询问alexa时,结果为“康纳有未定义的分数”,但是如果我立即再次询问,效果很好。

当我在浏览器中加载json端点时,它只会显示该值,因此无需深入研究我不认为的响应。

我知道请求模块应该更简单,但是如果我使用VS代码命令行安装请求模块并上传函数,因为文件在所有模块依赖项下都变得很大,我将无法再在线编辑该函数因为它超出了大小限制,所以请尽可能避免这种情况。

我知道该功能将更好地用作帮助程序,一旦我可以使用它,我就会做。我不需要这个特别漂亮,只需要它工作即可。

2 个答案:

答案 0 :(得分:1)

Node.js在默认情况下为异步,这意味着您的响应生成器在GET请求完成之前被调用。

解决方案:使用 async-await ,诸如此类

async handle(handlerInput) {

      var options = {
        "method": "GET",
        "hostname": "blah-blah-blah.firebaseio.com",
        "port": null,
        "path": "/users/Connor/points.json",
        "headers": {
          "cache-control": "no-cache"
        }
      };

      var req = await https.request(options, function (res) {
        var chunks = [];

        res.on("data", function (chunk) {
          chunks.push(chunk);
        });

        res.on("end", function () {
          var body = Buffer.concat(chunks);
          //console.log(body.toString());
          total = body.toString();

        });
    });

    req.end();

    speechOutput = "Connor has " + total + " points";

    return handlerInput.responseBuilder
      .speak(speechOutput)
      .getResponse();
  },

让我知道这是否行不通。另外,要开发供个人使用的alexa技能,请结帐alexa blueprints

答案 1 :(得分:1)

这是由于nodejs的异步行为所致。节点将不等待您的http请求完成。因此,甚至在获取speechOutput = "Connor has " + total + " points";的值之前就执行total。因此,undefined

要执行此操作,您必须使用Promises。编写一个单独的函数来触发http请求。选中此PetMatchSkill,然后看看它是如何完成的。您可以将其用作任何请求的常用方法。

例如:

function httpGet(options) {
  return new Promise(((resolve, reject) => {
    const request = https.request(options, (response) => {
      response.setEncoding('utf8');
      let returnData = '';    
      if (response.statusCode < 200 || response.statusCode >= 300) {
        return reject(new Error(`${response.statusCode}: ${response.req.getHeader('host')} ${response.req.path}`));
      }    
      response.on('data', (chunk) => {
        returnData += chunk;
      });    
      response.on('end', () => {
        resolve(JSON.parse(returnData));
      });    
      response.on('error', (error) => {
        reject(error);
      });
    });
    request.end();
  }));
}

现在在您的意图处理程序中使用async-await

async handle(handlerInput) {
   var options = {
        "method": "GET",
        "hostname": "blah-blah-blah.firebaseio.com",
        "port": null,
        "path": "/users/Connor/points.json",
        "headers": {
          "cache-control": "no-cache"
        }
      };
   const response = await httpGet(options);
   var total = 0;
   if (response.length > 0) {
      // do your stuff
      //total = response
   }
   speechOutput = "Connor has " + total + " points";
   return handlerInput.responseBuilder
     .speak(speechOutput)
     .getResponse();
}