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.
Related
I'm trying to build a custom Alexa skill for a gratitude diary. The goal is to have an interaction in which the Alexa device asks the user what they're grateful for, and repeats it back as confirmation.
I'm encountering a problem when it comes to repeating back what the user has said. I'd like the conversation to go like this:
Alexa: What are you grateful for today?
User I'm grateful for dogs
Alexa: You said you're grateful for dogs. Is that correct?
I've set this up as a single intent, as follows:
gratitude_object as a required slot, of type AMAZON.SearchQuery
user utterances for this slot are I'm grateful for {gratitude_object} (and a few variations)
confirmation message for this slot is You're feeling grateful for {gratitude_object}. Is that correct?
The problem I'm encountering is that when I test this model in the Utterance Profiler, it goes like this:
Alexa: What are you grateful for today?
User I'm grateful for dogs
Alexa: You said you're grateful for I'm grateful for dogs. Is that correct?
I'm guessing this is something to do with the fact that AMAZON.SearchQuery will accept anything as valid input, but I'm not sure how to go about resolving this.
I've also tried creating a custom slot for the I'm grateful for phrase:
slot name: gratitude_phrase_initiator
slot type: custom slot type
slot values: "I'm grateful for", "I am grateful for" (etc)
However, if I then try to use this slot in my intent, by making the user utterance for the gratitude_object slot:
{gratitude_phrase_initiator} {gratitude_object}
...then I get the following error:
Sample utterance "{gratitude_statement_initiator} {gratitude_object}" for slot "gratitude_object" in intent "NewEntryIntent" cannot include both a phrase slot and another intent slot. Error code: InvalidSlotSamplePhraseSlot
.
I'd really like to keep the interaction as it is currently, with the user starting by saying "I'm grateful for...". Any suggestions for how I could make this work using the interaction model, or is it just impossible? Is this something I could handle in the code instead of the interaction model?
Looks like you set it up perfectly but you would expect SearchQuery to do a better job of excluding the initial utterance phrase. So you'll have to parse it some more in code. You should use a Lambda Function to string replace the slot value to remove any initial phrases.
Example in Node.js:
var gratitude_object = this.event.request.intent.slots.gratitude_object.value;
var initial_phrases = [
"i'm grateful for",
"i am grateful for",
];
initial_phrases.forEach(function(value){
gratitude_object = gratitude_object.toLowerCase().replace(value,"");
});
Notice the array of intitial phrases are written in lowercase and the forEach loop also makes the slot value lowercase before checking to replace. That way you don't have to worry about case matching when writing the initial phrases you want to remove.
Recently, I'm building the Alexa skill with the built-in slot confirmation.
I found that when the slot type is AMAZON.DURATION, Alexa will confirm slot content with ISO-8601 duration format instead of verbal format.
For example, when the user says "10 mins", Alexa will reply with " Are you just said PT10M ?" automatically.
The Alexa Speech Prompt that I only set is in the Alexa develop console as
"Are you just said {period}"
Is there any way can fix this or I can just set the question inside the Lambda function.
Thanks a lot.
For each turn in a conversation, your backend will receive a request from Alexa. The speech prompts that you have configured in Alexa console are used when you use Delegate directive of dialog model. ie, when you delegate the next step to Alexa.
When the user says "10 mins", you will receive a request in your backend. You have to validate the {period} slot and if it is valid convert it to "10 mins". You can do this by updating the slot value of {period} slot from "PT10M" to "10 mins" while delegating.
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
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.
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;