여러분의 행운의 날입니다. 이것은 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
을 사용하고 해당 이름을 제공하면 세션 이름에 학생의 이름을 저장하고 모드 ClassNameIntent 및 BackIntent 만 허용하는 CLASSMODE
으로 모드를 변경합니다. 다른 인 텐트를 호출하려고 시도하면 UnhandledIntent
에 의해 클래스 이름으로 재발신됩니다.적절한 수업을 제공하거나 "모두"라고 말하면 응답이 제공되며 모드는 STUDENTMODE
으로 다시 변경됩니다. 로비에서 다른 학생들에 대한 질문을 할 수 있습니다. 빌라!
이 모드 변경 프로세스는 다중 부품 의도 스키마의 "{studentName}에 대한 성적 표시 (mathClass)"보다 훨씬 낫습니다. 이것이 확실하게 작동 할 수있는 이유는 학생 이름이나 클래스 이름과 같이 입력 값 중 하나가 올바르지 않으면 오류를 올바르게 처리 할 수 있기 때문입니다. 사용자에게 전체 다중 부분 의도를 다시 말해달라고 요청하는 대신 정보의 단일 부분을 쉽게 요구할 수 있습니다. 또한 알렉사가 필요한 모든 슬롯이 채워질 때까지 계속 질문을하기를 계속할 수 있도록 충분한 지시 사항을 사용하여 한 번에 여러 개의 정보 조각 하나를 가져 오는 것을 처리 할 수 있습니다.
내가 다루지 않은 항목이 하나 있습니다.
학생을 어디에 보관하고 있습니까? 나는 그것들을 람다 함수로 하드 코딩했다. amazon의 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 권한을 만들어야합니다. 그런 다음 마술처럼 Alexa는 각 고유 사용자에 대해 데이터 테이블에 단일 행을 만듭니다. 한 명의 선생님이 학생들을 쉽게 수업에 추가 할 수 있습니다. 그러나 하나의 마스터 데이터베이스에 액세스하기 위해 학교의 각 선생님을 찾고있는 경우 올바른 방법이 아닙니다. Alexa를 여러 사용자가 단일 데이터 테이블에 연결하는 방법에 대한 다른 자습서가있을 수 있습니다.
나는 당신의 질문의 핵심 문제는 당신이 원치 않는 의도를 차단할 수있는 다른 MODES
응답했다 생각합니다. 이 도움을 요청한 경우 트라이던트 레이어 및 평판이 입니다. 감사!
문제가 발생한 정확한 위치를 더 자세히 입력하십시오. 귀하의 질문은 너무 모호합니다. 슬롯을 사용하고 있습니까? –
일반적인 접근 방식을 제안하십시오. 저는이 문제에 익숙하지 않고 몇 일 전부터 다시 시작했습니다. – KMittal