Created
February 24, 2017 07:50
-
-
Save marcelobern/7e52b3a742745b59c7fb40456659078c to your computer and use it in GitHub Desktop.
Node.js Alexa skill: alexa-sdk or alexa-app?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Original code snippet from https://github.com/alexa/skill-sample-nodejs-decision-tree/blob/master/src/index.js | |
// set state to start up and welcome the user | |
var newSessionHandler = { | |
'LaunchRequest': function () { | |
this.handler.state = states.STARTMODE; | |
this.emit(':ask', welcomeMessage, repeatWelcomeMessage); | |
},'AMAZON.HelpIntent': function () { | |
this.handler.state = states.STARTMODE; | |
this.emit(':ask', helpMessage, helpMessage); | |
}, | |
'Unhandled': function () { | |
this.handler.state = states.STARTMODE; | |
this.emit(':ask', promptToStartMessage, promptToStartMessage); | |
} | |
}; | |
// --------------- Functions that control the skill's behavior ----------------------- | |
// Called at the start of the game, picks and asks first question for the user | |
var startGameHandlers = Alexa.CreateStateHandler(states.STARTMODE, { | |
'AMAZON.YesIntent': function () { | |
// --------------------------------------------------------------- | |
// check to see if there are any loops in the node tree - this section can be removed in production code | |
visited = [nodes.length]; | |
var loopFound = helper.debugFunction_walkNode(START_NODE); | |
if( loopFound === true) | |
{ | |
// comment out this line if you know that there are no loops in your decision tree | |
this.emit(':tell', loopsDetectedMessage); | |
} | |
// --------------------------------------------------------------- | |
// set state to asking questions | |
this.handler.state = states.ASKMODE; | |
// ask first question, the response will be handled in the askQuestionHandler | |
var message = helper.getSpeechForNode(START_NODE); | |
// record the node we are on | |
this.attributes.currentNode = START_NODE; | |
// ask the first question | |
this.emit(':ask', message, message); | |
}, | |
'AMAZON.NoIntent': function () { | |
// Handle No intent. | |
this.emit(':tell', goodbyeMessage); | |
}, | |
'AMAZON.StopIntent': function () { | |
this.emit(':tell', goodbyeMessage); | |
}, | |
'AMAZON.CancelIntent': function () { | |
this.emit(':tell', goodbyeMessage); | |
}, | |
'AMAZON.StartOverIntent': function () { | |
this.emit(':ask', promptToStartMessage, promptToStartMessage); | |
}, | |
'AMAZON.HelpIntent': function () { | |
this.emit(':ask', helpMessage, helpMessage); | |
}, | |
'Unhandled': function () { | |
this.emit(':ask', promptToStartMessage, promptToStartMessage); | |
} | |
}); | |
// user will have been asked a question when this intent is called. We want to look at their yes/no | |
// response and then ask another question. If we have asked more than the requested number of questions Alexa will | |
// make a choice, inform the user and then ask if they want to play again | |
var askQuestionHandlers = Alexa.CreateStateHandler(states.ASKMODE, { | |
'AMAZON.YesIntent': function () { | |
// Handle Yes intent. | |
helper.yesOrNo(this,'yes'); | |
}, | |
'AMAZON.NoIntent': function () { | |
// Handle No intent. | |
helper.yesOrNo(this, 'no'); | |
}, | |
'AMAZON.HelpIntent': function () { | |
this.emit(':ask', promptToSayYesNo, promptToSayYesNo); | |
}, | |
'AMAZON.StopIntent': function () { | |
this.emit(':tell', goodbyeMessage); | |
}, | |
'AMAZON.CancelIntent': function () { | |
this.emit(':tell', goodbyeMessage); | |
}, | |
'AMAZON.StartOverIntent': function () { | |
// reset the game state to start mode | |
this.handler.state = states.STARTMODE; | |
this.emit(':ask', welcomeMessage, repeatWelcomeMessage); | |
}, | |
'Unhandled': function () { | |
this.emit(':ask', promptToSayYesNo, promptToSayYesNo); | |
} | |
}); | |
// user has heard the final choice and has been asked if they want to hear the description or to play again | |
var descriptionHandlers = Alexa.CreateStateHandler(states.DESCRIPTIONMODE, { | |
'AMAZON.YesIntent': function () { | |
// Handle Yes intent. | |
// reset the game state to start mode | |
this.handler.state = states.STARTMODE; | |
this.emit(':ask', welcomeMessage, repeatWelcomeMessage); | |
}, | |
'AMAZON.NoIntent': function () { | |
// Handle No intent. | |
this.emit(':tell', goodbyeMessage); | |
}, | |
'AMAZON.HelpIntent': function () { | |
this.emit(':ask', promptToSayYesNo, promptToSayYesNo); | |
}, | |
'AMAZON.StopIntent': function () { | |
this.emit(':tell', goodbyeMessage); | |
}, | |
'AMAZON.CancelIntent': function () { | |
this.emit(':tell', goodbyeMessage); | |
}, | |
'AMAZON.StartOverIntent': function () { | |
// reset the game state to start mode | |
this.handler.state = states.STARTMODE; | |
this.emit(':ask', welcomeMessage, repeatWelcomeMessage); | |
}, | |
'DescriptionIntent': function () { | |
//var reply = this.event.request.intent.slots.Description.value; | |
//console.log('HEARD: ' + reply); | |
helper.giveDescription(this); | |
}, | |
'Unhandled': function () { | |
this.emit(':ask', promptToSayYesNo, promptToSayYesNo); | |
} | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Refactored code snippet from alexa-sdk-fsm-original.js | |
function welcome() { | |
this.handler.state = states.STARTMODE; | |
this.emit(':ask', welcomeMessage, repeatWelcomeMessage); | |
} | |
function help() { | |
this.handler.state = states.STARTMODE; | |
this.emit(':ask', helpMessage, helpMessage); | |
} | |
function startOver() { | |
this.handler.state = states.STARTMODE; | |
this.emit(':ask', promptToStartMessage, promptToStartMessage); | |
} | |
function goodbye() { | |
this.emit(':tell', goodbyeMessage); | |
} | |
// set state to start up and welcome the user | |
var newSessionHandler = { | |
'LaunchRequest': welcome, | |
'AMAZON.HelpIntent': help, | |
'Unhandled': startOver | |
}; | |
// --------------- Functions that control the skill's behavior ----------------------- | |
// Called at the start of the game, picks and asks first question for the user | |
var startGameHandlers = Alexa.CreateStateHandler(states.STARTMODE, { | |
'AMAZON.YesIntent': function () { | |
// --------------------------------------------------------------- | |
// check to see if there are any loops in the node tree - this section can be removed in production code | |
visited = [nodes.length]; | |
var loopFound = helper.debugFunction_walkNode(START_NODE); | |
if( loopFound === true) | |
{ | |
// comment out this line if you know that there are no loops in your decision tree | |
this.emit(':tell', loopsDetectedMessage); | |
} | |
// --------------------------------------------------------------- | |
// set state to asking questions | |
this.handler.state = states.ASKMODE; | |
// ask first question, the response will be handled in the askQuestionHandler | |
var message = helper.getSpeechForNode(START_NODE); | |
// record the node we are on | |
this.attributes.currentNode = START_NODE; | |
// ask the first question | |
this.emit(':ask', message, message); | |
}, | |
'AMAZON.NoIntent': goodbye, | |
'AMAZON.StopIntent': goodbye, | |
'AMAZON.CancelIntent': goodbye, | |
'AMAZON.HelpIntent': help, | |
'Unhandled': startOver | |
}); | |
// user will have been asked a question when this intent is called. We want to look at their yes/no | |
// response and then ask another question. If we have asked more than the requested number of questions Alexa will | |
// make a choice, inform the user and then ask if they want to play again | |
var askQuestionHandlers = Alexa.CreateStateHandler(states.ASKMODE, { | |
'AMAZON.YesIntent': function () { | |
// Handle Yes intent. | |
helper.yesOrNo(this,'yes'); | |
}, | |
'AMAZON.NoIntent': function () { | |
// Handle No intent. | |
helper.yesOrNo(this, 'no'); | |
}, | |
'AMAZON.StopIntent': goodbye, | |
'AMAZON.CancelIntent': goodbye, | |
'AMAZON.StartOverIntent': welcome, | |
'Unhandled': function () { | |
this.emit(':ask', promptToSayYesNo, promptToSayYesNo); | |
} | |
}); | |
// user has heard the final choice and has been asked if they want to hear the description or to play again | |
var descriptionHandlers = Alexa.CreateStateHandler(states.DESCRIPTIONMODE, { | |
'AMAZON.YesIntent': welcome, | |
'AMAZON.NoIntent': goodbye, | |
'AMAZON.StopIntent': goodbye, | |
'AMAZON.CancelIntent': goodbye, | |
'AMAZON.StartOverIntent': welcome, | |
'DescriptionIntent': function () { | |
//var reply = this.event.request.intent.slots.Description.value; | |
//console.log('HEARD: ' + reply); | |
helper.giveDescription(this); | |
}, | |
'Unhandled': function () { | |
this.emit(':ask', promptToSayYesNo, promptToSayYesNo); | |
} | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function welcome(){this.handler.state=states.STARTMODE,this.emit(":ask",welcomeMessage,repeatWelcomeMessage)}function help(){this.handler.state=states.STARTMODE,this.emit(":ask",helpMessage,helpMessage)}function startOver(){this.handler.state=states.STARTMODE,this.emit(":ask",promptToStartMessage,promptToStartMessage)}function goodbye(){this.emit(":tell",goodbyeMessage)}var newSessionHandler={LaunchRequest:welcome,"AMAZON.HelpIntent":help,Unhandled:startOver},startGameHandlers=Alexa.CreateStateHandler(states.STARTMODE,{"AMAZON.YesIntent":function(){visited=[nodes.length];var a=helper.debugFunction_walkNode(START_NODE);a===!0&&this.emit(":tell",loopsDetectedMessage),this.handler.state=states.ASKMODE;var b=helper.getSpeechForNode(START_NODE);this.attributes.currentNode=START_NODE,this.emit(":ask",b,b)},"AMAZON.NoIntent":goodbye,"AMAZON.StopIntent":goodbye,"AMAZON.CancelIntent":goodbye,"AMAZON.HelpIntent":help,Unhandled:startOver}),askQuestionHandlers=Alexa.CreateStateHandler(states.ASKMODE,{"AMAZON.YesIntent":function(){helper.yesOrNo(this,"yes")},"AMAZON.NoIntent":function(){helper.yesOrNo(this,"no")},"AMAZON.StopIntent":goodbye,"AMAZON.CancelIntent":goodbye,"AMAZON.StartOverIntent":welcome,Unhandled:function(){this.emit(":ask",promptToSayYesNo,promptToSayYesNo)}}),descriptionHandlers=Alexa.CreateStateHandler(states.DESCRIPTIONMODE,{"AMAZON.YesIntent":welcome,"AMAZON.NoIntent":goodbye,"AMAZON.StopIntent":goodbye,"AMAZON.CancelIntent":goodbye,"AMAZON.StartOverIntent":welcome,DescriptionIntent:function(){helper.giveDescription(this)},Unhandled:function(){this.emit(":ask",promptToSayYesNo,promptToSayYesNo)}}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Converted refactored code snippet from alexa-sdk-fsm-refactored.js into machina style FSM notation | |
const machina = require('machina'); | |
var myMachina = machina.Fsm.extend( { | |
initialState: "uninitialized", | |
states: { | |
uninitialized: { // set state to start up and welcome the user | |
// State used to mimic alexa-sdk newSession handler for alexa-app (which lacks newSession handlers) | |
launch: "WELCOME", | |
AMAZON_HelpIntent: "HELP", | |
"*": "STARTOVER" | |
}, | |
WELCOME: { // User invoked the skill or game restarted | |
_onEnter: function () { | |
// reset the game state to start mode | |
this.handler.state = states.STARTMODE; | |
this.emit(':ask', welcomeMessage, repeatWelcomeMessage); | |
} | |
}, | |
HELP: { // User is prompted to say yes or no | |
_onEnter: function () { | |
this.handler.state = states.STARTMODE; | |
this.emit(':ask', helpMessage, helpMessage); | |
} | |
}, | |
STARTOVER: { // User is prompted to say yes or no | |
_onEnter: function () { | |
this.handler.state = states.STARTMODE; | |
this.emit(':ask', promptToStartMessage, promptToStartMessage); | |
} | |
}, | |
// --------------- Functions that control the skill's behavior ----------------------- | |
STARTMODE: { // Called at the start of the game, picks and asks first question for the user | |
AMAZON_YesIntent: function () { | |
// --------------------------------------------------------------- | |
// check to see if there are any loops in the node tree - this section can be removed in production code | |
visited = [nodes.length]; | |
var loopFound = helper.debugFunction_walkNode(START_NODE); | |
if( loopFound === true) | |
{ | |
// comment out this line if you know that there are no loops in your decision tree | |
this.emit(':tell', loopsDetectedMessage); | |
} | |
// --------------------------------------------------------------- | |
// set state to asking questions | |
this.handler.state = states.ASKMODE; | |
// ask first question, the response will be handled in the askQuestionHandler | |
var message = helper.getSpeechForNode(START_NODE); | |
// record the node we are on | |
this.attributes.currentNode = START_NODE; | |
// ask the first question | |
this.emit(':ask', message, message); | |
}, | |
AMAZON_NoIntent: "GOODBYE", | |
AMAZON_StopIntent: "GOODBYE", | |
AMAZON_CancelIntent: "GOODBYE", | |
AMAZON_HelpIntent: "HELP", | |
"*": "STARTOVER" | |
}, | |
// user will have been asked a question when this intent is called. We want to look at their yes/no | |
// response and then ask another question. If we have asked more than the requested number of questions Alexa will | |
// make a choice, inform the user and then ask if they want to play again | |
ASKMODE: { // Alexa is asking user the questions. | |
AMAZON_YesIntent: function () { | |
// Handle Yes intent. | |
helper.yesOrNo(this,'yes'); | |
}, | |
AMAZON_NoIntent: function () { | |
// Handle No intent. | |
helper.yesOrNo(this, 'no'); | |
}, | |
AMAZON_StopIntent: "GOODBYE", | |
AMAZON_CancelIntent: "GOODBYE", | |
AMAZON_StartOverIntent: "WELCOME", | |
"*": function () { | |
this.emit(':ask', promptToSayYesNo, promptToSayYesNo); | |
} | |
}, | |
// user has heard the final choice and has been asked if they want to hear the description or to play again | |
DESCRIPTIONMODE: { // Alexa is describing the final choice and prompting to start again or quit | |
AMAZON_YesIntent: "WELCOME", | |
AMAZON_NoIntent: "GOODBYE", | |
AMAZON_StopIntent: "GOODBYE", | |
AMAZON_CancelIntent: "GOODBYE", | |
AMAZON_StartOverIntent: "WELCOME", | |
DescriptionIntent: function () { | |
//var reply = this.event.request.intent.slots.Description.value; | |
//console.log('HEARD: ' + reply); | |
helper.giveDescription(this); | |
}, | |
"*": function () { | |
this.emit(':ask', promptToSayYesNo, promptToSayYesNo); | |
} | |
}, | |
GOODBYE: { // User decided to quick the game | |
_onEnter: function () { | |
this.emit(':tell', goodbyeMessage); | |
} | |
}, | |
} | |
} ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const machina=require("machina");var myMachina=machina.Fsm.extend({initialState:"uninitialized",states:{uninitialized:{launch:"WELCOME",AMAZON_HelpIntent:"HELP","*":"STARTOVER"},WELCOME:{_onEnter:function(){this.handler.state=states.STARTMODE,this.emit(":ask",welcomeMessage,repeatWelcomeMessage)}},HELP:{_onEnter:function(){this.handler.state=states.STARTMODE,this.emit(":ask",helpMessage,helpMessage)}},STARTOVER:{_onEnter:function(){this.handler.state=states.STARTMODE,this.emit(":ask",promptToStartMessage,promptToStartMessage)}},STARTMODE:{AMAZON_YesIntent:function(){visited=[nodes.length];var a=helper.debugFunction_walkNode(START_NODE);a===!0&&this.emit(":tell",loopsDetectedMessage),this.handler.state=states.ASKMODE;var b=helper.getSpeechForNode(START_NODE);this.attributes.currentNode=START_NODE,this.emit(":ask",b,b)},AMAZON_NoIntent:"GOODBYE",AMAZON_StopIntent:"GOODBYE",AMAZON_CancelIntent:"GOODBYE",AMAZON_HelpIntent:"HELP","*":"STARTOVER"},ASKMODE:{AMAZON_YesIntent:function(){helper.yesOrNo(this,"yes")},AMAZON_NoIntent:function(){helper.yesOrNo(this,"no")},AMAZON_StopIntent:"GOODBYE",AMAZON_CancelIntent:"GOODBYE",AMAZON_StartOverIntent:"WELCOME","*":function(){this.emit(":ask",promptToSayYesNo,promptToSayYesNo)}},DESCRIPTIONMODE:{AMAZON_YesIntent:"WELCOME",AMAZON_NoIntent:"GOODBYE",AMAZON_StopIntent:"GOODBYE",AMAZON_CancelIntent:"GOODBYE",AMAZON_StartOverIntent:"WELCOME",DescriptionIntent:function(){helper.giveDescription(this)},"*":function(){this.emit(":ask",promptToSayYesNo,promptToSayYesNo)}},GOODBYE:{_onEnter:function(){this.emit(":tell",goodbyeMessage)}}}}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment