Alexa Skill with NodeJs, Part II: Understanding the flow

This is the second part in “Alexa Skill with NodeJs” series. In the first part, we discussed how to setup AWS configuration to use AWS Lambda. We also created a local development environment and deployed it using ASK CLI. If you are new to AWS configuration and ASK CLI, you should first go through “Alexa Skill with NodeJs, Part I: Setup

What’s in this article?

In this article, I will explain the project structure in detail. I will then introduce you to some ASK CLI commands to sync up Alexa Skill console and AWS Lambda function with local development. We will then understand basic fundamentals of Custom Alexa Skill. We will also have a look at using sessions, states and persisting our data in dynamoDB. For this article, I have already set up a project on GitHub based on this example.

Take a note that this is not the complete tutorial. Purpose of this article is to get you started with some basic fundamentals which you may not know as a beginner. Go through Custom Skill Guide and alexa-skills-kit-sdk-for-nodejs from time to time to build up your concepts.

Set up a new project

To follow up with this article, go through these steps:

  1. Set up a new project with the skill name “FlashCards”.
ask new --skill-name FlashCards --profile alexa-user

2. Copy files under lambda and models folder from here and paste it into your project.

3. Then deploy it.

ask deploy --profile alexa-user

After successful deployment you can see your deployed skill on Alexa Skill Console and lambda function uploaded on AWS Lambda.

Project Structure

Now we will take a look at our project structure from top to bottom.

Project Structure

config” file under “.ask” folder includes deployment settings. It has skill id and endpoint our skill will send requests to. In our case this endpoint points to our newly created lambda function. All our code which will be deployed on AWS Lambda is inside “lambda ”folder. Interaction models for our skill is in json file under “models” folder. Files are named with the name of locale your are developing that interaction model for. In this case, it is “en-US”. In the end we have “skill.json” which has publishing information. It also has an api endpoint which points to source directory of lambda function.

Some basics to begin with…

I hope you have some knowledge about how things work in when it comes to creating custom skill. If you don’t, you should consider reading official documentation. Anyways, to begin with, I will explain some basic fundamentals. Click on edit which should be on the left side of FlashCard skill on Alexa Skill Console page. You will be greeted by the following page.

Aelxa Skill Dashboard

Invocation

First thing on the left-hand side panel is Invocation. You can edit invocation name of your skill here. There are several ways to invoke a skill, For ex.- “Alexa, Open {invocation_name}”, “Alexa ask {invocation_name} to {do_something}”. Make sure it is “flash cards” in our case.

Intents

Then comes intents. Whatever we say or ask to do something to Alexa, it maps it to a particular intent. There are two types of intents, Custom and Built-In. Built-In intents are some standard intents for basic utterances like “yes”, “no”, “stop” or “help”. We have three custom intents here:

  • AnswerIntent
  • PracticeIntent
  • QuizIntent

Utterances

Alexa leverage NLU (Natural Language Understanding) to create utterances based on what user is saying. These utterances are then used to map intents. For ex.- “AnswerIntent” has utterances like “it is in {usstate}” and “{usstate}

Slots

Slots are basically a variable used in utterances. Slots have types and these particular types can have sample slot values. Slot values can have synonyms. Slots could be Custom or Built-In. It is always recommended to look for “Built-In” type if it serves your purpose. In above example “it is in {usstate}”, “usstate” is a slot of Built-In type AMAZON.US_STATE. Whenever user says something like “it is in virginia”, Alexa knows that slot “usstate” has value “virginia”.

Play around more to understand and get used to things.

Handy ASK CLI commands

Here are some commands to keep your local development in sync with Alexa Skill Console and AWS Lambda:

  • Update local “skill.json” file
ask api get-skill --skill-id --stage development > skill.json
  • Update local models
ask api get-model --skill-id <skill_id> --locale en-US --stage development > models/en-US.json
  • Update deployed skill info
ask api update-skill --skill-id <skill_id> --file skill.json --stage development --profile alexa-user
  • Update deployed interaction model
ask api update-model --skill-id <skill_id> --file models/en-US.json --locale en-Us --profile alexa-user --stage development
  • Deploy Lambda function
ask deploy -t lambda --profile alexa-user

All of these commands are to be run from the root directory. These commands will come in handy if you want to update only specific changes.

Heart of our Alexa Skill, Lambda function

Lambda folder
index.js

Let’s have a look at “index.js” file. It is exporting a handler function which represents the name of your lambda function. It is an entry point for AWS Lambda which it uses to execute your function’s code. An event is something which is passed from the application or service invoking the function. Context is for the purpose of interacting with lambda function to collect logs or other run-time parameters. Everything else is basic Alexa configuration and at the end, we call alexa.execute() to create a response.

Alexa creates requests based on invocation and utterances. It then sends these requests to lambda function in the event object. Now comes the role of handlers to handle the particular request based on intent. We have defined handlers in different files in handlers folder. According to intent present in our request’s event object, particular handler function specified for that intent is fired. Read documentation to know how to create a response and emit it in the handler function. All the handler functions needs to be registered using registerHandlers function of alexa object.

When you invoke a skill, Alexa creates a request containing “LaunchRequest” event. If you are using stateless handlers, you can specify “LaunchRequest” handler which will handle the invocation request. But in our project, we are using state manager to handle the request. In this case, “NewSession” handler in “newSessionHandlers.js” will be fired in case of any incoming intent or launch requests with no state. Read this to know more about state management.

Maintaining session

Note that Alexa cannot maintain a persistent connection to lambda as it is a serverless service. So to maintain a session, lambda function sends session key-value pairs in a sessionAttributes field of the response.

Launch Request

Alexa then puts these values in attributes field of the subsequent requests as follows.

Intent Request

Creating session attributes is very easy. You have to take use of this.attributes object. Whatever you store in it is saved in the session.

This session lasts only for the period your skill is active. To persist your session attributes in the database, you can take advantage of Amazon DynamoDB. So next time you launch your skill your session attributes will be right there in this.attributes object. And to do that, you have to add this line.

alexa.dynamoDBTableName="your_table_name"

Pretty neat, isn’t it?

Note that your states you define with this.hander.state also gets persist in DynamoDB. This happens because, this.handler.state references to this.attribute[‘state’]. So if you want to clear state in particular case, add following.

You can only use up to 24kb of data while creating request. So take care while persisting everything into session. You can use DynamoDB to store large values by leveraging aws-sdk. You can use DynamoDB’s Node.js API to create a table, update documents etc. Just be sure to use different table than the one you are using for persisting session attributes.

Conclusion

Use this article to get started with your first skill. To understand rest of the code you have to refer to following documentations from time to time.

Wait, there is more to it…

Well, this was a very basic example of how the skill works. To make a complex skill, you may have to make more use of sdk’s functionalities like interfaces and services. You can refer to above-mentioned documentations to learn more.
If you want to get acquainted with every functionality Alexa Skill Kit offers and know how to leverage it, then alexa-cookbook has the perfect set of examples for you to start.

What’s next?

While developing, you can’t always deploy to test just one change of line. It’s not efficient for collaborations too. While Amazon has not provided anything to work with our skill development locally, javascript testing frameworks like chai, mocha comes to rescue. In the next article, I will discuss how to setup lambda context and DynamoDB locally and write test for our use case using chai and mocha. See you there.

Questions? Feedback? Comments? Leave a note here or contact me on twitter @Akshay_Milmile.