Manage Skill Sessions and Session Attributes
Your skill can keep the skill session open to conduct a back-and-forth interaction with the user. While the session is open, the user doesn't need to use your invocation name to talk to your skill. To save data during the session, you can use session attributes.
Lifecycle of a skill session
The following steps show the lifecycle of a skill session.
-
A skill session begins when a user invokes your skill and Alexa sends your skill a request. The request contains a
Session
object with a Boolean property callednew
to indicate that this request is for a new session. -
Your skill receives the request and returns a response for Alexa to speak to the user.
-
What happens next depends on the value of the
shouldEndSession
parameter in your skill response:-
true
– After Alexa speaks theoutputSpeech
content, the session ends. Alexa, not the skill, handles any further speech from the user. If the user re-invokes the skill, Alexa creates a new session. Refer back to step 1.Note: You must close the session unless you send a prompt in theoutputSpeech
parameter. The prompt might be in the form of a question or instructions on what to say next. -
false
ornull
– After Alexa speaks theoutputSpeech
content, the session stays open, and Alexa opens the microphone to indicate that the skill expects the user to respond. If the user's response maps to your interaction model, Alexa sends a new intent to the skill and the process goes back to step 2.Tip: When your skill gives instructions on what to say next and leaves the session open, use utterances that are part of your interaction model, but don't use one-shot examples.
DO: Skill: There is water on Mars. Say, next fact, to hear something new. (The session remains open.)
DON'T': Skill: There is water on Mars. Say, Alexa, ask Quick Trivia for the next fact, to hear something new. (The session remains open.)However, if a few seconds elapse without a response from the user, Alexa closes the microphone. If the skill specified a reprompt, Alexa reprompts the user to speak and opens the microphone for a few more seconds. If the user still doesn't respond, the session ends. For more details, see Support session ended.
Tip: Include a specific reprompt that lets the user know what to say next.The session might remain open for a short time with the microphone closed if the user uses the skill on an Alexa-enabled device with a screen. For more details, see How devices with screens affect the skill session.
-
undefined
(not set) – The session behavior depends on the type of Echo device.
If the device has a screen and the skill response includes screen content, the session stays open for up to 30 more seconds, without opening the microphone to prompt the user for input. For more details, see How devices with screens affect the skill session. If the user speaks and precedes their request with the wake word (such as "Alexa,") Alexa sends the request to the skill. Otherwise, Alexa ignores the user's speech. If an Alexa Gadgets event handler is active, the session continues to stay open until the skill callsCustomInterfaceController.StopEventHandler
or the event handler expires.
-
One exception overrides the shouldEndSession
value. When you use skill connections to request a task from Amazon or another provider skill, you hand over control to the requested task and the session ends. Depending on the task, Alexa can hand control back to your skill. For example, the directives to start the purchase flow task for in-skill purchasing and paid skills automatically end the session, regardless of the shouldEndSession
value. After the purchase flow completes, you use saved session attributes to resume the skill. For details, see Skill Connections.
Example session interactions
The following example shows a skill session where the skill responds to the user, and then closes the session. The skill doesn't prompt the user for input.
User: Alexa, open Quick Trivia and tell me the trivia of the day.
Quick Trivia: On 21 July 1969, American astronaut Neil Armstrong became the first person to walk on the Moon.
The skill closes the session with shouldEndSession=true
.
The following example shows a skill session where the skill responds to the user, and then keeps the session open. The skill prompts the user for input.
User: Alexa, play Quick Trivia.
Quick Trivia: Who was the first astronaut to walk on the Moon?
The skill keeps the session open with shouldEndSession=false
.
User: Neil Armstrong!
Quick Trivia: That's right! Do you want another question?
The skill keeps the session open with shouldEndSession=false
.
User: No.
Quick Trivia: OK. Come back soon!
The skill closes the session with shouldEndSession=true
.
How devices with screens affect the skill session
When the user invokes a skill on an Alexa-enabled device with a screen, the session can remain open for up to 30 additional seconds with the microphone closed. The user continues to see content related to the skill on the screen. To continue interacting with the skill, the user can use the wake word to speak to Alexa, followed by an utterance that maps to the interaction model for the skill.
This extended session occurs when all the following conditions are true:
- The user invokes the skill with a device with a screen (such as an Echo Show).
- The skill configuration supports devices with screens. This means that one of these options on the Build > Interfaces page in the developer console is enabled:
- Alexa Presentation Language
- Display Interface (deprecated)
- The skill response includes content to display on the screen. The visual content can be one of the following items:
- An Alexa Presentation Language (APL) document, displayed when you return the
Alexa.Presentation.APL.RenderDocument
directive. - An Alexa app card, displayed when you include a
card
object. Although cards are intended for the Alexa app, screen devices display card content when you don't provide any other screen content.
- An Alexa Presentation Language (APL) document, displayed when you return the
- The
shouldEndSession
value in the response is eitherfalse
orundefined
(not set).- When
undefined
, the extended session remains open for approximately 30 seconds. - When
false
, the extended session occurs after the user fails to respond to the reprompt. Here, the session remains open for between 20 and 30 seconds.
- When
For example, a skill configured to support screen devices and display content on the screen might have the following interaction on a device with a screen.
User: Alexa, open Quick Trivia.
The skill gets a LaunchRequest
, and then responds with a prompt and shouldEndSession = false
.
Quick Trivia: Welcome to Quick Trivia. I know facts about space, how long it takes to travel between two planets and I even know a joke. What do you want to know?
Alexa speaks the prompt.
The screen displays content related to Quick Trivia, such as an APL document sent by means of the RenderDocument
directive.
User: ….
User says nothing. A few seconds elapse.
Quick Trivia: Try asking me to tell you something about space.
Alexa speaks the reprompt
provided with the response.
User: Um….
More time passes.
Microphone closes, but the session remains open. Content about Quick Trivia continues to display onscreen.
User: Alexa, tell me about Mars.
User interacts with the skill without using the invocation name, since the skill session is still active.
Alexa sends the skill a PlanetFacts
intent. The request shows that this is a continuing session, not a new session.
Quick Trivia: On Mars….
Save data during the session
To retain data during the session, use session attributes. Create a map of key-value pairs with the data you need to save. Include this map in the sessionAttributes
property of your response. When Alexa sends the next request as part of the same session, the request includes the same map in the session.attributes
property. Use the keys that you defined to retrieve the data from the map.
The following example shows an example skill session where the skill saves an attribute in the response and retrieves it in the request.
…earlier utterances to start this interaction.
User: My favorite color is blue
Alexa sends the skill the FavoriteColorIntent
with the favoriteColor
slot set to "blue". The skill responds with text to speak and a session attribute with the key favoriteColor
and the value "blue".
Skill: I now know your favorite color is blue. What do you want to know?
User: What was that color again?
Alexa sends the skill the WhatsMyColorIntent
intent. The request includes the favoriteColor
session attribute. The skill retrieves this attribute to build the response.
Skill: Your favorite color is blue.
Session attributes are useful for several situations:
- Keep track of state data to handle different skill states, such as a
state
attribute to indicate whether the user is already in a game or ready to start a new game. Use the attribute as criteria in the code that determines whether a handler can handle a particular request. This can be especially useful if your skill asks the user multiple yes/no questions, since the response "yes" or "no" may have a different meaning depending on skill state. - Keep track of game scores and counters.
- Save slot values that the user has provided as you continue to prompt for additional values. Note that as an alternative, you can use a dialog model and delegate the dialog to accomplish this without session attributes. See Delegate the Dialog to Alexa.
Store session attributes
The Alexa Skills Kit SDKs provide an AttributesManager
to add session attributes to your response, and then retrieve the attributes from an incoming request.
The following example shows how an intent handler can save data into the session attributes. In this example, the FavoriteColorIntent
has a single, required slot called favoriteColor
. The intent is configured with auto-delegation, so Alexa prompts the user to fill the slot if the user doesn't provide a value initially.
This code example uses the Alexa Skills Kit SDK for Node.js (v2).
const FavoriteColorIntentHandler = {
canHandle(handlerInput) {
getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& getIntentName(handlerInput.requestEnvelope) === 'FavoriteColorIntent'
&& getDialogState(handlerInput.requestEnvelope) === 'COMPLETED';
},
handle(handlerInput) {
const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();
const favoriteColor = getSlotValue(handlerInput.requestEnvelope, 'favoriteColor')
sessionAttributes.favoriteColor = favoriteColor;
handlerInput.attributesManager.setSessionAttributes(sessionAttributes);
const speechText = `I saved the value ${favoriteColor} in the session attributes.
Ask me for your favorite color to demonstrate retrieving the attributes.`;
const repromptText = `You can ask me, what's my favorite color?`;
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(repromptText)
.getResponse();
}
};
This code example uses the Alexa Skills Kit SDK for Python.
from ask_sdk_core.dispatch_components import AbstractRequestHandler
from ask_sdk_core.utils import is_intent_name, get_dialog_state, get_slot_value
from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_model import Response, DialogState
class FavoriteColorIntentHandler(AbstractRequestHandler):
"""Handler for FavoriteColorIntent."""
def can_handle(self, handler_input):
# type: (HandlerInput) -> bool
return is_intent_name("FavoriteColorIntent")(
handler_input) and get_dialog_state(
handler_input=handler_input) == DialogState.COMPLETED
def handle(self, handler_input):
# type: (HandlerInput) -> Response
# Get any existing attributes from the incoming request
session_attr = handler_input.attributes_manager.session_attributes
# Get the slot value from the request and add it to the session
# attributes dictionary. Because of the dialog model and dialog
# delegation, this code only ever runs when the favoriteColor slot
# contains a value, so a null check is not necessary.
fav_color = get_slot_value("favoriteColor")
session_attr["favoriteColor"] = fav_color
# The SDK automatically saves the attributes to the session,
# so that the value is available to the next intent
speech_text = ("I saved the value {} in the session attributes. "
"Ask me for your favorite color to demonstrate "
"retrieving the attributes.").format(fav_color)
reprompt_text = "You can ask me, what's my favorite color?"
return handler_input.response_builder.speak(speech_text).ask(
reprompt_text).response
This code example uses the Alexa Skills Kit SDK for Java.
package handlers;
import static com.amazon.ask.request.Predicates.intentName;
import java.util.Map;
import java.util.Optional;
import com.amazon.ask.attributes.AttributesManager;
import com.amazon.ask.dispatcher.request.handler.HandlerInput;
import com.amazon.ask.dispatcher.request.handler.impl.IntentRequestHandler;
import com.amazon.ask.model.DialogState;
import com.amazon.ask.model.IntentRequest;
import com.amazon.ask.model.Response;
import com.amazon.ask.request.RequestHelper;
public class FavoriteColorIntentHandler implements IntentRequestHandler {
@Override
public boolean canHandle(HandlerInput handlerInput, IntentRequest intentRequest) {
// This intent is configured with required slots and auto-delegation,
// so the handler only needs to handle completed dialogs.
return handlerInput.matches(intentName("FavoriteColorIntent"))
&& intentRequest.getDialogState() == DialogState.COMPLETED;
}
@Override
public Optional<Response> handle(HandlerInput handlerInput, IntentRequest intentRequest) {
RequestHelper requestHelper = RequestHelper.forHandlerInput(handlerInput);
// Get any existing attributes from the incoming request
AttributesManager attributesManager = handlerInput.getAttributesManager();
Map<String,Object> attributes = attributesManager.getSessionAttributes();
// Get the slot value from the request and add to a map for the attributes.
// Because of the dialog model and dialog delegation, this code only ever
// runs when the favoriteColor slot contains a value, so a null check
// is not necessary.
Optional<String> favoriteColor = requestHelper.getSlotValue("favoriteColor");
attributes.put("favoriteColor", favoriteColor.get());
// This saves the attributes to the session, so the value is available
// to the next intent.
attributesManager.setSessionAttributes(attributes);
// Include a reprompt in the response to automatically set
// shouldEndSession to false.
return handlerInput.getResponseBuilder()
.withSpeech("I saved the value " + favoriteColor.get() +
" in the session attributes. Ask me for your favorite color" +
" to demonstrate retrieving the attributes." )
.withReprompt("You can ask me, what's my favorite color?")
.build();
}
}
The following code example shows the JSON response sent by the FavoriteColorIntentHandler
. You can see that the sessionAttributes
object includes the favoriteColor
property.
{
"version": "1.0",
"sessionAttributes": {
"favoriteColor": "blue"
},
"response": {
"outputSpeech": {
"type": "SSML",
"ssml": "<speak>I saved the value blue in the session attributes. Ask me for your favorite color to demonstrate retrieving the attributes.</speak>"
},
"reprompt": {
"outputSpeech": {
"type": "SSML",
"ssml": "<speak>You can ask me, what's my favorite color?</speak>"
}
},
"shouldEndSession": false
}
}
Access session attributes
The following example shows how an intent handler can access data from the session attributes. In this example, the WhatsMyColorIntent
has no slots. It retrieves previously set data from the session attributes to respond. If the data doesn't yet exist (because the user invoked this intent before invoking FavoriteColorIntent
), the handler uses the Dialog.ElicitSlot
directive to invoke FavoriteColorIntent
and prompt for the missing data.
This code example uses the Alexa Skills Kit SDK for Node.js (v2).
const WhatsMyColorIntentHandler = {
canHandle(handlerInput) {
getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& getIntentName(handlerInput.requestEnvelope) === 'WhatsMyColorIntent';
},
handle(handlerInput) {
const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();
if (sessionAttributes.favoriteColor) {
return handlerInput.responseBuilder
.speak(`Your favorite color is ${sessionAttributes.favoriteColor}`)
.getResponse();
} else {
return handlerInput.responseBuilder
.speak('You need to tell me your favorite color first.')
.reprompt('Please tell me your favorite color.')
.addElicitSlotDirective('favoriteColor')
.getResponse();
}
}
}
This code example uses the Alexa Skills Kit SDK for Python.
from ask_sdk_core.dispatch_components import AbstractRequestHandler
from ask_sdk_core.utils import is_intent_name, get_slot_value
from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_model import Response, Intent
from ask_sdk_model.dialog import ElicitSlotDirective
class WhatsMyColorIntentHandler(AbstractRequestHandler):
"""Handler for WhatsMyColorIntent."""
def can_handle(self, handler_input):
# type: (HandlerInput) -> bool
return is_intent_name("WhatsMyColorIntent")(handler_input)
def handle(self, handler_input):
# type: (HandlerInput) -> Response
session_attr = handler_input.attributes_manager.session_attributes
# The user could invoke this intent before they set their favorite
# color, so check for the session attribute first.
if "favoriteColor" in session_attr:
fav_color = session_attr["favoriteColor"]
return handler_input.response_builder.speak(
"Your favorite color is {}. Goodbye".format(
fav_color)).set_should_end_session(True).response
else:
# The user must have invoked this intent before they set their color.
# Trigger the FavoriteColorIntent and ask the user to fill in the
# favoriteColor slot. Note that the skill must have a *dialog model*
# to use the ElicitSlot Directive.
return handler_input.response_builder.speak(
"You need to tell me your favorite color first.").ask(
"please tell me your favorite color.").add_directive(
directive=ElicitSlotDirective(
updated_intent=Intent(
name="FavoriteColorIntent"),
slot_to_elicit="favoriteColor")).response
This code example uses the Alexa Skills Kit SDK for Java.
package handlers;
import static com.amazon.ask.request.Predicates.intentName;
import java.util.Map;
import java.util.Optional;
import com.amazon.ask.attributes.AttributesManager;
import com.amazon.ask.dispatcher.request.handler.HandlerInput;
import com.amazon.ask.dispatcher.request.handler.impl.IntentRequestHandler;
import com.amazon.ask.model.Intent;
import com.amazon.ask.model.IntentRequest;
import com.amazon.ask.model.Response;
public class WhatsMyColorIntentHandler implements IntentRequestHandler {
@Override
public boolean canHandle(HandlerInput handlerInput, IntentRequest intentRequest) {
return handlerInput.matches(intentName("WhatsMyColorIntent"));
}
@Override
public Optional<Response> handle(HandlerInput handlerInput, IntentRequest intentRequest) {
AttributesManager attributesManager = handlerInput.getAttributesManager();
Map <String,Object> attributes = attributesManager.getSessionAttributes();
// The user could invoke this intent before they set their favorite
// color, so check for the session attribute first.
if (attributes.containsKey("favoriteColor")){
String favoriteColor = attributes.get("favoriteColor").toString();
return handlerInput.getResponseBuilder()
.withSpeech("Your favorite color is " + favoriteColor + ". Goodbye")
.withShouldEndSession(true)
.build();
} else {
// The user must have invoked this intent before they set their color.
// Trigger the FavoriteColorIntent and ask the user to fill in the
// favoriteColor slot. Note that the skill must have a *dialog model*
// to use the ElicitSlot directive.
// Create the intent.
Intent intent = Intent.builder()
.withName("FavoriteColorIntent")
.build();
return handlerInput.getResponseBuilder()
.withSpeech("You need to tell me your favorite color first.")
.withReprompt("Please tell me your favorite color.")
.addElicitSlotDirective("favoriteColor", intent)
.build();
}
}
}
The following JSON example shows the incoming IntentRequest
when the user provides the name of a color. You can see the color in the session.attributes
property.
{
"version": "1.0",
"session": {
"new": false,
"sessionId": "amzn1.echo-api.session.1",
"application": {
"applicationId": "amzn1.ask.skill.1"
},
"attributes": {
"favoriteColor": "blue"
},
"user": {
"userId": "amzn1.ask.account.1"
}
},
"context": {},
"request": {
"type": "IntentRequest",
"requestId": "amzn1.echo-api.request.1",
"timestamp": "2019-02-13T04:22:36Z",
"locale": "en-US",
"intent": {
"name": "WhatsMyColorIntent",
"confirmationStatus": "NONE"
}
}
}
Structure of session attributes
You can pass along more complex data in the session attributes if necessary, as long as you can structure the data into a key/value map. For example, a quiz game skill might need attributes to keep track of the current state of the game, the user's current score, and the correct answer to the question that was just asked.
In the following example, the quizitem
attribute represents the correct answers to the current question.
{
"sessionAttributes": {
"quizscore": 0,
"quizproperty": "STATEHOOD_YEAR",
"response": "OK. I will ask you 10 questions about the United States. ",
"state": "_QUIZ",
"counter": 1,
"quizitem": {
"name": "Nevada",
"abbreviation": "NV",
"capital": "Carson City",
"statehoodYear": "1864",
"statehoodOrder": "36"
}
}
}
Save data between sessions
Session attributes exist while the session is open. After the session ends, any attributes associated with that session are lost. If your skill needs to remember data across multiple sessions, you need to save that data in persistent storage, such as Amazon DynamoDB or Amazon S3.
You can use the userId
provided in each request to identify the user. The userId
for a given user is generated when the user enables your skill in the Alexa app. Every subsequent request from that user to your skill contains the same userId
unless the user disables the skill.
Persisting attributes between skill sessions is built in to the ASK SDKs for Node.js, Java, and Python. For details, see Managing Attributes.
Support session ended
When your skill sets shouldEndSession=true
, Alexa doesn't send any further requests to your skill session. However, there are cases when your skill might leave the session open, but the session ends unexpectedly. A session ends when one of the following happens:
- The user explicitly ends the session.
- An error occurs that causes the session to end.
- The user either doesn't respond or responds with an utterance that doesn't match any intents defined in your custom voice interface model.
To notify your skill that the session ended, Alexa sends a SessionEndedRequest
. Although your skill can't return a response with speech, a card, or directives after you receive a SessionEndedRequest
, your SessionEndedRequest
handler is a good place to put your cleanup logic.
Sample code
The following sample code demonstrates how to persist session attributes:
- Build An Alexa High Low Game Skill (Node.js)
- Build An Alexa High Low Game Skill (Python)
- Alexa Skill: Trivia Game (Java)
The following sample code demonstrates how to store more complex session attributes for game state:
- Build An Alexa Quiz Game Skill (Node.js)
- Build An Alexa Quiz Game Skill (Python)
- Build An Alexa Quiz Game Skill(Java)
Related topics
Last updated: Mar 13, 2024