2
votes

I have an Alexa skill where a user asks a question and the appropriate response is emitted. Example:

User: What state has the capital Harrisburg? Alexa: Pennsylvania

I was using an ask intent to achieve this (session stays alive), but received a reply when submitting my skill that the session remains open without any user input.

I do not want the session to end. I want the user to be able to continuously ask questions. What is the best way to handle this?

I thought about achieving this by adding a question to the end of every answer. Example:

User: What state has the capital Harrisburg? Alexa: Pennsylvania. Can I help you with anything else?

The problem with the above is I'm not sure how to handle the Yes/No replies.

Any help would be appreciated.

2

2 Answers

2
votes

Your suggested fix is reasonable, and a common pattern in Alexa skills -- Alexa supports built-in intents AMAZON.YesIntent and AMAZON.NoIntent that are already configured to listen for a set of related utterances like "yes", "no", etc. For the yes intent, you would probably want to :ask again with a question like "What question would you like to ask?", and for the no intent you would probably want to :tell the user goodbye, and this usage of tell will end the session.

State Management

That said, you wouldn't want Alexa to always respond to 'Yes' in this way -- what if your skill had other interactions where your response to 'Yes' for this question didn't make sense?

To resolve this, take a look at skill state management in alexa-sdk. From the documentation:

Alexa-sdk use state manager to route the incoming intents to the correct function handler. State is stored as a string in the session attributes indicating the current state of the skill. You can emulate the built-in intent routing by appending the state string to the intent name when defining your intent handlers, but alexa-sdk helps do that for you.

So when your alexa skill answers a question, part of your response logic could set a state like:

this.handler.state = 'AskAnotherQuestion';

And for a state string like AskAnotherQuestion you can use:

1. Literal Intents

Add an entry to your intent handler called AMAZON.YesIntentAskAnotherQuestion to handle the yes response for the YesIntent with the state literally appended.

Example:

'AMAZON.YesIntentAskAnotherQuestion': function() {
    this.emit(':ask', 'What would you like to ask?', 'Could you repeat that?');
},

2. Alexa-SDK State Handler

Use alexa-sdk CreateStateHandler(state, obj) to create an intent handler that appends the passed state to all entries.

Example:

const askQuestionHandlers = Alexa.CreateStateHandler('AskAnotherQuestion', {

    'AMAZON.YesIntent': function() {
        this.emit(':ask', 'What would you like to ask?', 'Could you repeat that?');
    },

    'AMAZON.NoIntent': function() {
        this.emit(':tell', 'See you later!');
    }

    // NOTE: Add another intent here that routes to your question answering logic, 
    // so that the user can just immediately ask their question again without 
    // saying yes or no.
}

See the skill state management documentation for a code-complete example implementation of CreateStateHandler.

Cavaets

Without setting another state in your YesIntent, this skill will be stuck at the 'AskAnotherQuestion' state. That's probably okay for the scope defined in your question, but keep in mind that you may want to switch to other states as your skill gets more complex.

Resetting states to null or empty is currently cumbersome and requires setting multiple fields. Discussion on this and proposed workarounds can be found in this github issue.

Further Reading

0
votes

This thread How to keep an alexa skill open? seems like is on the same topic, and it matches my experience also. The max duration you can keep a session open before Alexa close your skill is ~10 to 20 seconds.