这是你的幸运日。这是我如何在Node.js中使用多个MODES
来实现的。
免责声明:因为我急需您的声誉分,想成为 开发者传道我提供这个漫长的响应。 ;)
鉴于Node.js SDK和它的许多功能,这是我将使用的格式。
// To zip and upload to lambda
// cd Desktop/StudentSkill
// sudo rm -r foo.zip
// zip -r foo.zip .s
'use strict';
var Alexa = require("alexa-sdk");
var appId = 'YOUR-AMAZON-ALEXA-SKILL-ID';
exports.handler = function(event, context, callback) {
var alexa = Alexa.handler(event, context);
alexa.appId = appId;
alexa.registerHandlers(newSessionHandlers, studentSkillSessionHandlers, specificClassSessionHandlers, functionHandlers);
alexa.execute();
};
var states = {
STUDENTMODE: '_STUDENTMODE',
CLASSMODE: '_CLASSMODE',
};
//Variables
var myStudents = {'josh':{'math':'A Plus','english':'A Plus','gym':'C'},'sam':{'math':'A Plus','english':'A minus','gym':'B Plus'}}; //add more classes.
//Could add an intent to create new students.
//var newStudent = {name:{'math':null,'english':null,'gym':null}};
//Could also add an intent to set grades
var newSessionHandlers = {
'NewSession': function() {
this.handler.state = states.STUDENTMODE;
var message = `Welcome to the School Skill, You may add students, edit grades, and review grades. For a list of uses say information. `; //this skill only contains reviewing grades.
var reprompt = ` try saying, grades for josh. `;
this.emit(':ask',message,reprompt);
},
'Unhandled': function() {
console.log("UNHANDLED");
this.emit('NewSession');
}
};
/////////////////////////////////
var studentSkillSessionHandlers = Alexa.CreateStateHandler(states.STUDENTMODE, {//Your location
'NewSession': function() {
this.emit('NewSession'); // Uses the handler in newSessionHandlers
},
//Primary Intents
'GetGradeIntent': function() { // Sampe Utterance: Tell me the marks of {student} or Grades for {student}
this.handler.state = states.CLASSMODE; //Change mode to accept a class, the intent handler getClassIntent is only available in CLASSMODE
this.attributes['CURRENTSTUDENT'] = this.event.request.intent.slots.student.value;
var message = ` which of `+this.attributes['CURRENTSTUDENT']+`'s classes would you like the grade for, name a class or say all. `;
var reprompt = message;
this.emit(':ask',message,reprompt);
},
//Help Intents
"InformationIntent": function() {
console.log("INFORMATION");
var message = ` Try saying, Tell me the marks of josh. `;
this.emit(':ask', message, message);
},
"AMAZON.StopIntent": function() {
console.log("STOPINTENT");
this.emit(':tell', "Goodbye!");
},
"AMAZON.CancelIntent": function() {
console.log("CANCELINTENT");
this.emit(':tell', "Goodbye!");
},
'AMAZON.HelpIntent': function() {
var message = helpMessage;
this.emit(':ask', message, message);
},
//Unhandled
'Unhandled': function() {
console.log("UNHANDLED");
var reprompt = ` That was not an appropriate response. which student would you like grades for. Say, grades for josh. `;
this.emit(':ask', reprompt, reprompt);
}
});
////////////////////////////
/////////////////////////////////
var specificClassSessionHandlers = Alexa.CreateStateHandler(states.CLASSMODE, {//Your location
'NewSession': function() {
this.emit('NewSession'); // Uses the handler in newSessionHandlers
},
//Primary Intents
'GetClassIntent': function() { // {className} class. ex: gym class, math class, english class. It helps to have a word that's not a slot. but amazon may pick it up correctly if you just say {className}
this.attributes['CLASSNAME'] = this.event.request.intent.slots.className.value;
var message = ``;
var reprompt = ``;
if(this.attributes['CLASSNAME'] != undefined){
message = ` I didn't get that class name. would you please repeat it. `;
reprompt = message;
}else{
grade = myStudents[this.attributes['CURRENTSTUDENT']][this.attributes['CLASSNAME']];
if(grade != undefined){
this.handler.state = states.STUDENTMODE; //Answer was present. return to student mode.
message = this.attributes['CURRENTSTUDENT']+`'s `+[this.attributes['CLASSNAME']+` grade is `+aAn(grade)+` `+grade+`. What else would you like to know?`; //Josh's math grade is an A plus.
reprompt = `what else would you like to know?`;
}else{
message = this.attributes['CURRENTSTUDENT']+` does not appear to have a grade for `+[this.attributes['CLASSNAME']+` please try again with a different class or say back.`;
reprompt = `please try again with a different class or say back.`;
}
}
var message = this.attributes['FROM'] + ' .. '+ ProFirstCity;
var reprompt = ProFirstReprompt;
this.emit(':ask',message,reprompt);
},
"AllIntent": function() {// Utterance: All, All Classes
message = ``;
//Not going to code.
//Pseudo code
// for each in json object myStudents[this.attributes['CURRENTSTUDENT']] append to message class name and grade.
this.emit(':ask', message, message);
},
"BackIntent": function() {// Utterance: Back, go back
var message = ` Who's grade would you like to know. try saying, grades for josh. `;
this.emit(':ask', message, message);
},
//Help Intents
"InformationIntent": function() {
console.log("INFORMATION");
var message = ` You've been asked for which of `+this.attributes['CURRENTSTUDENT']+`'s classes you'd his grade. Please name a class or say back. `;
this.emit(':ask', message, 'Name a class or say back.');
},
"AMAZON.StopIntent": function() {
console.log("STOPINTENT");
this.emit(':tell', "Goodbye!");
},
"AMAZON.CancelIntent": function() {
console.log("CANCELINTENT");
this.emit(':tell', "Goodbye!");
},
'AMAZON.HelpIntent': function() {
var message = helpMessage;
this.emit(':ask', message, message);
},
//Unhandled
'Unhandled': function() {
console.log("UNHANDLED");
var reprompt = ' That was not an appropriate response. Name a class or say back.';
this.emit(':ask', reprompt, reprompt);
}
});
////////////////////////////////////////////////////////////
var functionHandlers = {//NOT USED IN THIS APP //Note tied to a specific mode.
};
//#############################HELPERS VVVV#########################
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function clone(a) {
return JSON.parse(JSON.stringify(a));
}
function responseRandomizer(responseType){
let len = responseType.length;
let index = getRandomInt(0,len-1);
return responseType[index];
}
var vowels = {}
function aAn(word){
if(word != ''){
let first = word[0];
if(/[aAeEiIoOuU]/.test(first)){
return 'an';
}else{
return 'a';
}
}else{
return '';
}
}
请注意:此代码是改编自活技能,但它自己没有经过测试。
要开始请求跟进问题,您需要了解不同的stateHandlers
。当你调用一项新技能时,它会从那里进入newSessionHandlers
,你可以运行某种设置代码,然后将MODE
更改为一个大厅,以捕捉该技能的主要意图。我已经命名这个大厅STUDENTMODE
。在STUDENTMODE
里面,你可以询问学生的成绩,理论上你可以创建一个新学生或添加一个班级,或者不添加班级。如果您使用现有的意图GetGradeIntent
并为其提供适当的名称,它会将学生的姓名保存在会话状态中,并将模式更改为仅接受Intents ClassNameIntent和BackIntent的CLASSMODE
。如果你试图调用其他意图,你将被UnhandledIntent
重新命名为类的名字。在提供适当的课程或说“全部”时,您将得到答复,模式将更改回STUDENTMODE
。这会让你回到大厅,在那里你可以提问关于其他学生的问题。瞧!
这种改变模式的过程比Multi Part Intent Schema好像“告诉我{{mathClass}中的{studentName}的成绩”)。虽然这当然有效,但模式更好的一个原因是,如果其中一个输入值不正确,它们允许您正确处理错误,例如学生姓名或班级名称。您可以轻松要求获取单个信息,而不是要求用户重新整理多部分意图。它还允许您在充足的指示下一次处理一小段信息,从而允许Alexa继续提出重新提示问题,直到所有需要的位置填满为止。
我没有涉及的一件物品。
你在哪里存储你的学生?我把它们硬编码到lambda函数中。您可以连接到亚马逊的dynamodb并将您的会话状态存储在那里,以便他们在下一个会话中可用。这实际上与添加一样简单。
alexa.dynamoDBTableName = 'NAME-OF-YOUR-DynamoDB-TABLE'; //You literally dont need any other code it just does the saving and loading??!! WHAT?
在这里你的功能。
exports.handler = function(event, context, callback) {
var alexa = Alexa.handler(event, context);
alexa.appId = appId;
alexa.dynamoDBTableName = 'NAME-OF-YOUR-DynamoDB-TABLE'; //You literally don't need any other code it just does the saving and loading??!! WHAT?
alexa.registerHandlers(newSessionHandlers, studentSkillSessionHandlers, specificClassSessionHandlers, functionHandlers);
alexa.execute();
};
您需要创建一个dynamoDB数据表和一个IAm权限以允许您的lambda函数访问它。然后,神奇地,Alexa将在每个独特用户的数据表中创建一行。一位老师可以很容易地将学生添加到他们的班级中。但是,如果您正在寻找学校中的每位教师访问一个主数据库,这可能不是正确的方法。关于如何将Alexa与多个用户的单个数据表连接起来,可能还有其他教程。
我相信你的问题的核心关注是由 不同MODES
在那里你可以屏蔽掉不需要的意图回答。如果你 发现此回复很有帮助我在三叉戟层和 声望付款。谢谢!
请添加更多细节,您在哪里遇到问题。你的问题太模糊了。你在使用插槽吗? –
请为此提出一个通用方法,我对此很陌生,几天前就开始了。 – KMittal