question

Colin W Wightman avatar image
Colin W Wightman asked

How to make callbacks persistant

Okay, this is simple...but its kicking my butt :( I want to ask the user a yes/no question and respond appropriately. I tried to create a callback to take care of things once we know what the response is and saving it in the session object so the Yes and No intent handlers can call it: session.yesNoCallback = function callback(yea,newSession,newResponse) { if( yea ){ console.log('resuming the previous game'); doSomethingGood(newSession, newResponse); } else { console.log('starting the new game'); doBadThings(newSession, newResponse); } }; response.ask(speechOutput, reprompt); and then calling that in the intent handler: intentHandlers['AMAZON.NoIntent'] = function (intent, session, response) { if( session.yesNoCallback !== null ) { callback = session.yesNoCallback; session.yesNoCallback = null; callback( false, session, response ); } else { response.ask("I wasn't expecting a yes or no response. " + session.attributes.lastPrompt); } }; Of course that fails because because the session object doesn't like things other than strings...so what do I do? Stingify the function? or am I completely missing the point?
alexa skills kitdebugging
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

jjaquinta avatar image
jjaquinta answered
I think you're missing the point. Session attributes, as you note, can only contain strings. Callbacks are code. Although it might be possible to mix them, that's not really using things they way they are meant. Alexa skills are simple, atomic, call and return functions. There is no state, other than what you maintain in your session object. Consequently each call into your skill needs to be treated exactly the same. If you want it to take different logic routes, you need that business logic to be in your skill. Pretty much, the classical implementation of doing this is a finite state machine. You can look the definition up in Wikipedia, or fine some on-line first year computing science course. They're pretty pervasive in the industry. You probably have your code structured to handle a 'stateless' skill. I.e. when called, you look at the intent, and branch based on which intent was invoked. You need to extend this to two levels. In a nutshell, you basically set a session variable that represents the "state" of your machine. The first thing you do when your function is invoked is access that variable, then branch to the appropriate business logic to action it. Essentially you have a separate set of business logic that branches based on the intent for each state. For example, I'm working on a "blackjack" skill. It has four states: BASE, INGAME, QUERY_CONTINUE, and QUERY_QUIT. When you are in a BASE state, you haven't started a game. It responds to the "new game" intents, and things like "score", it gives errors for the other intents. When you are in a INGAME state, it responds to "hit", "hold", etc, and gives errors for other intents. QUERY_CONTINUE is entered if you restart the skill with the game in progress. It only responds to "yes" or "no", and errors on the rest. "help" works for them all, but says something different depending on the state.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Galactoise avatar image
Galactoise answered
One slight correction - Session attributes can only contain strings for the [b]key[/b], but the map accepts a [b]value[/b] of any JSON type (String, integer, boolean, array, JSON Object). This doesn't help with passing a callback, but it may be useful when deciding how to store the state itself in the session attributes.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Ross@Amazon avatar image
Ross@Amazon answered
It is recommended that you re-architects your code a bit since session attributes cannot have callbacks in them. Instead it is possible to use the built in yes and no slot types, and map them to an intent. Then when the yes or no intent is triggered they can be handled accordingly.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.