Amazon Alexa Skill Lambda Node JS - Http GET 不工作
Amazon Alexa Skill Lambda Node JS - Http GET not working
我想知道是否有人可以提供帮助,因为我正为此苦苦挣扎。几天来我一直在寻找答案并尝试了各种方法,下面是我得到的最接近的答案。
基本上,我正在构建一个 Alexa 技能,供我在家里个人使用,以给我儿子奖励积分,它会在我们的厨房仪表板上更新。我可以 POST 分很好,仪表板也更新了(更新了一个 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 的结果是 "Connor has undefined points",但如果我立即再次询问,它就可以正常工作。
json 端点实际上只是在我将其加载到浏览器中时显示值,因此无需深入研究我不认为的响应。
我知道请求模块应该更简单,但是如果我使用 VS 代码命令行安装它并上传函数,因为文件变得太大了所有模块依赖项,我无法再编辑在线功能,因为它超过了大小限制,所以尽可能避免这种情况。
我知道该函数更适合用作助手,一旦我开始使用它我就会这样做。我不需要它特别漂亮,只需要它能工作。
Node.js默认是异步的,这意味着你的response builder在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。
这是因为 nodejs 的异步行为。 Node 不会等待您的 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();
}
我想知道是否有人可以提供帮助,因为我正为此苦苦挣扎。几天来我一直在寻找答案并尝试了各种方法,下面是我得到的最接近的答案。
基本上,我正在构建一个 Alexa 技能,供我在家里个人使用,以给我儿子奖励积分,它会在我们的厨房仪表板上更新。我可以 POST 分很好,仪表板也更新了(更新了一个 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 的结果是 "Connor has undefined points",但如果我立即再次询问,它就可以正常工作。
json 端点实际上只是在我将其加载到浏览器中时显示值,因此无需深入研究我不认为的响应。
我知道请求模块应该更简单,但是如果我使用 VS 代码命令行安装它并上传函数,因为文件变得太大了所有模块依赖项,我无法再编辑在线功能,因为它超过了大小限制,所以尽可能避免这种情况。
我知道该函数更适合用作助手,一旦我开始使用它我就会这样做。我不需要它特别漂亮,只需要它能工作。
Node.js默认是异步的,这意味着你的response builder在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。
这是因为 nodejs 的异步行为。 Node 不会等待您的 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();
}