Alexa 请求技能生成器不等待响应生成器
Alexa request skill builder does not wait for response builder
我创建了一个 Alexa 技能,它需要从 API.
中获取数据
根据示例aws-nodejs-factskill
,我创建了技能:
exports.handler = async function (event, context) {
console.log(`REQUEST++++${JSON.stringify(event)}`);
if (!skill) {
skill = Alexa.SkillBuilders.custom()
.addRequestHandlers(
customHandler,
HelpHandler,
ExitHandler,
FallbackHandler,
SessionEndedRequestHandler,
)
.addErrorHandlers(ErrorHandler)
.create();
}
return skill.invoke(event, context);
};
const customHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'LaunchRequest'
|| (request.type === 'IntentRequest'
&& request.intent.name === 'customIntent');
},
handle(handlerInput) {
const myRequest = "size=1&lat=<lat>&long=<lon>";
var speechOutput = "Default Message";
callAPI(myRequest, (myResult) => {
console.log("sent : " + myRequest);
console.log("received : " + JSON.stringify(myResult));
speechOutput = JSON.stringify(myResult).replace(/['"]+/g, '');
return handlerInput.responseBuilder
.speak(speechOutput)
.withSimpleCard(SKILL_NAME, speechOutput)
.getResponse();
});
},
};
但是返回给 Alexa 的响应为空,会话因错误而结束。
{
"body": {
"version": "1.0",
"response": {},
"sessionAttributes": {},
"userAgent": "ask-node/2.0.7 Node/v8.10.0"
}
拉姆达
Session ended with reason: ERROR
API 调用的响应正常。而且我能够在控制台中看到响应。
如果我在外部使用相同的代码和 return 构建器,它工作正常。
const customHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'LaunchRequest'
|| (request.type === 'IntentRequest'
&& request.intent.name === 'customIntent');
},
handle(handlerInput) {
const myRequest = "size=1&lat=<lat>&long=<lon>";
var speechOutput = "Default Message";
locateNearestDealer(myRequest, (myResult) => {
console.log("sent : " + myRequest);
console.log("received : " + JSON.stringify(myResult));
speechOutput = JSON.stringify(myResult).replace(/['"]+/g, '');
});
return handlerInput.responseBuilder
.speak(speechOutput)
.withSimpleCard(SKILL_NAME, speechOutput)
.getResponse();
},
};
我到底做错了什么,我该如何解决?
您应该将句柄函数设为异步函数,因为它需要等待 api 响应,这是一个示例:
const HelloWorldIntentHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === 'HelloWorldIntent';
},
async handle(handlerInput) {
const response = await httpGet();
return handlerInput.responseBuilder
.speak('Example')
.getResponse();
}}
function httpGet() {
return new Promise((resolve, reject) => {
request.get(URL, (error, response, body) => {
console.log('error:', error);
console.log('statusCode:', response.statusCode);
resolve(JSON.parse(body));
});
});
}
我创建了一个 Alexa 技能,它需要从 API.
中获取数据根据示例aws-nodejs-factskill
,我创建了技能:
exports.handler = async function (event, context) {
console.log(`REQUEST++++${JSON.stringify(event)}`);
if (!skill) {
skill = Alexa.SkillBuilders.custom()
.addRequestHandlers(
customHandler,
HelpHandler,
ExitHandler,
FallbackHandler,
SessionEndedRequestHandler,
)
.addErrorHandlers(ErrorHandler)
.create();
}
return skill.invoke(event, context);
};
const customHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'LaunchRequest'
|| (request.type === 'IntentRequest'
&& request.intent.name === 'customIntent');
},
handle(handlerInput) {
const myRequest = "size=1&lat=<lat>&long=<lon>";
var speechOutput = "Default Message";
callAPI(myRequest, (myResult) => {
console.log("sent : " + myRequest);
console.log("received : " + JSON.stringify(myResult));
speechOutput = JSON.stringify(myResult).replace(/['"]+/g, '');
return handlerInput.responseBuilder
.speak(speechOutput)
.withSimpleCard(SKILL_NAME, speechOutput)
.getResponse();
});
},
};
但是返回给 Alexa 的响应为空,会话因错误而结束。
{
"body": {
"version": "1.0",
"response": {},
"sessionAttributes": {},
"userAgent": "ask-node/2.0.7 Node/v8.10.0"
}
拉姆达
Session ended with reason: ERROR
API 调用的响应正常。而且我能够在控制台中看到响应。
如果我在外部使用相同的代码和 return 构建器,它工作正常。
const customHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'LaunchRequest'
|| (request.type === 'IntentRequest'
&& request.intent.name === 'customIntent');
},
handle(handlerInput) {
const myRequest = "size=1&lat=<lat>&long=<lon>";
var speechOutput = "Default Message";
locateNearestDealer(myRequest, (myResult) => {
console.log("sent : " + myRequest);
console.log("received : " + JSON.stringify(myResult));
speechOutput = JSON.stringify(myResult).replace(/['"]+/g, '');
});
return handlerInput.responseBuilder
.speak(speechOutput)
.withSimpleCard(SKILL_NAME, speechOutput)
.getResponse();
},
};
我到底做错了什么,我该如何解决?
您应该将句柄函数设为异步函数,因为它需要等待 api 响应,这是一个示例:
const HelloWorldIntentHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === 'HelloWorldIntent';
},
async handle(handlerInput) {
const response = await httpGet();
return handlerInput.responseBuilder
.speak('Example')
.getResponse();
}}
function httpGet() {
return new Promise((resolve, reject) => {
request.get(URL, (error, response, body) => {
console.log('error:', error);
console.log('statusCode:', response.statusCode);
resolve(JSON.parse(body));
});
});
}