我尝试使用Alexa创建一项技能,使用扫描或查询功能(或两者)从DynamoDB表中读取数据。
我表格中的列是日期,时间和电影名称。
我是新手,但我设法将我的Lambda功能链接到Alexa。我还创建了一个单独的Lambda函数,当我配置测试事件时,它将从我的表中调用数据,因此当我输入特定日期时,它将调用相应的电影和时间。但是现在我想把它实现到Alexa中并且不确定如何。
这是我目前的代码
console.log('Loading function');
var AWSregion = 'us-east-1'; // us-east-1
var AWS = require('aws-sdk');
var dclient = new AWS.DynamoDB.DocumentClient();
var getItems = (event, context, callback)=>{
dclient.get(event.params,(error,data)=>{
if(error){
callback(null,"error occurerd");
}
else{
callback(null,data);
}
});
};
exports.handler = getItems;
exports.handler = (event, context, callback) => {
try {
var request = event.request;
if (request.type === "LaunchRequest") {
context.succeed(buildResponse({
speechText: "Welcome to H.S.S.M.I skill, what would you like to find",
repromptText: "I repeat, Welcome to my skill, what would you like to find",
endSession: false
}));
}
else if (request.type === "IntentRequest") {
let options = {};
if (request.intent.name === "cinema") {
} else if (request.intent.name === "AMAZON.StopIntent" || request.intent.name === "AMAZON.CancelIntent") {
options.speechText = "ok, good bye.";
options.endSession = true;
context.succeed(buildResponse(options));
}
else if (request.intent.name === "AMAZON.HelpIntent") {
options.speechText = "My skill will read your table depending on what is asked. For example, you can ask what about a specific date. Please refer to skill description for all possible utterences.";
options.repromptText = "What is the data sign you want to know about today? If you want to exit from my skill please say stop or cancel.";
options.endSession = false;
context.succeed(buildResponse(options));
}
else {
context.fail("Unknown Intent");
}
}
else if (request.type === "SessionEndedRequest") {
options.endSession = true;
context.succeed();
}
else {
context.fail("Unknown Intent type");
}
} catch (e) {
}
};
function buildResponse(options) {
var response = {
version: "1.0",
response: {
outputSpeech: {
"type": "SSML",
"ssml": `<speak><prosody rate="slow">${options.speechText}</prosody></speak>`
},
shouldEndSession: options.endSession
}
};
if (options.repromptText) {
response.response.reprompt = {
outputSpeech: {
"type": "SSML",
"ssml": `<speak><prosody rate="slow">${options.repromptText}</prosody></speak>`
}
};
}
return response;
}
function readDynamoItem(params, callback) {
var AWS = require('aws-sdk');
AWS.config.update({region: AWSregion});
var dynamodb = new AWS.DynamoDB();
console.log('reading item from DynamoDB table');
dynamodb.scan(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else{
console.log(data); // successful response
callback(JSON.stringify(data));
}
});
var docClient = new AWS.DynamoDB.DocumentClient();
//Get item by key
docClient.get(params, (err, data) => {
if (err) {
console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2));
} else {
console.log("GetItem succeeded:", JSON.stringify(data, null, 2));
callback(data.Item.message); // this particular row has an attribute called message
}
});
}
///////////////////////////////////////////////////////////////////////////////
&#13;
这是我的DBHandler
var AWS = require('aws-sdk');
AWS.config.update({
region: "'us-east-1'"
});
let docClient = new AWS.DynamoDB.DocumentClient();
var table = "Cinema";
let getItems = (Id,callback) => {
var params = {
TableName: "cinema",
Key: {
"date": "2018-01-04",
"filmname": "rugrats"
}
};
docClient.get(params, function (err, data) {
callback(err, data);
});
};
module.exports = {
getItems
};
&#13;
我可以启动应用程序,并且我有一个Lambda函数,当我配置测试事件以从某个日期查找电影时,它可以独立工作,但我不能让它与Alexa一起工作。
任何人都可以帮助我或指明我出错的地方
UPDATE *************
以下是我的意图架构的设置方式
{
"intents": [
{
"slots": [
{
"name": "sincedate",
"type": "AMAZON.DATE"
}
],
"intent": "date"
},
{
"intent": "AMAZON.CancelIntent"
},
{
"intent": "AMAZON.HelpIntent"
},
{
"intent": "AMAZON.StopIntent"
},
{
"slots": [
{
"name": "sincedate",
"type": "AMAZON.DATE"
}
],
"intent": "cinema"
},
{
"intent": "MyIntent"
}
]
}
&#13;
答案 0 :(得分:1)
您可能无法从技能中读取DynamoDB的一个可能原因是权限。
您应该仔细检查分配给技能lambda的IAM角色,以确保它具有从DynamoDB读取的权限。
一些参考文献:
我重新阅读了您的问题,我对您谈论设置第二个Lambda以从Dynamo读取数据的部分感到困惑。你不应该有两个Lambda函数 - 只有一个处理来自Alexa的请求,并且在调用Dynamo之后你应该将你的响应返回给Alexa。
现在,具体细节。在您的第一个代码段中,您有:
exports.handler = getItems;
exports.handler = (event, context, callback) => {
// here you have your handler to handle alexa responses
}
立即突出的一点是,您首先将处理程序设置为getItems
,然后重置回应该响应Alexa的处理程序。
我猜测的另一件事是,有时技能会起作用,就像你第一次启动时一样,可能是你说帮助,但在其他情况下它并不是,就像你发送时一样它是电影&#34;意图。
这是因为从Alexa请求到您的技能的入口点是exports.handler
,它基本上被定义为具有三个参数的函数(它像void main(int argc,char * argv)交流计划的[])。
第一个参数 - event
是您技能的输入。 Alexa将在此处提供信息,例如请求类型,是否为意图,意图名称,会话信息等。
第二个和第三个参数 - context
和callback
是用于从lambda函数返回控制的内容,具体取决于节点运行时。对于Note v4和更新版本,您使用回调,对于旧版本,您使用上下文。
您可以使用类似的内容发回成功回复:
if(typeof callback === 'undefined') {
context.succeed("successful response message");
} else {
callback(null, "successful response message");
}
这样的事情发送失败的回复
if(typeof callback === 'undefined') {
context.fail("failure response message");
} else {
callback("failure response message", null);
}
总而言之,这里是一个基本的Lambda处理程序,它始终响应您的技能调用:
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. what do you want to find?",
endSession: false
});
}
else if (request.type === "IntentRequest") {
let options = {};
if (request.intent.name === "cinema") {
// this is where we will wire up the dynamo call
// for now, just send a simple response and end the session
sendResponse(context, callback, {
output: "cinema not implemented yet!",
endSession: true
});
} 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 films",
reprompt: "what can I help you with?"
endSession: false
});
}
else {
sendResponse(context, callback, {
output: "I don't know that one! Good bye!",
endSession: true
});
}
}
else if (request.type === "SessionEndedRequest") {
sendResponse(context, callback, ""); // no response needed
}
else {
// un unexpected request type received.. just say I don't know..
sendResponse(context, callback, {
output: "I don't know that one! Good bye!",
endSession: true
});
}
} 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");
}
}
};
达到这一点,技能应该是有效的,它应该能够处理您的所有请求。假设您已正确配置了交互模型并且cinema
意图已发送给您的技能,那么您可以使用发电机客户端来响应表中的数据。
var AWSregion = 'us-east-1'; // us-east-1
var AWS = require('aws-sdk');
var dbClient = new AWS.DynamoDB.DocumentClient();
let handleCinemaIntent = (context, callback) => {
let params = {
TableName: "cinema",
Key: {
"date": "2018-01-04",
"filmname": "rugrats"
}
};
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 Dynamo",
endSession: true
});
} else {
console.log('loaded data item:\n' + JSON.stringify(data.Item, null, 2))
// assuming the item has an attribute called "message"..
sendResponse(context, callback, {
output: data.Item.message,
endSession: true
});
}
});
};
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. what do you want to find?",
endSession: false
});
}
else if (request.type === "IntentRequest") {
let options = {};
if (request.intent.name === "cinema") {
handleCinemaIntent(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 films",
reprompt: "what can I help you with?"
endSession: false
});
}
else {
sendResponse(context, callback, {
output: "I don't know that one! Good bye!",
endSession: true
});
}
}
else if (request.type === "SessionEndedRequest") {
sendResponse(context, callback, ""); // no response needed
}
else {
// un unexpected request type received.. just say I don't know..
sendResponse(context, callback, {
output: "I don't know that one! Good bye!",
endSession: true
});
}
} 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");
}
}
};