簡體   English   中英

Amazon Alexa技能Lambda節點JS-Http GET無法正常工作

[英]Amazon Alexa Skill Lambda Node JS - Http GET not working

我想知道是否有人可以幫忙,因為我正在用這個把頭撞在牆上。 我一直在尋找答案,並嘗試了各種方法,以下是我所獲得的最接近的方法。

基本上,我正在家里建立個人使用的Alexa技能,以給兒子獎勵積分,並且它會在我們的廚房儀表板上更新。 我可以很好地發布積分,並更新儀表板(更新Firebase數據庫),但是當我問alexa他有多少時,我無法獲取積分。 我的代碼如下。

const GetPointsHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest'
      && request.intent.name === 'HowManyPointsDoesNameHaveIntent';
  },
  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 = 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時的結果是“康納有未定義的分數”,但是如果我立即再次詢問,它的效果很好。

當我在瀏覽器中加載json端點時,它實際上只是顯示該值,因此無需深入研究我認為不是的響應。

我知道請求模塊應該更簡單,但是如果我使用VS代碼命令行安裝請求模塊並上載函數,因為文件在包含所有模塊依賴項的情況下變得很大,我將無法再在線編輯該函數超出大小限制,因此請盡可能避免這種情況。

我知道該功能將更好地用作幫助程序,一旦完成此工作,我將做該工作。 我不需要這個特別漂亮,只需要它工作即可。

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藍圖

這是由於nodejs的異步行為。 Node不會等待您的http請求完成。 因此, speechOutput = "Connor has " + total + " points";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();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM