这是你的幸运日。这就是我MODES
在 Node.js 中使用多个执行此操作的方式。
免责声明:我提供这个冗长的回复是因为我非常渴望获得声誉积分,并想成为一名开发人员布道者。;)
鉴于 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
并为其提供适当的名称,它将在会话状态中保存学生的名称,并将模式更改为CLASSMODE
仅接受 Intents ClassNameIntent 和 BackIntent。如果您尝试调用其他意图,系统会再次提示您输入类的名称UnhandledIntent
. 在提供适当的课程或说“全部”后,您将收到回复,并且模式将更改回STUDENTMODE
. 这会让你回到大厅,在那里你可以询问其他学生的问题。瞧!
这种改变模式的过程比多部分意图模式要好得多,比如“告诉我 {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
您可以阻止不需要的意图的不同方式得到解答。如果您发现此回复有帮助,我会以三叉戟层和声誉付款。谢谢!