Reputation: 21
Currently I am creating an Alexa skill which handles FAQ questions, and questions which result in a direct reply work fine, however i have questions regarding when alexa expects another reply.
For example, if a user asks,
"What should i eat"
Alexa will reply with "Do you want to eat pasta?"
User will say "yes" or "no"
If the user says anything else other than yes or no, it will reprompt the user to say yes or no.
At the moment i have the following code:
if (intentName == "WhatShouldIEat")
{
EatQuestion = true;
reprompt = "Answer with yes or no";
return MakeSkillResponse(FAQHelper.getQuestionInformation(intentName)); //returns the voice response on alexa
}
//Check if users says yes or no for for eating that food
if (EatQuestion)
{
switch (intentName)
{
case "AMAZON.YesIntent":
intentName = "YesFood"; //sets response to when user says yes
EatQuestion = false;
reprompt = "Ask me another question";
break;
case "AMAZON.NoIntent":
intentName = "NoFood"; //sets response for when user says no
EatQuestion = false;
reprompt = "Ask me another question";
break;
default:
intentName = "YesNoPrompt"; //Alexa will ask the user to say either yes or no
break;
}
}
So the code works, and will loop the reprompt if the user says anything other than yes or no, and gives the correct response i want.
However i was wondering if there was a better way of achieving this, as the functionality is currently in the FunctionHandler and is quite messy with the switch cases, and extending the current code for other questions that require yes,no confirmation would also be quite messy.
Basically i want to know if there is a cleaner way of doing the same functionality in the code above.
Upvotes: 2
Views: 888
Reputation: 4387
AMAZON.YesIntent
or AMAZON.NoIntent
will be triggered whenever the user says ”yes” or "no" and there might be other questions which can have “yes” or "no" as an answer. You can determine or keep a track of what-was-asked-before or the context-of-the-conversation by using sessionAttributes
.
Using sessionAttributes
Imagine your skill with "states"
. Every multiturn conversation has a state, and a state means the context-of-your-conversation or what-you-are-talking-about. So whenever there is a conversation, you set the state/context in the sessionAttributes
so that when the next request comes in you take action based on the state
.
Ex:
User: What should I eat?
[SelectFoodIntent is triggered]
[SelectFoodIntent handler receives this request]
[SelectFoodIntent can set usefull information like]
"sessionAttribute": {
"state":"SELECT_FOOD",
"givenChoice":"pasta"
}
[SelectFoodIntent sends the response back with the sessionAttribute]
Alexa: "Do you want to eat pasta?"
User: no
[AMAZON.NoIntent is triggered]
When the request comes in your backend you will get all the sessionAttributes
you set before and with that, you can determine that the state
is "SELECT_FOOD"
so it's a "NO" for Pasta. Now you can respond back with another food and set the sessionAttributes
accordingly.
"sessionAttribute": {
"state":"SELECT_FOOD",
"givenChoice":"Noodle"
}
Alexa: What about some noodle?
User: Yes
AMAZON.YesIntent
is triggered and with the help of sessionAttributes
you know that its a "Yes" for "Noodle".
The approach is to consider the state
first and inside it have the intents which are necessary. And same intent might be used in different states like the AMAZON.YesIntent
or AMAZON.NoIntent
. So you will have a set of intent handlers under each state which will be triggered only for that particular state.
Remember there can also be the request without state
, so make sure that your code handles it too.
Ex:
+-----------------+------------------+---------------------+
| State | FOOD_SELECT | PLACE_ORDER |
+-----------------+------------------+---------------------+
| Inetnt Handlers | AMAZON.YesIntent | AMAZON.YesIntent |
+ +------------------+---------------------+
| | AMAZON.NoIntent | AMAZON.NoIntent |
+ +------------------+---------------------+
| | | SelectAddressIntent |
+-----------------+------------------+---------------------+
Check out the ask-nodejs-sdk. This will help you to achieve this with much less development effort.
Upvotes: 0
Reputation: 440
You could also use States
for this. Similar to the answer provided by Shailesh Pratapwar, this will store the state in the session data and then respond according to the state the user is currently in. Here is an example for an "Adventure Game" user flow from our Adventure Game Alexa Skill and Google Action Course:
If this is helpful, you can find the full part that introduces the concept of states here: Step 5: Introduction to States.
Upvotes: 1
Reputation: 4224
Use Session attributes properly
You will have separate handler classes for yesintent and nointent.
When your whatShouldIEat handler sends a question back to user expecting an yes - no response, set a session attribute lastHandler = whatShouldIEat.
Now when user responds , the control will come in yeshandler or nohandler. In this, you can check from session attributes what is this yes or no is for and call the specific handler. This way you can use same yeshandler, nohandler for other questions as well.
Now its upto you what you would like to save in session attributes , whether it is a boolean flag, or any variable or any handler object. The objective is to identify last action.
In addition, You can use Stack data structure to keep track of which handler to call in case there are multiple actions to be taken. The top item (the handler) on stack will tell the latest action to be invoked. The next item after that will tell the next action to be invoked.
Upvotes: 1