Skip to content

Instantly share code, notes, and snippets.

@marcelobern
Created February 24, 2017 07:50
Show Gist options
  • Save marcelobern/7e52b3a742745b59c7fb40456659078c to your computer and use it in GitHub Desktop.
Save marcelobern/7e52b3a742745b59c7fb40456659078c to your computer and use it in GitHub Desktop.
Node.js Alexa skill: alexa-sdk or alexa-app?
// 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);
}
});
// 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);
}
});
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)}});
// 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);
}
},
}
} );
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