Alexa技能无法理解命令
Alexa skill can't understand command
我正在尝试在 Alexa 开发控制台中创建一项技能,它将通过 returning 从 API 查询中找到的信息来响应命令。我的其他命令有效,例如“帮助”、电梯 xxx 的状态等。仅此一个命令无法 return 正确结果。
预期结果:
我:what is going on
.
Alexa:Greetings. There are currently XXX elevators deployed in the XXX buildings of your XXX customers Currently, XXX elevators are not in Running Status and are being serviced XXX Batteries are deployed across XXX cities On another note you currently have XXX quotes awaiting processing You also have XXX leads in your contact requests
.
实际结果:
我:what is going on
.
Alexa:Sorry, I can't understand the command. Please say again.
JSON 从命令输入1:
{
"version": "1.0",
"session": {
"new": false,
"sessionId": "amzn1.echo-api.session.b7c275c5-a4d6-40a0-a905-2c767181ef14",
"application": {
"applicationId": "amzn1.ask.skill.a6415548-f2a7-4098-8d6b-62a74c41fb60"
},
"attributes": {},
"user": {
"userId": "amzn1.ask.account.AEI2SJB7LJZYKBWBT23GK4W4WGU2NYIWO7YG5UG3PRXRVICLXOHYB33PZXP63NNBIW4ZIIJF63XTT32CKBGKJDIIMNH32DD6VTFUYE4MW3D72OVKZ52UGSGVDKDD4TDAK3Q2AXBAKQHZ5R3XZDLXFWC3OAY5HMV3BL47NG7YKS43WR3RLM4UEMQBC2EQM6OPSWJIWALUGSYVO7A"
}
},
"context": {
"Viewports": [
{
"type": "APL",
"id": "main",
"shape": "RECTANGLE",
"dpi": 213,
"presentationType": "STANDARD",
"canRotate": false,
"configuration": {
"current": {
"mode": "HUB",
"video": {
"codecs": [
"H_264_42",
"H_264_41"
]
},
"size": {
"type": "DISCRETE",
"pixelWidth": 1280,
"pixelHeight": 800
}
}
}
}
],
"Viewport": {
"experiences": [
{
"arcMinuteWidth": 346,
"arcMinuteHeight": 216,
"canRotate": false,
"canResize": false
}
],
"mode": "HUB",
"shape": "RECTANGLE",
"pixelWidth": 1280,
"pixelHeight": 800,
"dpi": 213,
"currentPixelWidth": 1280,
"currentPixelHeight": 800,
"touch": [
"SINGLE"
],
"video": {
"codecs": [
"H_264_42",
"H_264_41"
]
}
},
"Extensions": {
"available": {
"aplext:backstack:10": {}
}
},
"System": {
"application": {
"applicationId": "amzn1.ask.skill.a6415548-f2a7-4098-8d6b-62a74c41fb60"
},
"user": {
"userId": "amzn1.ask.account.AEI2SJB7LJZYKBWBT23GK4W4WGU2NYIWO7YG5UG3PRXRVICLXOHYB33PZXP63NNBIW4ZIIJF63XTT32CKBGKJDIIMNH32DD6VTFUYE4MW3D72OVKZ52UGSGVDKDD4TDAK3Q2AXBAKQHZ5R3XZDLXFWC3OAY5HMV3BL47NG7YKS43WR3RLM4UEMQBC2EQM6OPSWJIWALUGSYVO7A"
},
"device": {
"deviceId": "amzn1.ask.device.AG7VS7XSFW5VZ73I6A7HFTJPUO56OU4TAM2ICF2KIU75TSD3U53KGGOIYR4IUUUPMRC7AR3KY3X5JT3IDBJ5VADVZLQTWLXFNPSJC3BKM6QOH4IYJLGB3HZOKXMD5XTYZPQILBUHROBVAYAOQ7ZNJRSFFR62DW3G2ZCG3MEMBT45MIRT56F44",
"supportedInterfaces": {}
},
"apiEndpoint": "https://api.amazonalexa.com",
"apiAccessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.eyJhdWQiOiJodHRwczovL2FwaS5hbWF6b25hbGV4YS5jb20iLCJpc3MiOiJBbGV4YVNraWxsS2l0Iiwic3ViIjoiYW16bjEuYXNrLnNraWxsLmE2NDE1NTQ4LWYyYTctNDA5OC04ZDZiLTYyYTc0YzQxZmI2MCIsImV4cCI6MTY0MTM0Nzk4NiwiaWF0IjoxNjQxMzQ3Njg2LCJuYmYiOjE2NDEzNDc2ODYsInByaXZhdGVDbGFpbXMiOnsiY29udGV4dCI6IkFBQUFBQUFBQUFBdUVDMVZqR1IvSklqOXR4VDJqMXljS3dFQUFBQUFBQUNpSlhzaGQ3eXhVUEViZjNnMWk2c1JiYmMwTENQN2hnUm5OZXlmTnNKdldWWHE5QWg3ajdkNC8raEJxYnB6THpoYzJiR0dNeHdLdFlQZ3FDK08xdWh0b3dGcFBaaEE0RElnN1FFNXE5dDBaalR0M0VnejdCeDhOWDloYm9mVG1TOHc0VWZ5NGc0dVA1RVducHYvQUtzNGlRSzdNbmh0a3hEdm8vMzNycmRWZ0JzTm5wM1l5bDBNSHE4QTBkVS85VUdZUlZ5Q0FyaTJqeFBVMTZIVTJhWFJZTWZuN2FDeTBEa0FWUk81TXliYUJDWklxSjhxaWtUUURoOUE5NlAxNTREc3hrK0FkMnVyRUVrN1E2VC84a0grYVkyVjQ3dVRFM1h4cWppVCt1KzBsR0M5N3JpdXpSU2Z5MGtXVlpwNFBLTGZpU0dlRzJIbHNtRE5HRFFwNUJRZy8yaittVHNYdXEweDlkR3QrYUpNYTh0VkFHTzd6RVBHelZxMlFydllFRXA2aHNPdWxoaTlQc1I0aXc9PSIsImNvbnNlbnRUb2tlbiI6bnVsbCwiZGV2aWNlSWQiOiJhbXpuMS5hc2suZGV2aWNlLkFHN1ZTN1hTRlc1Vlo3M0k2QTdIRlRKUFVPNTZPVTRUQU0ySUNGMktJVTc1VFNEM1U1M0tHR09JWVI0SVVVVVBNUkM3QVIzS1kzWDVKVDNJREJKNVZBRFZaTFFUV0xYRk5QU0pDM0JLTTZRT0g0SVlKTEdCM0haT0tYTUQ1WFRZWlBRSUxCVUhST0JWQVlBT1E3Wk5KUlNGRlI2MkRXM0cyWkNHM01FTUJUNDVNSVJUNTZGNDQiLCJ1c2VySWQiOiJhbXpuMS5hc2suYWNjb3VudC5BRUkyU0pCN0xKWllLQldCVDIzR0s0VzRXR1UyTllJV083WUc1VUczUFJYUlZJQ0xYT0hZQjMzUFpYUDYzTk5CSVc0WklJSkY2M1hUVDMyQ0tCR0tKRElJTU5IMzJERDZWVEZVWUU0TVczRDcyT1ZLWjUyVUdTR1ZES0RENFREQUszUTJBWEJBS1FIWjVSM1haRExYRldDM09BWTVITVYzQkw0N05HN1lLUzQzV1IzUkxNNFVFTVFCQzJFUU02T1BTV0pJV0FMVUdTWVZPN0EifX0.YxsDZNDIU69YvWX7RmjTF6UzeoMSp8fTK6jlhTe4qoS-JAfXUxPkzjygs3QMKfphu7B-a5Ht8zkXybuGR1S_rny3-46UiehOJHRdrYoyf46K_9pCNCehFsOjsPf7sH5-QgqSetDHcy9qgbGUs1MSnh5oAN0tZdpXBdYtopjcW6h2N0GFnaeNGVi2iuhQgkO-qz4FXlB1rfbAPWXzfxKMI6GLNAdLMusjXpgqVeFJasyg-a6OXr_9cHfkIKJZsYSEtfRrOYJkQUcgnYLfvwqKdmVcORrL2bUuRvFYb4YQa49K6d2vcwJg8Y2mHtomCzElIr9N-4tdPwgU5LvrFWv75A"
}
},
"request": {
"type": "IntentRequest",
"requestId": "amzn1.echo-api.request.3ed6b0ec-ef10-4816-bb17-ecdd18dccdac",
"locale": "en-US",
"timestamp": "2022-01-05T01:54:47Z",
"intent": {
"name": "GetRemoteDataIntent",
"confirmationStatus": "NONE"
}
}
}
JSON 输出 1:
{
"body": {
"version": "1.0",
"response": {
"outputSpeech": {
"type": "SSML",
"ssml": "<speak>Sorry, I can't understand the command. Please say again.</speak>"
},
"reprompt": {
"outputSpeech": {
"type": "SSML",
"ssml": "<speak>Sorry, I can't understand the command. Please say again.</speak>"
}
},
"shouldEndSession": false,
"type": "_DEFAULT_RESPONSE"
},
"sessionAttributes": {},
"userAgent": "ask-node/2.11.0 Node/v12.22.7"
}
}
Index.js:
/* eslint-disable func-names */
/* eslint-disable no-console */
const Alexa = require("ask-sdk-core");
const http = require("https");
// greating message hello there.
const GetLaunchHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === "LaunchRequest";
},
handle(handlerInput) {
const speechText = "Hello there. How can i help you today?";
return handlerInput.responseBuilder
.speak(speechText)
.reprompt()
.getResponse();
}
};
// ----- find the elevator status of a elevator specific-----
const GetStatusHandler = {
canHandle(handlerInput) {
return (
handlerInput.requestEnvelope.request.intent.name === "GetStatusIntent"
);
},
async handle(handlerInput) {
let outputSpeech = "This is the default message.";
const id = handlerInput.requestEnvelope.request.intent.slots.id.value;
if (id > 200) {
outputSpeech = "Please enter a valid number";
return handlerInput.responseBuilder
.speak(outputSpeech)
.reprompt()
.getResponse();
}
//need to add elevator status endpoint
const elevatorStatus = await getRemoteElevatorData(
"https://jakerocket.azurewebsites.net/elevator/" + id
);
const elevator = JSON.parse(elevatorStatus);
outputSpeech = `The status of elevator ${id} is ${elevator} `;
return handlerInput.responseBuilder
.speak(outputSpeech)
.reprompt()
.getResponse();
}
};
// ----- make all get for the big sentence -----
const GetRemoteDataHandler = {
canHandle(handlerInput) {
return (
handlerInput.requestEnvelope.request.type === "IntentRequest" &&
handlerInput.requestEnvelope.request.intent.name === "GetRemoteDataIntent"
);
},
async handle(handlerInput) {
let outputSpeech = "This is the default message.";
//elevators that are not in running status and are being serviced
const elevatorData = await getRemoteElevatorData(
"https://jakerocket.azurewebsites.net/elevator/inactive"
);
const elevatorAllData = await getRemoteElevatorAllData(
"https://jakerocket.azurewebsites.net/elevator"
);
const buildingData = await getRemoteBuildingData(
"https://jakerocket.azurewebsites.net/buildings"
);
const customerData = await getRemoteCustomerData(
"https://jakerocket.azurewebsites.net/customer"
);
const batteryData = await getRemoteBatteryData(
"https://jakerocket.azurewebsites.net/battery"
);
const AddressCityData = await getRemoteCityData(
"https://jakerocket.azurewebsites.net/address"
);
const QuoteData = await getQuoteData(
"https://jakerocket.azurewebsites.net/quote"
);
const LeadData = await getLeadData(
"https://jakerocket.azurewebsites.net/leads"
);
const elevator = JSON.parse(elevatorData);
const elevatorAll = JSON.parse(elevatorAllData);
const building = JSON.parse(buildingData);
const customer = JSON.parse(customerData);
const batteries = JSON.parse(batteryData);
const cities = JSON.parse(AddressCityData);
const quotes = JSON.parse(QuoteData);
const leads = JSON.parse(LeadData);
outputSpeech = `Hi Sir welcome to Rocket Elevator Statistic. There are currently ${
elevatorAll.length
} elevators deployed in the ${building.length} buildings of your ${
customer.length
} customers . Currently, ${
elevator.length
} elevators are not in Running Status and are being serviced.
${batteries.length} Batteries are deployed across ${
cities.length
} cities. On another note you currently have ${
quotes.length
} quotes awaiting processing. You also have ${
leads.length
} leads in your contact requests
`;
return handlerInput.responseBuilder
.speak(outputSpeech)
.reprompt()
.getResponse();
}
};
// ----- help commands -----
const HelpIntentHandler = {
canHandle(handlerInput) {
return (
handlerInput.requestEnvelope.request.type === "IntentRequest" &&
handlerInput.requestEnvelope.request.intent.name === "AMAZON.HelpIntent"
);
},
handle(handlerInput) {
const speechText =
`Here is the list of all commands : what is the status of elevator {id},Can you tell me the status of elevator {id}, how is rocket elevators going, what is happening at rocket elevators, what is going on`;
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.getResponse();
}
};
const CancelAndStopIntentHandler = {
canHandle(handlerInput) {
return (
handlerInput.requestEnvelope.request.type === "IntentRequest" &&
(handlerInput.requestEnvelope.request.intent.name ===
"AMAZON.CancelIntent" ||
handlerInput.requestEnvelope.request.intent.name ===
"AMAZON.StopIntent")
);
},
handle(handlerInput) {
const speechText = "Goodbye!";
return handlerInput.responseBuilder.speak(speechText).getResponse();
}
};
const SessionEndedRequestHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === "SessionEndedRequest";
},
handle(handlerInput) {
console.log(
`Session ended with reason: ${
handlerInput.requestEnvelope.request.reason
}`
);
return handlerInput.responseBuilder.getResponse();
}
};
const ErrorHandler = {
canHandle() {
return true;
},
handle(handlerInput, error) {
console.log(`Error handled: ${error.message}`);
return handlerInput.responseBuilder
.speak("Sorry, I can't understand the command. Please say again.")
.reprompt("Sorry, I can't understand the command. Please say again.")
.getResponse();
}
};
const getLeadData = function(url) {
return new Promise((resolve, reject) => {
const client = url.startsWith("https") ? require("https") : require("http");
const request = client.get(url, response => {
if (response.statusCode < 200 || response.statusCode > 299) {
reject(new Error("Failed with status code: " + response.statusCode));
}
const body = [];
response.on("data", chunk => body.push(chunk));
response.on("end", () => resolve(body.join("")));
});
request.on("error", err => reject(err));
});
};
const getRemoteElevatorData = function(url) {
return new Promise((resolve, reject) => {
const client = url.startsWith("https") ? require("https") : require("http");
const request = client.get(url, response => {
if (response.statusCode < 200 || response.statusCode > 299) {
reject(new Error("Failed with status code: " + response.statusCode));
}
const body = [];
response.on("data", chunk => body.push(chunk));
response.on("end", () => resolve(body.join("")));
});
request.on("error", err => reject(err));
});
};
const getRemoteElevatorAllData = function(url) {
return new Promise((resolve, reject) => {
const client = url.startsWith("https") ? require("https") : require("http");
const request = client.get(url, response => {
if (response.statusCode < 200 || response.statusCode > 299) {
reject(new Error("Failed with status code: " + response.statusCode));
}
const body = [];
response.on("data", chunk => body.push(chunk));
response.on("end", () => resolve(body.join("")));
});
request.on("error", err => reject(err));
});
};
const getQuoteData = function(url) {
return new Promise((resolve, reject) => {
const client = url.startsWith("https") ? require("https") : require("http");
const request = client.get(url, response => {
if (response.statusCode < 200 || response.statusCode > 299) {
reject(new Error("Failed with status code: " + response.statusCode));
}
const body = [];
response.on("data", chunk => body.push(chunk));
response.on("end", () => resolve(body.join("")));
});
request.on("error", err => reject(err));
});
};
const getRemoteBuildingData = function(url) {
return new Promise((resolve, reject) => {
const client = url.startsWith("https") ? require("https") : require("http");
const request = client.get(url, response => {
if (response.statusCode < 200 || response.statusCode > 299) {
reject(new Error("Failed with status code: " + response.statusCode));
}
const body = [];
response.on("data", chunk => body.push(chunk));
response.on("end", () => resolve(body.join("")));
});
request.on("error", err => reject(err));
});
};
const getRemoteCityData = function(url) {
return new Promise((resolve, reject) => {
const client = url.startsWith("https") ? require("https") : require("http");
const request = client.get(url, response => {
if (response.statusCode < 200 || response.statusCode > 299) {
reject(new Error("Failed with status code: " + response.statusCode));
}
const body = [];
response.on("data", chunk => body.push(chunk));
response.on("end", () => resolve(body.join("")));
});
request.on("error", err => reject(err));
});
};
const getRemoteCustomerData = function(url) {
return new Promise((resolve, reject) => {
const client = url.startsWith("https") ? require("https") : require("http");
const request = client.get(url, response => {
if (response.statusCode < 200 || response.statusCode > 299) {
reject(new Error("Failed with status code: " + response.statusCode));
}
const body = [];
response.on("data", chunk => body.push(chunk));
response.on("end", () => resolve(body.join("")));
});
request.on("error", err => reject(err));
});
};
const getRemoteBatteryData = function(url) {
return new Promise((resolve, reject) => {
const client = url.startsWith("https") ? require("https") : require("http");
const request = client.get(url, response => {
if (response.statusCode < 200 || response.statusCode > 299) {
reject(new Error("Failed with status code: " + response.statusCode));
}
const body = [];
response.on("data", chunk => body.push(chunk));
response.on("end", () => resolve(body.join("")));
});
request.on("error", err => reject(err));
});
};
const skillBuilder = Alexa.SkillBuilders.custom();
exports.handler = skillBuilder
.addRequestHandlers(
GetLaunchHandler,
GetRemoteDataHandler,
HelpIntentHandler,
CancelAndStopIntentHandler,
SessionEndedRequestHandler,
GetStatusHandler
)
.addErrorHandlers(ErrorHandler)
.lambda();
最后,JSON 交互模型:
{
"interactionModel": {
"languageModel": {
"invocationName": "rocket elevators",
"intents": [
{
"name": "GetLaunchIntent",
"slots": [],
"samples": [
"hi",
"hello"
]
},
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": [
"help"
]
},
{
"name": "AMAZON.StopIntent",
"samples": []
},
{
"name": "GetStatusIntent",
"slots": [
{
"name": "id",
"type": "AMAZON.NUMBER"
}
],
"samples": [
"what is the status of elevator {id}",
"Can you tell me the status of elevator {id}"
]
},
{
"name": "GetRemoteDataIntent",
"slots": [],
"samples": [
"how is rocket elevators going",
"what is happening at rocket elevators",
"what is going on"
]
},
{
"name": "AMAZON.NavigateHomeIntent",
"samples": []
}
],
"types": []
}
}
}
我对 Alexa 技能开发还很陌生,我只是在学习一个可能有点过时的教程。任何帮助将不胜感激!
在您的交互模型中添加 AMAZON.FallbackIntent。
“抱歉,我无法理解该命令。请再说一遍。”此语音输出应在请求 AMAZON.FallbackIntent 时发送,而不是在出错时发送。
我不知道 javascript 是如何工作的,但我认为你的代码中有一些错误会触发 errorHandler 然后给出输出。
我正在尝试在 Alexa 开发控制台中创建一项技能,它将通过 returning 从 API 查询中找到的信息来响应命令。我的其他命令有效,例如“帮助”、电梯 xxx 的状态等。仅此一个命令无法 return 正确结果。
预期结果:
我:what is going on
.
Alexa:Greetings. There are currently XXX elevators deployed in the XXX buildings of your XXX customers Currently, XXX elevators are not in Running Status and are being serviced XXX Batteries are deployed across XXX cities On another note you currently have XXX quotes awaiting processing You also have XXX leads in your contact requests
.
实际结果:
我:what is going on
.
Alexa:Sorry, I can't understand the command. Please say again.
JSON 从命令输入1:
{
"version": "1.0",
"session": {
"new": false,
"sessionId": "amzn1.echo-api.session.b7c275c5-a4d6-40a0-a905-2c767181ef14",
"application": {
"applicationId": "amzn1.ask.skill.a6415548-f2a7-4098-8d6b-62a74c41fb60"
},
"attributes": {},
"user": {
"userId": "amzn1.ask.account.AEI2SJB7LJZYKBWBT23GK4W4WGU2NYIWO7YG5UG3PRXRVICLXOHYB33PZXP63NNBIW4ZIIJF63XTT32CKBGKJDIIMNH32DD6VTFUYE4MW3D72OVKZ52UGSGVDKDD4TDAK3Q2AXBAKQHZ5R3XZDLXFWC3OAY5HMV3BL47NG7YKS43WR3RLM4UEMQBC2EQM6OPSWJIWALUGSYVO7A"
}
},
"context": {
"Viewports": [
{
"type": "APL",
"id": "main",
"shape": "RECTANGLE",
"dpi": 213,
"presentationType": "STANDARD",
"canRotate": false,
"configuration": {
"current": {
"mode": "HUB",
"video": {
"codecs": [
"H_264_42",
"H_264_41"
]
},
"size": {
"type": "DISCRETE",
"pixelWidth": 1280,
"pixelHeight": 800
}
}
}
}
],
"Viewport": {
"experiences": [
{
"arcMinuteWidth": 346,
"arcMinuteHeight": 216,
"canRotate": false,
"canResize": false
}
],
"mode": "HUB",
"shape": "RECTANGLE",
"pixelWidth": 1280,
"pixelHeight": 800,
"dpi": 213,
"currentPixelWidth": 1280,
"currentPixelHeight": 800,
"touch": [
"SINGLE"
],
"video": {
"codecs": [
"H_264_42",
"H_264_41"
]
}
},
"Extensions": {
"available": {
"aplext:backstack:10": {}
}
},
"System": {
"application": {
"applicationId": "amzn1.ask.skill.a6415548-f2a7-4098-8d6b-62a74c41fb60"
},
"user": {
"userId": "amzn1.ask.account.AEI2SJB7LJZYKBWBT23GK4W4WGU2NYIWO7YG5UG3PRXRVICLXOHYB33PZXP63NNBIW4ZIIJF63XTT32CKBGKJDIIMNH32DD6VTFUYE4MW3D72OVKZ52UGSGVDKDD4TDAK3Q2AXBAKQHZ5R3XZDLXFWC3OAY5HMV3BL47NG7YKS43WR3RLM4UEMQBC2EQM6OPSWJIWALUGSYVO7A"
},
"device": {
"deviceId": "amzn1.ask.device.AG7VS7XSFW5VZ73I6A7HFTJPUO56OU4TAM2ICF2KIU75TSD3U53KGGOIYR4IUUUPMRC7AR3KY3X5JT3IDBJ5VADVZLQTWLXFNPSJC3BKM6QOH4IYJLGB3HZOKXMD5XTYZPQILBUHROBVAYAOQ7ZNJRSFFR62DW3G2ZCG3MEMBT45MIRT56F44",
"supportedInterfaces": {}
},
"apiEndpoint": "https://api.amazonalexa.com",
"apiAccessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.eyJhdWQiOiJodHRwczovL2FwaS5hbWF6b25hbGV4YS5jb20iLCJpc3MiOiJBbGV4YVNraWxsS2l0Iiwic3ViIjoiYW16bjEuYXNrLnNraWxsLmE2NDE1NTQ4LWYyYTctNDA5OC04ZDZiLTYyYTc0YzQxZmI2MCIsImV4cCI6MTY0MTM0Nzk4NiwiaWF0IjoxNjQxMzQ3Njg2LCJuYmYiOjE2NDEzNDc2ODYsInByaXZhdGVDbGFpbXMiOnsiY29udGV4dCI6IkFBQUFBQUFBQUFBdUVDMVZqR1IvSklqOXR4VDJqMXljS3dFQUFBQUFBQUNpSlhzaGQ3eXhVUEViZjNnMWk2c1JiYmMwTENQN2hnUm5OZXlmTnNKdldWWHE5QWg3ajdkNC8raEJxYnB6THpoYzJiR0dNeHdLdFlQZ3FDK08xdWh0b3dGcFBaaEE0RElnN1FFNXE5dDBaalR0M0VnejdCeDhOWDloYm9mVG1TOHc0VWZ5NGc0dVA1RVducHYvQUtzNGlRSzdNbmh0a3hEdm8vMzNycmRWZ0JzTm5wM1l5bDBNSHE4QTBkVS85VUdZUlZ5Q0FyaTJqeFBVMTZIVTJhWFJZTWZuN2FDeTBEa0FWUk81TXliYUJDWklxSjhxaWtUUURoOUE5NlAxNTREc3hrK0FkMnVyRUVrN1E2VC84a0grYVkyVjQ3dVRFM1h4cWppVCt1KzBsR0M5N3JpdXpSU2Z5MGtXVlpwNFBLTGZpU0dlRzJIbHNtRE5HRFFwNUJRZy8yaittVHNYdXEweDlkR3QrYUpNYTh0VkFHTzd6RVBHelZxMlFydllFRXA2aHNPdWxoaTlQc1I0aXc9PSIsImNvbnNlbnRUb2tlbiI6bnVsbCwiZGV2aWNlSWQiOiJhbXpuMS5hc2suZGV2aWNlLkFHN1ZTN1hTRlc1Vlo3M0k2QTdIRlRKUFVPNTZPVTRUQU0ySUNGMktJVTc1VFNEM1U1M0tHR09JWVI0SVVVVVBNUkM3QVIzS1kzWDVKVDNJREJKNVZBRFZaTFFUV0xYRk5QU0pDM0JLTTZRT0g0SVlKTEdCM0haT0tYTUQ1WFRZWlBRSUxCVUhST0JWQVlBT1E3Wk5KUlNGRlI2MkRXM0cyWkNHM01FTUJUNDVNSVJUNTZGNDQiLCJ1c2VySWQiOiJhbXpuMS5hc2suYWNjb3VudC5BRUkyU0pCN0xKWllLQldCVDIzR0s0VzRXR1UyTllJV083WUc1VUczUFJYUlZJQ0xYT0hZQjMzUFpYUDYzTk5CSVc0WklJSkY2M1hUVDMyQ0tCR0tKRElJTU5IMzJERDZWVEZVWUU0TVczRDcyT1ZLWjUyVUdTR1ZES0RENFREQUszUTJBWEJBS1FIWjVSM1haRExYRldDM09BWTVITVYzQkw0N05HN1lLUzQzV1IzUkxNNFVFTVFCQzJFUU02T1BTV0pJV0FMVUdTWVZPN0EifX0.YxsDZNDIU69YvWX7RmjTF6UzeoMSp8fTK6jlhTe4qoS-JAfXUxPkzjygs3QMKfphu7B-a5Ht8zkXybuGR1S_rny3-46UiehOJHRdrYoyf46K_9pCNCehFsOjsPf7sH5-QgqSetDHcy9qgbGUs1MSnh5oAN0tZdpXBdYtopjcW6h2N0GFnaeNGVi2iuhQgkO-qz4FXlB1rfbAPWXzfxKMI6GLNAdLMusjXpgqVeFJasyg-a6OXr_9cHfkIKJZsYSEtfRrOYJkQUcgnYLfvwqKdmVcORrL2bUuRvFYb4YQa49K6d2vcwJg8Y2mHtomCzElIr9N-4tdPwgU5LvrFWv75A"
}
},
"request": {
"type": "IntentRequest",
"requestId": "amzn1.echo-api.request.3ed6b0ec-ef10-4816-bb17-ecdd18dccdac",
"locale": "en-US",
"timestamp": "2022-01-05T01:54:47Z",
"intent": {
"name": "GetRemoteDataIntent",
"confirmationStatus": "NONE"
}
}
}
JSON 输出 1:
{
"body": {
"version": "1.0",
"response": {
"outputSpeech": {
"type": "SSML",
"ssml": "<speak>Sorry, I can't understand the command. Please say again.</speak>"
},
"reprompt": {
"outputSpeech": {
"type": "SSML",
"ssml": "<speak>Sorry, I can't understand the command. Please say again.</speak>"
}
},
"shouldEndSession": false,
"type": "_DEFAULT_RESPONSE"
},
"sessionAttributes": {},
"userAgent": "ask-node/2.11.0 Node/v12.22.7"
}
}
Index.js:
/* eslint-disable func-names */
/* eslint-disable no-console */
const Alexa = require("ask-sdk-core");
const http = require("https");
// greating message hello there.
const GetLaunchHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === "LaunchRequest";
},
handle(handlerInput) {
const speechText = "Hello there. How can i help you today?";
return handlerInput.responseBuilder
.speak(speechText)
.reprompt()
.getResponse();
}
};
// ----- find the elevator status of a elevator specific-----
const GetStatusHandler = {
canHandle(handlerInput) {
return (
handlerInput.requestEnvelope.request.intent.name === "GetStatusIntent"
);
},
async handle(handlerInput) {
let outputSpeech = "This is the default message.";
const id = handlerInput.requestEnvelope.request.intent.slots.id.value;
if (id > 200) {
outputSpeech = "Please enter a valid number";
return handlerInput.responseBuilder
.speak(outputSpeech)
.reprompt()
.getResponse();
}
//need to add elevator status endpoint
const elevatorStatus = await getRemoteElevatorData(
"https://jakerocket.azurewebsites.net/elevator/" + id
);
const elevator = JSON.parse(elevatorStatus);
outputSpeech = `The status of elevator ${id} is ${elevator} `;
return handlerInput.responseBuilder
.speak(outputSpeech)
.reprompt()
.getResponse();
}
};
// ----- make all get for the big sentence -----
const GetRemoteDataHandler = {
canHandle(handlerInput) {
return (
handlerInput.requestEnvelope.request.type === "IntentRequest" &&
handlerInput.requestEnvelope.request.intent.name === "GetRemoteDataIntent"
);
},
async handle(handlerInput) {
let outputSpeech = "This is the default message.";
//elevators that are not in running status and are being serviced
const elevatorData = await getRemoteElevatorData(
"https://jakerocket.azurewebsites.net/elevator/inactive"
);
const elevatorAllData = await getRemoteElevatorAllData(
"https://jakerocket.azurewebsites.net/elevator"
);
const buildingData = await getRemoteBuildingData(
"https://jakerocket.azurewebsites.net/buildings"
);
const customerData = await getRemoteCustomerData(
"https://jakerocket.azurewebsites.net/customer"
);
const batteryData = await getRemoteBatteryData(
"https://jakerocket.azurewebsites.net/battery"
);
const AddressCityData = await getRemoteCityData(
"https://jakerocket.azurewebsites.net/address"
);
const QuoteData = await getQuoteData(
"https://jakerocket.azurewebsites.net/quote"
);
const LeadData = await getLeadData(
"https://jakerocket.azurewebsites.net/leads"
);
const elevator = JSON.parse(elevatorData);
const elevatorAll = JSON.parse(elevatorAllData);
const building = JSON.parse(buildingData);
const customer = JSON.parse(customerData);
const batteries = JSON.parse(batteryData);
const cities = JSON.parse(AddressCityData);
const quotes = JSON.parse(QuoteData);
const leads = JSON.parse(LeadData);
outputSpeech = `Hi Sir welcome to Rocket Elevator Statistic. There are currently ${
elevatorAll.length
} elevators deployed in the ${building.length} buildings of your ${
customer.length
} customers . Currently, ${
elevator.length
} elevators are not in Running Status and are being serviced.
${batteries.length} Batteries are deployed across ${
cities.length
} cities. On another note you currently have ${
quotes.length
} quotes awaiting processing. You also have ${
leads.length
} leads in your contact requests
`;
return handlerInput.responseBuilder
.speak(outputSpeech)
.reprompt()
.getResponse();
}
};
// ----- help commands -----
const HelpIntentHandler = {
canHandle(handlerInput) {
return (
handlerInput.requestEnvelope.request.type === "IntentRequest" &&
handlerInput.requestEnvelope.request.intent.name === "AMAZON.HelpIntent"
);
},
handle(handlerInput) {
const speechText =
`Here is the list of all commands : what is the status of elevator {id},Can you tell me the status of elevator {id}, how is rocket elevators going, what is happening at rocket elevators, what is going on`;
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.getResponse();
}
};
const CancelAndStopIntentHandler = {
canHandle(handlerInput) {
return (
handlerInput.requestEnvelope.request.type === "IntentRequest" &&
(handlerInput.requestEnvelope.request.intent.name ===
"AMAZON.CancelIntent" ||
handlerInput.requestEnvelope.request.intent.name ===
"AMAZON.StopIntent")
);
},
handle(handlerInput) {
const speechText = "Goodbye!";
return handlerInput.responseBuilder.speak(speechText).getResponse();
}
};
const SessionEndedRequestHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === "SessionEndedRequest";
},
handle(handlerInput) {
console.log(
`Session ended with reason: ${
handlerInput.requestEnvelope.request.reason
}`
);
return handlerInput.responseBuilder.getResponse();
}
};
const ErrorHandler = {
canHandle() {
return true;
},
handle(handlerInput, error) {
console.log(`Error handled: ${error.message}`);
return handlerInput.responseBuilder
.speak("Sorry, I can't understand the command. Please say again.")
.reprompt("Sorry, I can't understand the command. Please say again.")
.getResponse();
}
};
const getLeadData = function(url) {
return new Promise((resolve, reject) => {
const client = url.startsWith("https") ? require("https") : require("http");
const request = client.get(url, response => {
if (response.statusCode < 200 || response.statusCode > 299) {
reject(new Error("Failed with status code: " + response.statusCode));
}
const body = [];
response.on("data", chunk => body.push(chunk));
response.on("end", () => resolve(body.join("")));
});
request.on("error", err => reject(err));
});
};
const getRemoteElevatorData = function(url) {
return new Promise((resolve, reject) => {
const client = url.startsWith("https") ? require("https") : require("http");
const request = client.get(url, response => {
if (response.statusCode < 200 || response.statusCode > 299) {
reject(new Error("Failed with status code: " + response.statusCode));
}
const body = [];
response.on("data", chunk => body.push(chunk));
response.on("end", () => resolve(body.join("")));
});
request.on("error", err => reject(err));
});
};
const getRemoteElevatorAllData = function(url) {
return new Promise((resolve, reject) => {
const client = url.startsWith("https") ? require("https") : require("http");
const request = client.get(url, response => {
if (response.statusCode < 200 || response.statusCode > 299) {
reject(new Error("Failed with status code: " + response.statusCode));
}
const body = [];
response.on("data", chunk => body.push(chunk));
response.on("end", () => resolve(body.join("")));
});
request.on("error", err => reject(err));
});
};
const getQuoteData = function(url) {
return new Promise((resolve, reject) => {
const client = url.startsWith("https") ? require("https") : require("http");
const request = client.get(url, response => {
if (response.statusCode < 200 || response.statusCode > 299) {
reject(new Error("Failed with status code: " + response.statusCode));
}
const body = [];
response.on("data", chunk => body.push(chunk));
response.on("end", () => resolve(body.join("")));
});
request.on("error", err => reject(err));
});
};
const getRemoteBuildingData = function(url) {
return new Promise((resolve, reject) => {
const client = url.startsWith("https") ? require("https") : require("http");
const request = client.get(url, response => {
if (response.statusCode < 200 || response.statusCode > 299) {
reject(new Error("Failed with status code: " + response.statusCode));
}
const body = [];
response.on("data", chunk => body.push(chunk));
response.on("end", () => resolve(body.join("")));
});
request.on("error", err => reject(err));
});
};
const getRemoteCityData = function(url) {
return new Promise((resolve, reject) => {
const client = url.startsWith("https") ? require("https") : require("http");
const request = client.get(url, response => {
if (response.statusCode < 200 || response.statusCode > 299) {
reject(new Error("Failed with status code: " + response.statusCode));
}
const body = [];
response.on("data", chunk => body.push(chunk));
response.on("end", () => resolve(body.join("")));
});
request.on("error", err => reject(err));
});
};
const getRemoteCustomerData = function(url) {
return new Promise((resolve, reject) => {
const client = url.startsWith("https") ? require("https") : require("http");
const request = client.get(url, response => {
if (response.statusCode < 200 || response.statusCode > 299) {
reject(new Error("Failed with status code: " + response.statusCode));
}
const body = [];
response.on("data", chunk => body.push(chunk));
response.on("end", () => resolve(body.join("")));
});
request.on("error", err => reject(err));
});
};
const getRemoteBatteryData = function(url) {
return new Promise((resolve, reject) => {
const client = url.startsWith("https") ? require("https") : require("http");
const request = client.get(url, response => {
if (response.statusCode < 200 || response.statusCode > 299) {
reject(new Error("Failed with status code: " + response.statusCode));
}
const body = [];
response.on("data", chunk => body.push(chunk));
response.on("end", () => resolve(body.join("")));
});
request.on("error", err => reject(err));
});
};
const skillBuilder = Alexa.SkillBuilders.custom();
exports.handler = skillBuilder
.addRequestHandlers(
GetLaunchHandler,
GetRemoteDataHandler,
HelpIntentHandler,
CancelAndStopIntentHandler,
SessionEndedRequestHandler,
GetStatusHandler
)
.addErrorHandlers(ErrorHandler)
.lambda();
最后,JSON 交互模型:
{
"interactionModel": {
"languageModel": {
"invocationName": "rocket elevators",
"intents": [
{
"name": "GetLaunchIntent",
"slots": [],
"samples": [
"hi",
"hello"
]
},
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": [
"help"
]
},
{
"name": "AMAZON.StopIntent",
"samples": []
},
{
"name": "GetStatusIntent",
"slots": [
{
"name": "id",
"type": "AMAZON.NUMBER"
}
],
"samples": [
"what is the status of elevator {id}",
"Can you tell me the status of elevator {id}"
]
},
{
"name": "GetRemoteDataIntent",
"slots": [],
"samples": [
"how is rocket elevators going",
"what is happening at rocket elevators",
"what is going on"
]
},
{
"name": "AMAZON.NavigateHomeIntent",
"samples": []
}
],
"types": []
}
}
}
我对 Alexa 技能开发还很陌生,我只是在学习一个可能有点过时的教程。任何帮助将不胜感激!
在您的交互模型中添加 AMAZON.FallbackIntent。
“抱歉,我无法理解该命令。请再说一遍。”此语音输出应在请求 AMAZON.FallbackIntent 时发送,而不是在出错时发送。
我不知道 javascript 是如何工作的,但我认为你的代码中有一些错误会触发 errorHandler 然后给出输出。