2017-05-22 56 views
0

我想建立一个alexa定制技能。我面临的一个问题是,我试图从用户那里获得技术问用户的问题的答复。如何回答的问题 - Alexa

User : Tell me marks of student1 ? 
Alexa: Subject 
User: Maths 
Alexa : student1 marks in maths is {xyz} 

,或者如果用户犯规给任何输入:

User : Tell me marks of student1 ? 
Alexa: Subject 
User: No Answer 
Alexa : Gives marks of all subject for student1. 

我使用Node.js的 请告诉我如何做到这一点。

+0

请添加更多细节,您在哪里遇到问题。你的问题太模糊了。你在使用插槽吗? –

+0

请为此提出一个通用方法,我对此很陌生,几天前就开始了。 – KMittal

回答

2

那么,它很复杂。有几个方法在这里你可以遵循对话机制

https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/dialog-interface-reference

或者你可以使用意图。

你将有学生的意图和学科意图。

"intents": [ 
    { 
     "intent": "Student", 
     "slots": [ 
     { 
      "name": "Students", 
      "type": "LIST_OF_STUDENTS" 
     } 
     ] 
    }, 
    { 
     "intent": "Subject", 
     "slots": [ 
     { 
      "name": "Subjects", 
      "type": "LIST_OF_SUBJECTS" 
     } 
     ] 
    } 

您需要在您保持学生的名字,并在你的技能方案中的发电机db表,你将有学生,和主题的列表。

我不能为你写出整个技能,它太复杂了。

只要按照教程,然后问一个具体的问题。 https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs

让我的技能是不是一个问题....

2

在一点你要注意的是,Alexa的不回应“没有答案”。因此,您需要指导用户使用“全部”或“无”进行回复。

0

这是你的幸运日。这是我如何在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在那里你可以屏蔽掉不需要的意图回答。如果你 发现此回复很有帮助我在三叉戟层和 声望付款。谢谢!