This document covers how to use Dynamo DB persistence in your Alexa skill using a direct connection the AWS SDK rather than using the ASK SDK persistence adapter (you can see how to use the adapter here).
This readme assumes you have your developer environment ready to go and that you have some familiarity with CLI (Command Line Interface) Tools, AWS, and the ASK Developer Portal.
- Node.js (> v8)
- Register for an AWS Account
- Register for an Amazon Developer Account
- Install and Setup ASK CLI
-
Make sure you are running the latest version of the CLI
npm update -g ask-cli
-
Create the skill.
ask new
ASK CLI will create the skill and the lambda function for you. The Lambda function will be created in us-east-1 (Northern Virginia)
by default. If you want the back-end in Europe export this environment variable: AWS_REGION=eu-west-1
.
- Navigate to the project's root directory. you should see a file named 'skill.json' there.
- Deploy the skill and the lambda function in one step by running the following command:
ask deploy
- Once deployed, additional permissions need to be added to the AWS IAM role being used by the function since it is persisting data in Amazon DynamoDB. Locate the execution role used by the skill's Lambda function in the AWS IAM Console.
- Open the AWS Console: https://console.aws.amazon.com/iam
- Click on Roles.
- Type (at least part of) the name of your skill in the search box. (Replace spaces with dashes.)
- Click the role that corresponds to your skill's function.
Note: If you can't find the correct role, first locate your skill's function in AWS Lambda. Scroll down to the section labeled Execution Role and find the role name there.
- On the right side of the Permissions tab, click + Add inline policy.
- Click the JSON tab.
- Select the existing JSON and replace it with the following policy document. This policy grants access to the role to (1) create the needed table and (2) read/write items to the table. It is restricted to this for just a table named 'My-Table' (replace it with yours).
{ "Version": "2012-10-17", "Statement": [ { "Sid": "DynamoDBTableAccess", "Effect": "Allow", "Action": [ "dynamodb:CreateTable", "dynamodb:PutItem", "dynamodb:GetItem", "dynamodb:UpdateItem", "dynamodb:PutItem", "dynamodb:DeleteItem", "dynamodb:Scan", "dynamodb:Query" ], "Resource": "arn:aws:dynamodb:*:*:table/My-Table" } ] }
> Note: The table name as specified in the sample code is `My-Table`. If you want to use a different name, change it in the policy and in the sample code. The name doesn't matter as long as they match.
- Click Review Policy.
- Enter
DynamoDBTableAccess
as the Name. - Click Create Policy.
-
lambda/custom/package.json
You need to include the AWS package in imports:
{ "name": "hello-world", "version": "0.9.0", "description": "alexa hello world sample skill", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { "ask-sdk-core": "^2.0.7", "ask-sdk-model": "^1.4.1", "aws-sdk": "^2.326.0" } }
Note that there's no need to incluse any SDK persistence adapter in the dependencies
-
./lambda/custom/index.js
Incorporate @javichur's DB helper file (MIT licensed) in your lambda and call the helper functions like this (using async/await):
const DBHelper = require('./dbHelper'); const dynamoDb = new DBHelper("My-Table", "userId", null); // "Primary partition key" = userId (String) // parent function must be defined as "async" let data; try { data = await dynamoDb.getItem(userID); .catch((err) => { // error accessing dynamodb ... }); if(data){ // data exists } ...