-1

我正在尝试建立一个 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。请告诉我如何做到这一点。

4

3 回答 3

4

这是你的幸运日。这就是我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您可以阻止不需要的意图的不同方式得到解答。如果您发现此回复有帮助,我会以三叉戟层和声誉付款。谢谢!

于 2017-08-04T19:38:43.567 回答
2

需要注意的是,Alexa 不会回应“没有回答”。因此,您需要指导用户回答“全部”或“无”。

于 2017-05-23T10:47:37.233 回答
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"
        }
      ]
    }

您将需要一个 dynamo db 表,其中保存学生姓名,并且在您的技能计划中,您将有一个学生和科目列表。

我不能给你写完整的技能,太复杂了。

只需按照教程进行操作,然后提出具体问题。 https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs

MAKE ME A SKILL 不是问题....

于 2017-05-22T18:53:33.640 回答