Save the State of an Echo Button Skill

As with any Alexa skill, you can personalize the user experience of your Echo Button skill by saving the state for a user across multiple skill sessions. This way, your skill can welcome the user back, restore their progress, provide a shorter version of the instructions, and so on. Another reason to save the state is that your skill can be interrupted at any time by an Alexa event such as a call or an alarm. This topic describes your options for saving the state of your skill, and provides an example.

What is a Skill Session?

First let's review what a skill session is, and how it is tied to a particular user. A skill session represents a sequence of one or more user interactions with the skill, and the skill's responses to those interactions. A user can interact with the skill using their voice, a touchscreen (for certain Echo devices), or by pressing Echo Buttons (if the skill supports the Gadgets Skill API). A skill session's lifecycle is as follows:

  1. A user invokes your skill by speaking a phrase such as "Alexa, open [skill's invocation name]".
  2. Alexa sends a request to your skill code (for example, it calls your AWS Lambda function). The request contains a session object, which contains information about the session (such as the session ID) and about the user (such as the user ID). As such, the session is tied to the user.
  3. Your skill provides a response for Alexa to speak to the user. In its response, the skill can store data as attributes in the session object as key/value pairs. These will be passed back to your skill in the next request object.
  4. The skill session continues as the user speaks to Alexa (who passes the requests to your skill) and your skill responds to Alexa (who passes the responses to the user). The skill session ends when either the skill sets the shouldEndSession property in the response object to true, or the user fails to respond.

Where to Save the State

To save the state of your skill across multiple sessions, you must save the state in a data store that is external to the skill session. The built-in attributes in the session object that Alexa includes in the requests to your skill will not work for this purpose because when the skill session ends, the session object no longer exists.

You can use any external data store to save the state of your skill. The option that you choose depends on aspects of your project such as cost, code complexity, maintenance, and so on. For example, the Amazon DynamoDB FAQ discusses the suitability of DynamoDB versus other AWS options such as Amazon S3. When you save the state of an Alexa skill to a data store, particularly important aspects include:

  • Low latency – Writing and reading the state data should be as fast as possible.
  • Data consistency – Writing and reading the state data must preserve the accuracy and validity of the data. For example, reads and writes must not interfere with each other.

In the next section, we provide a simple implementation that uses DynamoDB.

Example

As mentioned previously, you cannot save the skill state across sessions by using session attributes alone. However, as shown in this example, you can use session attributes in conjunction with the Alexa SDK and DynamoDB to achieve this objective.

To do so, you configure the Alexa SDK to automatically save the session attributes to a table in DynamoDB. The table uses the user ID as the primary key. On subsequent invocations of your skill, the session attributes for that user are automatically loaded from DynamoDB into the session object. Note that the user ID will change if the user disables and re-enables your skill.

This example assumes that your skill code is an AWS Lambda function written in Node.js.

The steps are as follows:

Step 1: Give the Lambda Function Permission to Access DynamoDB

You first need to give your Lambda function's role permission to access DynamoDB. You can do so in the IAM console as follows:

  1. Sign in to the AWS Management Console and navigate to the IAM console.
  2. In the left-hand menu, choose Roles. From the role list, choose the role that your skill's Lambda function uses.
  3. On the Permissions tab, at the bottom right, choose Add Inline Policy.
  4. On the Visual editor tab, choose the following settings:
    • Service – Choose DynamoDB.
    • Actions – Choose the following actions:
      • Read actions – Choose GetItem and Query.
      • Write actions – Choose CreateTable, DeleteItem, PutItem, and UpdateItem.
    • Resources – Choose All resources for now. Later, after you know the ARN of the DynamoDB table, you can use this setting to scope permissions to that table only.
    • Request conditions – Leave this at the default setting.
  5. Click the Review policy button.
  6. Enter a name for the policy, and then click the Create policy button.

Step 2: Include the Alexa SDK

In your skill code, at the top of index.js, include the Alexa SDK by adding the following line:

var Alexa = require('alexa-sdk');

Step 3: Configure exports.handler

In the exports.handler block of your skill code, declare an Alexa.handler object and specify a name for the DynamoDB table by setting the alexa.dynamoDBTableName property any time before alexa.execute(). The table does not need to exist yet. It will be created automatically the next time this Lambda function is invoked.

exports.handler = function(event, context, callback) {
    var alexa = Alexa.handler(event, context);
    alexa.dynamoDBTableName = 'YourTableName'; // Session attributes will be saved to this table.
    alexa.registerHandlers(handlers);
    alexa.execute();
};

Step 4: Set Session Attributes

In your skill code, set session attributes by saving to the attributes property of the Alexa object. Be sure to do this before you emit() a response.

For example, you can keep track of the fact that the user listened to the instructions by saving an attribute in an intent handler as follows:

this.attributes["ListenedToInstructions"] = true;
this.emit(':responseReady');

Note that ListenedToInstructions is just an example of an attribute name; it is not defined by Alexa.

The attributes will be automatically saved to DynamoDB in the table that you specified in the last step, using the user ID as the key.

Step 5: Use the Restored Session Attributes

You don't need to add code to load the session attributes from DynamoDB to the session object. This happens automatically the next time the same user invokes your skill. In your skill's intent handlers, you access the session attributes as you normally would. Continuing the previous example:

if (this.attributes["ListenedToInstructions"] === true) {
  // Play the short form of the instructions.
}
else {
  // Play the long form of the instructions.
}