我对alexa,nodejs和编码很新,但我目前正在尝试使用日期和时间创建一个从我的dynamodb表中查找机器状态的技能。
我目前已经设置了我的技能,让alexa和lambda了解我的插槽值,但我不知道如何将这些值用于dynamodb查询并让alexa调用相应时间的状态
我的表设置了主键和排序键,它们是日期和时间,我有第三列机器状态。
我不确定我是否应该为机器状态设置一个自定义插槽,因为它很容易做,因为只有4种可能的状态。
以下是我目前的代码,请随时清理部件或解释您是如何找到我的解决方案的。
const awsSDK = require('aws-sdk');
const updatedincident = 'updatedincident';
const docClient = new awsSDK.DynamoDB.DocumentClient();
var AWSregion = 'us-east-1'; // us-east-1
var AWS = require('aws-sdk');
var dbClient = new AWS.DynamoDB.DocumentClient();
AWS.config.update({
region: "'us-east-1'"
});
const params = {
TableName: "updatedincident",
Key:{ date: "2018-03-28",
time: "04:23",
state: "Blocked Primary"
}
};
let GetMachineStateIntent = (context, callback) => {
var params = {
TableName: "updatedincident",
Key: {
date: "2018-03-28",
time: "04:23",
state: "Blocked Primary"
}
};
dbClient.get(params, function (err, data) {
if (err) {
// failed to read from table for some reason..
console.log('failed to load data item:\n' + JSON.stringify(err, null, 2));
// let skill tell the user that it couldn't find the data
sendResponse(context, callback, {
output: "the data could not be loaded from your database",
endSession: false
});
} else {
console.log('loaded data item:\n' + JSON.stringify(data.Item, null, 2));
// assuming the item has an attribute called "state"..
sendResponse(context, callback, {
output: data.Item.state,
endSession: false
});
}
});
};
function sendResponse(context, callback, responseOptions) {
if(typeof callback === 'undefined') {
context.succeed(buildResponse(responseOptions));
} else {
callback(null, buildResponse(responseOptions));
}
}
function buildResponse(options) {
var alexaResponse = {
version: "1.0",
response: {
outputSpeech: {
"type": "SSML",
"ssml": `<speak><prosody rate="slow">${options.output}</prosody></speak>`
},
shouldEndSession: options.endSession
}
};
if (options.repromptText) {
alexaResponse.response.reprompt = {
outputSpeech: {
"type": "SSML",
"ssml": `<speak><prosody rate="slow">${options.reprompt}</prosody></speak>`
}
};
}
return alexaResponse;
}
exports.handler = (event, context, callback) => {
try {
var request = event.request;
if (request.type === "LaunchRequest") {
sendResponse(context, callback, {
output: "welcome to my skill, I can tell you about the status of machines at different times. what data are you looking for?",
endSession: false
});
}
else if (request.type === "IntentRequest") {
if (request.type === "IntentRequest"
// make sure the name of the intent matches the one in interaction model
&& request.intent.name == "GetMachineStateIntent") {
var dateSlot = request.intent.slots.Date != null ?
request.intent.slots.Date.value : "unknown date";
var timeSlot = request.intent.slots.Time != null ?
request.intent.slots.Time.value : "unknown time";
// respond with speech saying back what the skill thinks the user requested
sendResponse(context, callback, {
output: "You wanted the machine state at "
+ timeSlot + " on " + dateSlot,
endSession: false
});
var ConfirmationHandlers = Alexa.CreateStateHandler(states.CONFIRMATIONMODE, {
'YesIntent': function () {
this.emit("GetMachineStateIntent");
},
'AMAZON.NoIntent': function () {
this.response.speak(GetMachineStateIntent);
this.emit(':responseReady');
}
});
}
let options = {};
if (request.intent.name === "GetMachineStateIntent") {
GetMachineStateIntent(context, callback);
} else if (request.intent.name === "AMAZON.StopIntent" || request.intent.name === "AMAZON.CancelIntent") {
sendResponse(context, callback, {
output: "ok. good bye!",
endSession: true
});
}
else if (request.intent.name === "AMAZON.HelpIntent") {
sendResponse(context, callback, {
output: "you can ask me about incidents that have happened or states of machines in the past",
reprompt: "what can I help you with?",
endSession: false
});
}
else {
sendResponse(context, callback, {
output: "I don't know that one! please try again!",
endSession: false
});
}
}
else if (request.type === "SessionEndedRequest") {
sendResponse(context, callback, ""); // no response needed
}
else {
// an unexpected request type received.. just say I don't know..
sendResponse(context, callback, {
output: "I don't know that one! please try again!",
endSession: false
});
}
} catch (e) {
// handle the error by logging it and sending back an failure
console.log('Unexpected error occurred in the skill handler!', e);
if(typeof callback === 'undefined') {
context.fail("Unexpected error");
} else {
callback("Unexpected error");
}
}
};
&#13;
更新************
目前正在回答alexa中的技能I / O
"request": {
"type": "IntentRequest",
"requestId": "amzn1.echo-api.request.c515c39e-4ce1-4f28-97ed-30536fa593b9",
"timestamp": "2018-05-15T08:55:25Z",
"locale": "en-GB",
"intent": {
"name": "GetMachineStateIntent",
"confirmationStatus": "NONE",
"slots": {
"Time": {
"name": "Time",
"value": "04:23",
"confirmationStatus": "NONE"
},
"Date": {
"name": "Date",
"value": "2018-03-28",
"confirmationStatus": "NONE"
}
}
},
"dialogState": "STARTED"
}
}
&#13;
答案 0 :(得分:1)
有几点意见:
<强>第一强>
在处理GetMachineStateIntent
的代码分支中,您添加了代码来创建状态处理程序,但它们没有正确连接。最好的代码什么都不做,最坏的情况可能会导致一些问题。删除它。
// take the following lines of code out
var ConfirmationHandlers = Alexa.CreateStateHandler(states.CONFIRMATIONMODE, {
'YesIntent': function () {
this.emit("GetMachineStateIntent");
},
'AMAZON.NoIntent': function () {
this.response.speak(GetMachineStateIntent);
this.emit(':responseReady');
}
});
秒您传递给DynamoDB查询的查询参数是硬编码的。这意味着你总是会得到相同的结果。您需要将意图中接收的插槽值传递给查询参数。
var params = {
TableName: "updatedincident",
Key: {
date: "2018-03-28",
time: "04:23",
state: "Blocked Primary"
}
};
这些都是硬编码的。您只需指定主键(date
)和排序键(&#39;时间&#39;),这样您就可以删除state
。对于date
和time
,您必须更改要从dateSlot
和timeSlot
动态传入的值。
第三在处理IntentRequest
类型请求的代码分支中,您处理GetMachineStateIntent
两次,代码有点多余。重写如下:
...
} else if (request.type === "IntentRequest") {
if (request.intent.name === "GetMachineStateIntent") {
GetMachineStateIntent(context, callback);
} else if (request.intent.name === "AMAZON.StopIntent" || request.intent.name === "AMAZON.CancelIntent") {
sendResponse(context, callback, {
output: "ok. good bye!",
endSession: true
});
}
else if (request.intent.name === "AMAZON.HelpIntent") {
sendResponse(context, callback, {
output: "you can ask me about incidents that have happened or states of machines in the past",
reprompt: "what can I help you with?",
endSession: false
});
}
else {
sendResponse(context, callback, {
output: "I don't know that one! please try again!",
endSession: false
});
}
} else if (request.type === "SessionEndedRequest") {
<强>四强> 这是最难解释的。查询计算机状态时,您将提供日期和时间,但可能是机器状态可能未存储在数据库中,其时间戳与查询中的时间值完全匹配。所以你必须做一个基本上相当于&#34的查询;什么是日期X的机器状态,在最近的时间之前或等于Y&#34;
这是&#34;最近一次或等于Y&#34;部分是棘手的。您必须在表上创建表达该查询的查询,并且还必须更改表中存储时间戳的方式,从字符串到数字格式,以便您可以轻松表达此不等式。
我将在这里展示如何传递dateSlot和timeSlot来进行查询,但我建议你研究一下这个问题(如果你遇到问题,可能会问一些具体的问题)。
以下是我提到的修改代码:
const awsSDK = require('aws-sdk');
const updatedincident = 'updatedincident';
const docClient = new awsSDK.DynamoDB.DocumentClient();
var AWSregion = 'us-east-1'; // us-east-1
var AWS = require('aws-sdk');
var dbClient = new AWS.DynamoDB.DocumentClient();
AWS.config.update({
region: "'us-east-1'"
});
let GetMachineStateIntent = (context, callback, dateSlot, timeSlot) => {
var params = {
TableName: "updatedincident",
KeyConditionExpression: '#d = :dVal and #t < :tVal',
ExpressionAttributeValues: {
':dVal': dateSlot,
':tVal': timeSlot
},
ExpressionAttributeNames: {
'#d': 'date',
'#t': 'time'
},
ScanIndexForward: false // gets values in reverse order by time
};
dbClient.query(params, function (err, data) {
if (err) {
// failed to read from table for some reason..
console.log('failed to load data item:\n' + JSON.stringify(err, null, 2));
// let skill tell the user that it couldn't find the data
sendResponse(context, callback, {
output: "the data could not be loaded from your database",
endSession: false
});
} else {
let dataItem = data.Items[0];
console.log('loaded data item:\n' + JSON.stringify(dataItem, null, 2));
// assuming the item has an attribute called "state"..
sendResponse(context, callback, {
output: dataItem.state,
endSession: false
});
}
});
};
function sendResponse(context, callback, responseOptions) {
if(typeof callback === 'undefined') {
context.succeed(buildResponse(responseOptions));
} else {
callback(null, buildResponse(responseOptions));
}
}
function buildResponse(options) {
var alexaResponse = {
version: "1.0",
response: {
outputSpeech: {
"type": "SSML",
"ssml": `<speak><prosody rate="slow">${options.output}</prosody></speak>`
},
shouldEndSession: options.endSession
}
};
if (options.repromptText) {
alexaResponse.response.reprompt = {
outputSpeech: {
"type": "SSML",
"ssml": `<speak><prosody rate="slow">${options.reprompt}</prosody></speak>`
}
};
}
return alexaResponse;
}
exports.handler = (event, context, callback) => {
try {
var request = event.request;
if (request.type === "LaunchRequest") {
sendResponse(context, callback, {
output: "welcome to my skill, I can tell you about the status of machines at different times. what data are you looking for?",
endSession: false
});
} else if (request.type === "IntentRequest") {
if (request.intent.name === "GetMachineStateIntent") {
var dateSlot = request.intent.slots.Date != null
? request.intent.slots.Date.value : null;
var timeSlot = request.intent.slots.Time != null
? request.intent.slots.Time.value : null;
// pass the slot values to the GetMachineStateIntent function
GetMachineStateIntent(context, callback, dateSlot, timeSlot);
} else if (request.intent.name === "AMAZON.StopIntent" || request.intent.name === "AMAZON.CancelIntent") {
sendResponse(context, callback, {
output: "ok. good bye!",
endSession: true
});
}
else if (request.intent.name === "AMAZON.HelpIntent") {
sendResponse(context, callback, {
output: "you can ask me about incidents that have happened or states of machines in the past",
reprompt: "what can I help you with?",
endSession: false
});
}
else {
sendResponse(context, callback, {
output: "I don't know that one! please try again!",
endSession: false
});
}
}
else if (request.type === "SessionEndedRequest") {
sendResponse(context, callback, ""); // no response needed
}
else {
// an unexpected request type received.. just say I don't know..
sendResponse(context, callback, {
output: "I don't know that one! please try again!",
endSession: false
});
}
} catch (e) {
// handle the error by logging it and sending back an failure
console.log('Unexpected error occurred in the skill handler!', e);
if(typeof callback === 'undefined') {
context.fail("Unexpected error");
} else {
callback("Unexpected error");
}
}
};
&#13;