[英]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.