Selecting item on list template using voice - alexa

How can I select the item on the list template using voice?
I can now select an item by tapping the screen on echo spot, then created an ElementSelected intent then provide some utterances like {choice}, select {choice}, .... and add the handler for that intent which will log some test string.
After the skill respond with the list, Alexa will no longer listen even though I set the shouldEndSession to true.

shouldEndSession must definitely be set to false if you want Alexa to listen further on.
https://developer.amazon.com/de/docs/custom-skills/request-and-response-json-reference.html#response-object

What I did to select the item on the list are:
add .listen before emitting :responseReady to this.response.listen('your reprompt speech here?.
add my list items to the this.attributes.
add choice slot to the ElementSelected intent.
when the user says select {choice} on the list, Alexa will forward the {choice} slot to ElementSelected handler then I do some further processing about the slot value.

I have returned SpeechletResponse from onIntent like below code.
SpeechletResponse response = new SpeechletResponse();
response.setShouldEndSession(false);
response.setOutputSpeech(outputSpeech);
response.setReprompt(reprompt);
return response;

Related

Alexa Dialog Model Step and dialogState is never in COMPLETED

I'm implementing an Alexa Dialog Model with an PHP Endpoint.
I used the Alexa doc (https://developer.amazon.com/fr/docs/custom-skills/dialog-interface-reference.html)
Here is my example:
My skill:
RequestIntent
Utterance : add an {obj} in the bedroom
Slots : {obj} / Slot Filling
Phrase:
Me : Alexa, Add an object in the bedroom
Alexa : What object do you want to add in bedroom ?
Me : I would like to add a cars in the bedroom
Alexa : You want to add a car in the bedroom ?
Me : Yes
STEP1:
DialogState is STARTED
I use ElicitSlot to set the {obj} slot
STEP2:
dialogState is IN_PROGRESS.
I use ConfirmIntent to ask user to confirm it
STEP3:
User say yes/no
ConfirmIntent is now set to CONFIRMED/DENIED
BUT still in IN_PROGRESS
dialogState should be COMPLETED because i set all of my slot and intent value right ? So why should not be working in here ?
Thanks by advance
The reason your dialogState is not COMPLETE because you are using Dialog.ElicitSlot directive. The COMPLETED status is only possible when you use Dialog.Delegate directive.
More information on controlling the dialog with Dialog.Delegate directive here
DialogState has only the following status:
"STARTED" , "IN_PROGRESS" , "COMPLETED.
The reason why is not completed could be because not all the steps are complete or the IntentRequest has not all the required slot values.
For me, I must enable the Auto Delegation option in Interfaces from Alexa Developer Console.
Let Alexa automatically determine and complete each step of the dialog, based on your dialog model. Your skill gets a single IntentRequest when the dialog is complete. You can override this setting at the intent level. Learn More about Auto Delegation.
Once all the steps are complete, the skill receives the final IntentRequest with dialogState set to COMPLETED.

Ask user for input from LaunchIntent

I'm writing a skill in Node JS 8. I have an intent set up with slots and it works properly if I say
Ask {skill name} to {utterance}.
I'd like to design my skill so that the user can just say
Open {skill Name}
and on opening it will ask them for input that will then be handled and passed to the intent. I've seen multiple people say that you can't do this. But I've used 2 skills today that did exactly this. I'm just looking for the correct syntax to do this.
I have:
'LaunchRequest': function() {
this.response.speak("What note would you like?");
this.emit(':responseReady');
}
Which seems like it should work, but I'm pretty new to JS and Alexa.
Yes, it is possible.
When the skill user open your skill, you can give a welcome message followed by a question.
Ex:
[user] : open note skill
[Alexa] : Welcome to note skill. What note would you like?
----------<Alexa will wait for users input>--------
[user] : ABC note.
[Alexa] : <response>
In order for Alexa to wait for users input after it says the welcome message, you need to keep the session alive. The session is kept alive based on shouldEndSession parameter in the response. For any request, if not provided, shouldEndSession defaults to true. In your case, the response to LaunchRequest should have this shouldEndSession parameter set to false. Only by which the session remains open and users can continue interaction.
Ex:
'LaunchRequest': function() {
const speech = "Welcome to note skill. What note would you like?";
const reprompt = "What note would you like?";
this.emit(':ask', speech, reprompt);
}
Read this answer to know more about how you can keep the session alive using ask-nodejs-sdk.
Using Dialog Model
Another way to achieve this is to use Dialog directives. Dialog directives helps you to fill and validate slot values easily. You can use the directives to ask the user for the information you need to fulfill their request.
More information on Dialog directives here

List in custom Alexa skills

I'm new to Alexa Skills but meanwhile I've read tons of information and tutorials.
Fortunately, I'm currently able to create my own custom skill (based on PHP) on my own server and it already works using different intents, utterances, slots etc..
Now, I want Alexa to read a list of items (I send via JSON) in PlainText but I can't find any information how to do this.
I assume there are two options (please correct me if I'm wrong):
Sending a JSON answer including one item - Alexa reads this item - the user says e.g. "next" - Alexa requests my server for the next item - my server sends the next JSON answer ... and so on.
Sending a JSON answer including all items in an array - Alexa reads each item one after another.
I'm not sure which solution is possible and how it can be solved.
So, can anyone help me on this or point me to some information?
Both ways are possible and which one to choose depends on what you are listing.
Using AMAZON.NextIntent
If a single list item include item name and some details about it, then reading out it in one go won't be a good user experience. In this case you can use AMAZON.NextIntent to handle users "next" request.
When the user asks for the list, give the first item in your response and keep a track of the item index in response sessionAttributes. You can also set a STATE attribute too, so that you can check this state in AMAZON.NextIntent handler before you give the next item.
"sessionAttributes": {
"index": 1,
"STATE": "LIST_ITEMS"
}
When the user say "next"
check whether the state is LIST_ITEMS and based on the index give the next item from your list. And in sessionAttributes increment the index
More on sessionAttributes and Response Parameters here
Now, if your items are just names then you can read it one after the other.
In both these solutions it is always good to use SSML rather than just PlainText. SSML gives you more control on how your response is spoken.
More on SSML here

Using sessionAttributes in Alexa Skill

I am building an Alexa skill and not quite sure if I am using sessionAtrributes correctly. I know sessionAttributes are used to carry-forward a session's data to next invocation.
So I have these two intents
1) ListToDoItem
In this intent my skill will look into a database and list out the
to-do items stored in the database. After listing the items, Alexa
will go on to say "do you want me to list detailed info on these
to-do items?", to handle this I will pass the items retrieved in the
previous session as sessionAttributes. When asked to list detailed
info on the items, I will extract the previously forwarded
sessionAtrributes and compose a detailed speech response.
So for this intent I have to sample utterances
list my to-do items
yes
The utterance 'yes' will be used so that the sessionAttributes can be extracted to create a detailed speech response.
2) ListDoneItems
This intent will be used to list out completed items. It is similar to the previous intent, the only difference being, this intent will list out completed items.
For this intent will have 2 sample utterances
list my completed items
yes
Like before it has an 'yes' to generate a detailed speech response based on the sessionAttributes.
But the problem I have is that when I reply 'yes' to the ListDoneItems intent's 'Do you want me to list the completed items'?, the next intent request generated is of type ListToDoItems instead of ListDoneItems, even though I have set shouldEndSession to false in my skill response. This is happening because there is a crossover between sample utterances between my intents. So is having similar intents in different intents wrong? How to design interaction model to create a multi-turn dialog in order to use in sessionAttributes?
I think this will be of use to someone searching for answer.
Basically in the sample utterance you should not include phrases for your re-prompts; i.e. in my case I should not add 'yes' as an utterance. Instead I should be using Amazon.YesIntent.
When using Amazon.YesIntent, you should maintain a state machine in your SessionAttributes pointing to the last invoked intent. For example if two or more of your intents have a possible case where the user response could invoke a YesIntent, you should store the last invoked intent name and the associated session data in the SessionAttributes. So in the function which handles the YesIntent, you should check the state of your previous invocations and delegate to control to the corresponding intent handler.
In my case I will store previously invoked intent name as key and its associated data as it's value in the session.attributes;
"session": {
"new":"false",
"sessionId": "sessionId",
"application": {
"applicationId": "applicationId"
},
"attributes": {
"PreviousIntent": {
"PreviousIntentData"
}
}
In the function which handles YesIntent, check the for the previous state (session.attributes.PreviousIntent) and delegate the control to the function which handles that intent.

Conditionally return from digression in watson assistant

I have been reading through the documentation and cannot find the answer to this question for Watson Assistant.
I have a digression that I only sometimes want to return back to the previous place in the dialog.
Specifically, after the user enters the digression, if the user responds "Yes" then I do not want the digression to return back, but if the user responds "No" then I do want the digression to return to the previous place.
Is there a way to do this? Perhaps by manually editing the JSON to somehow override the directive to return from the digression in some cases?
Below is a diagram of the issue:
Dialog Flow
There is a function <? clearDialogStack() ?> that when called it will erase all the digressions that are set in dialog and hence the dialog will not return from digression. So just call this function in a node where you don't want WA to return.
Here it is in the doc: https://cloud.ibm.com/docs/services/assistant?topic=assistant-dialog-runtime#dialog-runtime-digressions
If I understand you correctly, you could create two different nodes for handling the user response of "yes" or "no" based on the way digressions are setup today. If yes, the node needs to be configured to not return back (don't click the checkbox). If no, click the checkbox.

Resources