How to get and use confirmation 'yes' or 'no' for Alexa skill intent response
Asked Answered
G

2

8

I am developing a Alexa skill in which on launch it will ask Do you want to perform something ?
Depending upon user's reply 'yes' or 'no' I want to launch another intent.

var handlers = {
  'LaunchRequest': function () {
    let prompt = this.t("ASK_FOR_SOMETHING");
    let reprompt = this.t("LAUNCH_REPROMPT");
    this.response.speak(this.t("WELCOME_MSG") + ' ' + prompt).listen(reprompt);
    this.emit(':responseReady');
  },
  "SomethingIntent": function () {
    //Launch this intent if the user's response is 'yes'
  }
};

I did have a look at dialog model and it seems that it will serve the purpose. But I am not sure how to implement it.

Germanophile answered 31/3, 2018 at 13:21 Comment(1)
i would say use state to handle yes or no during launch set state as start and then add session based handler for yes or no.Brisbane
S
7

The simplest way to do what you're looking for from the skill, is to handle the AMAZON.YesIntent and AMAZON.NoIntent from your skill (make sure to add them to the interaction model as well):

var handlers = {
  'LaunchRequest': function () {
    let prompt = this.t("ASK_FOR_SOMETHING");
    let reprompt = this.t("LAUNCH_REPROMPT");
    this.response.speak(this.t("WELCOME_MSG") + ' ' + prompt).listen(reprompt);
    this.emit(':responseReady');
  },
  "AMAZON.YesIntent": function () { 
    // raise the `SomethingIntent` event, to pass control to the "SomethingIntent" handler below 
    this.emit('SomethingIntent');
  },
  "AMAZON.NoIntent": function () {
    // handle the case when user says No
    this.emit(':responseReady');
  }
  "SomethingIntent": function () {
    // handle the "Something" intent here
  }
};

Note, that in a more complex skill you might have to store some state to figure out that the user sent a 'Yes' intent in response to your question as to whether to "do something". You can save this state using the skill session attributes in the session object. For instance:

var handlers = {
  'LaunchRequest': function () {
    let prompt = this.t("ASK_FOR_SOMETHING");
    let reprompt = this.t("LAUNCH_REPROMPT");
    this.response.speak(this.t("WELCOME_MSG") + ' ' + prompt).listen(reprompt);
    this.attributes.PromptForSomething = true;
    this.emit(':responseReady');
  },
  "AMAZON.YesIntent": function () { 
    if (this.attributes.PromptForSomething === true) {
      // raise the `SomethingIntent` event, to pass control to the "SomethingIntent" handler below 
      this.emit('SomethingIntent');
    } else {
      // user replied Yes in another context.. handle it some other way
      //  .. TODO ..
      this.emit(':responseReady');
    }
  },
  "AMAZON.NoIntent": function () {
    // handle the case when user says No
    this.emit(':responseReady');
  }
  "SomethingIntent": function () {
    // handle the "Something" intent here
    //  .. TODO ..
  }
};

Finally, you could also look into using the Dialog Interface as you alluded to in your question but if all you're trying to do is get a simple Yes/No confirmation as a prompt from the launch request than I think my example above would be pretty straight forward to implement.

Saucedo answered 4/4, 2018 at 2:5 Comment(1)
I tried this approach for my use case but it didn't work exactly the way I needed it to. My 'SomethingIntent' had logic to fill slots associated with the intent, but the request context when inside the 'SomethingIntent' was from the YesIntent user utterance event. So the slots were undefined when trying to access this.event.request.intent.slots inside the 'SomethingIntent' handler. I couldn't even hack around this by defining slots on the YesIntent. I also asked the Amazon Developer team and they said this is just a limitation of how intent forwarding works when done internally.Crocker
P
0

Here is how I have it coded with javascript in the Lambda function for the skill:

    'myIntent': function() {
        
        // there is a required prompt setup in the language interaction model (in the Alexa Skill Kit platform) 
        // To use it we "deligate" it to Alexa via the delegate dialoge directive.
        
        if (this.event.request.dialogState === 'STARTED') {
            // Pre-fill slots: update the intent object with slot values for which
            // you have defaults, then emit :delegate with this updated intent.
            //var updatedIntent = this.event.request.intent;
            //updatedIntent.slots.SlotName.value = 'DefaultValue';
            //this.emit(':delegate', updatedIntent);
            this.emit(':delegate');
        } else if (this.event.request.dialogState !== 'COMPLETED'){
            this.emit(':delegate');
        } else {
            // completed
            var intentObj = this.event.request.intent;
            if (intentObj.confirmationStatus !== 'CONFIRMED') {
                // not confirmed
                if (intentObj.confirmationStatus !== 'DENIED') {
                    // Intent is completed, not confirmed but not denied
                    this.emit(':tell', "You have neither confirmed or denied. Please try again.");
                } else {
                    // Intent is completed, denied and not confirmed
                    this.emit(':ask', 'I am sorry but you cannot continue.');
                }
            } else {
                // intent is completed and confirmed. Success!
                var words = "You have confirmed, thank you!";
                this.response.speak(words);
                this.emit(':responseReady');
            }
        }
        
    },

And you'll need to enable a confirmation for the intent in the Alexa interaction model.

Phraseology answered 18/4, 2022 at 16:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.