How to ask for an input after navigating using this.toIntent() and continue executing the same intent after grabbing user input using this.ask()


#1

I am very new to Alexa development and I am using JOVO framework for this purpose. So my apology if this is not the right place to ask this question.

My skeleton of app.js (JOVO) looks like this:

    const ivr_menu: = [
    {
        choice: "contact detail",
        desc: "know more about a given contact."
      },
      {
        choice: "email history",
        desc: "know emailing history of a given contact."
      },
    ]
    app.setHandler({
         LAUNCH(){
              return this.toIntent("WelcomeIntent");
         },

     async WelcomeIntent() {
        let os = "Welcome. Please listen to the IVR menu options carefully.";
        for (var index = 0; index < ivr_menu.length; index++) {
           os += `Say ${ivr_menu[index].choice} to ${ivr_menu[index].desc}.`;
        }
        this.ask(os);
     },

     async UserChoiceIntent() {
        const menu_option = this.$inputs.ivrmenuoption.value;
        switch(menu_option) {
          case "contact detail":
             return this.toIntent("ContactLookupIntent");
          case "email history":
             return this.toIntent("EmailHistoryIntent");
        }
     },

     async ContatLookupIntent() {
        const contact_id = this.$inputs.contactid.value;
        this.tell(contact_id);
     }
});

What I am trying to accomplish is when user tells his choice, it will first greet the user with the IVR menu options. Once user picks up a choice (say by saying contact detail), the skill will enter into UserChoiceIntent and navigates to the correct intent (switch-case).

Each of these intents like ContactLookup or EmailHistory asks an input from the user. In the case of this skill the IDs are always numeric, like 5099563.

In the above approach the issue I am having is when alexa navigates to an intent it does not get the required input (const contact_id = this.$inputs.contactid.value) and hence ending up saying There is an error in your requested skill's response.

Here are my questions:

  1. Is there any option that I navigate to an intent and ask the user for an input? Is there any way that I can use a kind of slot utterance that will be asked by alexa after navigating to the intent and wait for user input (this.ask())? Once the input value is available, alexa will continue to execute rest of the logic inside that intent? The bottom line is alexa does a this.ask() and then continue with the rest of the logic in the intent.

  2. How can I create slot utterances by hand? Please note I am building the skill using JOVO locally and deploying it to alexa.

  3. Since all my intents in this skill take inputs like 5099563, i.e. a numeric value, how can I send that to alexa? I tried with AMAZON.NUMBER, but when I enter a value, I don’t know it comes up with some strange results which is nowhere related to my intent response. It seems like the input is taken and used for some other skill from somewhere! What is the right slot type to use here? I tried AMAZON.LITERAL but it is only available in the US and I am fro India so it won’t work for my skill. The best way I can think to send such value is by saying it like five zero nine nine five six three. AMAZON.NUMBER will not accept this (or may be I am wrong). So what is the best way to handle such a situation?

The interaction model:

​{
    "interactionModel": {
        "languageModel": {
            "invocationName": "metrics report",
            "types": [],
            "intents": [
                {
                    "name": "WelcomeIntent",
                    "samples": [],
                    "slots": []
                },
                {
                    "name": "UserOptionIntent",
                    "samples": [
                        "{ivrmenuoption}"
                    ],
                    "slots": [
                        {
                            "name": "ivrmenuoption",
                            "type": "AMAZON.Person"
                        }
                    ]
                },
                {
                    "name": "ContactLookupIntent",
                    "samples": [
                        "{contactid}",
                    ],
                    "slots": [
                        {
                            "name": "contactid",
                            "type": "AMAZON.NUMBER"
                        }
                    ]
                },
                {
                    "name": "AMAZON.CancelIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.HelpIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.StopIntent",
                    "samples": []
                }
            ]
        }
    }
}​

Please note I am very new to Alexa skill development. If some of my questions look stupid, please consider my newbie level of understanding.


#2

Using two different intents with the same slot makes it almost impossible for Alexa to differentiate.

I recommend using one NumberIntent and then work with states. Learn more about states here:


#3

Thank you @jan. I am going to look into the tutorial now. Meanwhile I have another question. I built a skill previously directly at Alexa console where alexa was asking me question against each slot. Please see the screeshot.

How can I make this possible in JOVO framework?


#4

Hi @jan,
I am trying to implement the state management in my skill under the current scenario.

async ContactDetailIntent() {
     const result = api_result; // gets result from API.
     ....
     // I generate the speech output here.
     const outputSpeech = result.data.description;
     this.$speech.addText = `${result.data.description}.`;
     this.$reprompt.addText('Say yes for groups. No to continue with another contact');

    this.followUpState('SayGroupNameState')
      .ask(this.$speech, this.$reprompt);
},

async ContactGroupsIntent() {
    // takes a contact ID as input and
    // retrieves the groups it belongs to!
}

SayGroupNameState:{
    async YesIntent() {
         return this.toIntent('ContactGroupsIntent');
    },
    async NoIntent() {
         return this.toIntent('ContactDetailIntent');
    }
}

Two things I would like to ask:

  1. When inside ContactDetailIntent, when I say yes, it does not do anything and session gets terminated. Do I need to put one other slot (for yes and no for this intent in interaction model?
    The problem is when I added like phrases:["{contactid, yesno}"] I am getting deployment error.
    Moreover, since most of my intents are dealing with similar kind of inputs (*id), so I have to made some differentiation by adding some specific texts to the utterances like "get me contact detail for {contactid}" rather than just {contactid}. How can I deal with this situation?
    In my another question you said the slots should be written as ["{slot1, slot2}"] and not like ["{slot1}, {slot2}"] (if I am not mistaking.

  2. I hope there is a solution for 1 above which I don’t know yet. But if that gets resolved, another question is I need to pass the same {contactid} in ContactGroupsIntent so that alexa immediately fetches the groups from database and reads them out for the user.

Please let me know how I can accomplish this.