Use DynamoDB for Data Persistence with Your Alexa-hosted Skill
When you create an Alexa-hosted skill, you get access to an Amazon DynamoDB table for persisting data. Your DynamoDB table is part of the Amazon Web Services (AWS) free tier that provides storage free of charge within the usage limits. All user data stored in your DynamoDB table is fully encrypted at rest with encryption keys managed by AWS Key Management Service (KMS). For details, see DynamoDB Encryption at Rest.
The ASK SDK for Node.js and the ASK SDK for Python each include an adapter to persist data to DynamoDB.
For an overview of hosted skills, see About Alexa-hosted Skills. To provision DynamoDB resources close to your skill users to reduce the perceived latency of your skill, see Hosting your skill resources in different AWS Regions.
Use DynamoDB to persistent session data
When you create an Alexa-hosted skill, Alexa creates a DynamoDB table, named with a UUID-formatted string. Use the table, as needed, to store skill attributes so that you can continue the skill on the next invocation.
Each item in the table has a unique identifier, called a primary key, that distinguishes the item from others items in the table. For the Alexa-hosted DynamoDB table, the primary key is the user ID from the context.System.user.userId
property in standard requests from Alexa. You define the attributes for each user entry in the database. Each attribute is a data element that your skill wants to persist across sessions, such as the last question answered in a trivia game.
DynamoDB uses the user ID value as the partition key to determine the partition in which to store the item. As a result, the DynamoDB service stores each user's data in a separate partition to allow for scalability and efficient retrieval. For more details about the structure of DynamoDB, see Core components of Amazon DynamoDB.
In your skill code, you can configure the Alexa Skills Kit (ASK) SDK PersistenceAdapter
to use the DynamoDB table to persist attributes for each user. Then, use the persistentAttributes
object to store and retrieve any attributes that you want to persist across sessions.
Alexa stores the DynamoDB table name and region in the following environment variables that you can access from your skill:
DYNAMODB_PERSISTENCE_TABLE_NAME
DYNAMODB_PERSISTENCE_REGION
View your Amazon DynamoDB table
Each Alexa-hosted skill gets one DynamoDB table to use to persist data.
To see the Amazon DynamoDB table for your Alexa-hosted skill
- Open the Alexa developer console and log in.
- In the list of your skills, click the name of the skill that you want to view.
- Click the Code tab.
- In the toolbar, click the Database icon to open the AWS DynamoDB console.
Your Amazon DynamoDB table appears.
Persist data with Node.js
Use the ASK SDK for Node.js to persist attributes in the DynamoDB table.
To persist data with Node.js
-
First add the following dependency in the dependencies section of your
package.json
file:"ask-sdk": "^2.6.0" "aws-sdk": "2.637.0" "ask-sdk-dynamodb-persistence-adapter": "^2.9.0"
-
Then, in your
index.js
file, add the code to import the ASK persistence adapter.const AWS = require("aws-sdk"); const ddbAdapter = require('ask-sdk-dynamodb-persistence-adapter');
-
Add the
SessionEndedRequestHandler
request handler to your skill builder request handlers.exports.handler = Alexa.SkillBuilders.custom() .addRequestHandlers( LaunchRequestHandler, // Other request handlers SessionEndedRequestHandler ) .addErrorHandlers(ErrorHandler) .withPersistenceAdapter( new ddbAdapter.DynamoDbPersistenceAdapter({ tableName: process.env.DYNAMODB_PERSISTENCE_TABLE_NAME, createTable: false, dynamoDBClient: new AWS.DynamoDB({apiVersion: 'latest', region: process.env.DYNAMODB_PERSISTENCE_REGION}) }) ) .lambda();
-
Add a handler to save attributes. By default, the
attributesManager
uses theuserId
as the primary key.async handle(handlerInput) { const attributesManager = handlerInput.attributesManager; let attributes = {"counter":10}; attributesManager.setPersistentAttributes(attributes); await attributesManager.savePersistentAttributes(); let speechOutput = `Hi there, Hello World! Your saved counter is ${attributes.counter}`; return handlerInput.responseBuilder .speak(speechOutput) .getResponse(); }
-
Add a handler to read attributes.
async handle(handlerInput){ const attributesManager = handlerInput.attributesManager; const attributes = await attributesManager.getPersistentAttributes() || {}; console.log('attributes is: ', attributes); const counter = attributes.hasOwnProperty('counter')? attributes.counter : 0; let speechOutput = `Hi there, Hello World! Your counter is ${counter}`; return handlerInput.responseBuilder .speak(speechOutput) .getResponse(); }
Persist data with Python
Use the ASK SDK for Python to persist attributes in the DynamoDB table.
To persist data with Python
-
First add the following dependency in the dependencies section of your
requirements.txt
file:boto3==1.9.216 ask-sdk-core==1.11.0 ask-sdk-dynamodb-persistence-adapter==1.15.0
-
Then, in your
lambda_function.py
file, add the code. Import the ASK persistence adapter.import os import boto3 from ask_sdk_core.skill_builder import CustomSkillBuilder from ask_sdk_dynamodb.adapter import DynamoDbAdapter
-
Initialize the persistence adapter.
ddb_region = os.environ.get('DYNAMODB_PERSISTENCE_REGION') ddb_table_name = os.environ.get('DYNAMODB_PERSISTENCE_TABLE_NAME') ddb_resource = boto3.resource('dynamodb', region_name=ddb_region) dynamodb_adapter = DynamoDbAdapter(table_name=ddb_table_name, create_table=False, dynamodb_resource=ddb_resource)
-
Add the
SessionEndedRequestHandler
request handler to your skill builder request handlers.sb = CustomSkillBuilder(persistence_adapter = dynamodb_adapter) sb.add_request_handler(LaunchRequestHandler()) sb.add_request_handler(CancelOrStopIntentHandler()) sb.add_request_handler(SessionEndedRequestHandler()) # # Other request handlers # sb.add_exception_handler(CatchAllExceptionHandler()) lambda_handler = sb.lambda_handler()
-
Add a handler to save attributes. By default, the
attributes_manager
uses theuserId
as the primary key.def handle(self, handler_input): # type: (HandlerInput) -> Response attr = handler_input.attributes_manager.persistent_attributes if not attr: attr['counter'] = 0 attr['state'] = 'ENDED' handler_input.attributes_manager.session_attributes = attr handler_input.attributes_manager.save_persistent_attributes() speak_output = ("Welcome back. Your saved counter is {}. You can say Hello or Help?".format(attr["counter"])) reprompt = "Say hello or help to start." return ( handler_input.response_builder .speak(speak_output) .ask(reprompt) .response )
-
Add a handler to read attributes.
def handle(self, handler_input): # type: (HandlerInput) -> Response session_attr = handler_input.attributes_manager.session_attributes session_attr['state'] = "STARTED" session_attr["counter"] += 1 handler_input.attributes_manager.persistent_attributes = session_attr handler_input.attributes_manager.save_persistent_attributes() speak_output = ("Hi there, Hello World! Your saved counter is {}.".format(session_attr["counter"])) return ( handler_input.response_builder .speak(speak_output) # .ask("add a reprompt if you want to keep the session open for the user to respond") .response )
-
(Optional) Add a handler to delete attributes.
def handle(self, handler_input): # type: (HandlerInput) -> Response session_attr = handler_input.attributes_manager.session_attributes session_attr['state'] = "ENDED" speak_output = ("Goodbye. Your counter is {}".format(session_attr["counter"])) handler_input.attributes_manager.delete_persistent_attributes() return ( handler_input.response_builder .speak(speak_output) .response )
Related topics
- Use Media Files with Your Alexa-Hosted Skill
- Use Personal AWS Resources with Your Alexa-hosted Skill
Last updated: May 01, 2024