Alexa skill development done right: Advanced setup

In order to build an engaging skill, the first part of this series — introducing the basics of Alexa skill development — may not be detailed enough. For an advanced skill it is often necessary to use a session- and file-storage which allows to save the session through multiple invocations. Furthermore, you can make card responses more appealing using images. Therefore we will learn how to add a DynamoDB session storage and S3 file storage to our skill.

As an optional goal we will minify our code before we deploy it to lambda. This could save up to 90% of deployment file size and therefore deployment time which makes developing a skill even faster.

Check out the repo with the finished setup on Github.

Add a session storage: DynamoDB

DynamoDB is a NoSQL database where you can save json without having to deal with schema definitions, setup or scaling. Also the ask sdk can deal with a DynamoDB by default so we don’t have to think about saving and matching the session to specific users.

To add a DynamoDB we have to add it as resource to our serverless.yml. We also need to extend the default serverless IAM roles, so that out lambda function is allowed to access the database:

As you can see, we added the database and an IAM role. Note that the added role allows the lambda funtion to access all databases. This is only because of simplicity, in production you should limit it to the skills database.

For the DynamoDB we defined a primary key column userId as this is mandatory for the ask sdk to save the session id for every user. Other columns (the ones with the actual session data) will be created directly on the fly from the ask sdk. The name of the database comes from a config file (line 15).

The config file looks like this:

Because we have outsourced the table name into a json file we can also access the json within our skill. This is necessary as we have to reference it to the ask sdk like this:

With this setup we can now deploy our infrastructure with serverless and save session data. Examples how to save the data can be found in the finished example project on Github or the offical ask sdk documentation.


Add a file storage: S3

At some point your skill may need static content like an image or a sound. The simplest way to store this content is with AWS S3. We therefore have to add a new resource in our serverless.yml like we did with DynamoDB in the previous step:

As you can see the configuration defines a bucket that is publicly accessible for GET requests and also adds a corresponding CORS rule like it is described in the alexa documentation for hosting images. Unfortunately we must upload our files manually, as serverless currently doesn’t support uploading binaries to S3. This can be realized for example with the AWS SDK and the sync command. Check out the example project to see it implemented. After you have uploaded the files, you can copy their URL from the S3 dashboard and paste them into your skills card response.

Speed up deployment

Serverless packages all files in the src and node_modules folder and uploads them to lambda. This leads to a lot of unused data which will be uploaded. If we look into our deployment logs we will see that the whole package is about 5.7MB. That’s a lot for such a small skill and it could get a lot more if we add more libraries. As the file size directly impacts the upload time — and the upload time is the biggest time consumer during deployment — this can slow down the deployment time in general.

To throw out all stuff that’s not needed we can use webpack. Webpack bundles all scripts into one file and throws out all unused code. To use it with serverless we need to install webpack and the serverless-webpack plugin. Then we can activate the plugin by adding it to our serverless.yml file:

Webpack needs a basic configuration like this:

If we now deploy our function to lambda, serverless will automatically bundle our files. When we look into the deployment logs we can see that the size of the whole package is now only about 0.5KB. This is a minification of over 90 percent! If our skill gets bigger the minification can even be better and save us even more deployment time.


Conclusion

Our skill is now able to save session data, store files, the deployment is extremely fast and everything is configurable within the project. This is the perfect basis for developing a successful skill. If you want to see everything in full detail, checkout the repository with an example skill:

Happy coding :)