Alexa

An Alexa Skill in Javascript – Part 6

We’ve done it! We’ve built an Alexa skill! Woohoo! Now we need to publish our skill to the Alexa Skills Catalog and make it official. Publishing your Alexa skill is the last step in the process of developing and deploying an Alexa Skill.

NOTE: Pay attention to Amazon’s developer promotions. You can get a free T-Shirt, Echo Dot, Echo Spot, and even the Echo Show if you publish your skill at the right time.

Prepping the skill.json File

There are a few things we can do to enhance the skill.json file so our skill is ready for publishing.

First, find two images that you can use to represent your skill. These will appear in the catalog inside the speech bubble, like so:

The images should be png files in two sizes: small (108 x 108 px) and large (512 x 512 px). Create a new folder in your project called images and drop the two image files into it for safe-keeping. We’ll add them to the distribution page later.

Next, we can add some keywords to our skill.json file to help people find our skill more easily, right after the description tag add a “keywords” tag:

Say “Alexa, start Roll Some Dice and roll a die.” Alexa will generate a random number between 1 and 6 and say, for example, “You said roll 1 dice. I rolled a three.”

Say “Alexa, start Roll Some Dice and roll 10 dice.” Alexa will generate 10 random numbers between 1 and 6 and report the results, for example, “You said roll 10 dice. I rolled 3 ones, 4 threes, a four, a five and a six.”

With a modifier:

Say “Alexa, start Roll Some Dice and roll a die plus one.” Alexa will generate a random number between 1 and 6 and add 1, and say, for example, “You said roll 1 dice plus 1. I rolled a two.”

Say “Alexa, start Roll Some Dice and roll a die minus one.” Alexa will generate a random number between 1 and 6 and subtract 1, and say, for example, “You said roll 1 dice minus 1. I rolled a three.”

With a modifier using synonyms:

Say “Alexa, start Roll Some Dice and roll a die add one.” Alexa will generate a random number between 1 and 6 and add 1, and say, for example, “You said roll 1 dice plus 1. I rolled a six.”

Say “Alexa, start Roll Some Dice and roll a die subtract one.” Alexa will generate a random number between 1 and 6 and subtract 1, and say, for example, “You said roll 1 dice minus 1. I rolled a three.”

With a modifier, testing the edge/limits we put in:

Say “Alexa, start Roll Some Dice and roll a die plus seven.” Alexa will generate a random number between 1 and 6 and add 7, maxing out at 6, and say, for example, “You said roll 1 dice plus 7. I rolled a six.”

Say “Alexa, start Roll Some Dice and roll a die minus seven.” Alexa will generate a random number between 1 and 6 and subtract 7, with a minimum value of 0, and say, for example, “You said roll 1 dice minus 1. I rolled a zero.”

Testing missing slots and default values:

Say “Alexa, start Roll Some Dice and roll dice.” Alexa will generate a random number between 1 and 6 and say, for example, “You said roll 1 dice. I rolled a three.”

Say “Alexa, start Roll some Dice and roll a die plus.” Alexa will generate a random number between 1 and 6 and say, for example, “You said roll 1 dice. I rolled a three.”

Say “Alexa, start Roll some Dice and roll 1 die frog 3.” Alexa will not understand and should respond, “Sorry, I can’t understand the command.”

Now we need to “stringify” those phrases and put them in our skill.json file here:

The easiest way I’ve found to convert the text in the lists above into the correct format is in a text editor (like Notepad++) to replace the “ marks with \” and then MS Word to replace all paragraph marks (under Special…) with \n, and tab characters (also under Special…) with spaces. When you’re done, the tests will look like this:

Basic Phrases:\n1. Say \"Alexa, start Roll Some Dice and roll a die.\" Alexa will generate a random number between 1 and 6 and say, for example, \"You said roll 1 dice. I rolled a three.\"\n2. Say \"Alexa, start Roll Some Dice and roll 10 dice.\" Alexa will generate 10 random numbers between 1 and 6 and report the results, for example, \"You said roll 10 dice. I rolled 3 ones, 4 threes, a four, a five and a six.\"\nWith a modifier:\n1. Say \"Alexa, start Roll Some Dice and roll a die plus one.\" Alexa will generate a random number between 1 and 6 and add 1, and say, for example, \"You said roll 1 dice plus 1. I rolled a two.\"\n2. Say \"Alexa, start Roll Some Dice and roll a die minus one.\" Alexa will generate a random number between 1 and 6 and subtract 1, and say, for example, \"You said roll 1 dice minus 1. I rolled a three.\"\nWith a modifier using synonyms:\n1. Say \"Alexa, start Roll Some Dice and roll a die add one.\" Alexa will generate a random number between 1 and 6 and add 1, and say, for example, \"You said roll 1 dice plus 1. I rolled a six.\"\n2. Say \"Alexa, start Roll Some Dice and roll a die subtract one.\" Alexa will generate a random number between 1 and 6 and subtract 1, and say, for example, \"You said roll 1 dice minus 1. I rolled a three.\"\nWith a modifier, testing the edge/limits we put in:\n1. Say \"Alexa, start Roll Some Dice and roll a die plus seven.\" Alexa will generate a random number between 1 and 6 and add 7, maxing out at 6, and say, for example, \"You said roll 1 dice plus 7. I rolled a six.\"\n2. Say \"Alexa, start Roll Some Dice and roll a die minus seven.\" Alexa will generate a random number between 1 and 6 and subtract 7, with a minimum value of 0, and say, for example, \"You said roll 1 dice minus 1. I rolled a zero.\"\nTesting missing slots and default values:\n1. Say \"Alexa, start Roll Some Dice and roll dice.\" Alexa will generate a random number between 1 and 6 and say, for example, \"You said roll 1 dice. I rolled a three.\"\n2. Say \"Alexa, start Roll some Dice and roll a die plus.\" Alexa will generate a random number between 1 and 6 and say, for example, \"You said roll 1 dice. I rolled a three.\"\n3. Say \"Alexa, start Roll some Dice and roll 1 die frog 3.\" Alexa will not understand and should respond, \"Sorry, I can't understand the command.\"\n

Now you can plug the new string in the place of Sample Testing Instructions. Like so:

"isAvailableWorldwide": true,
"testingInstructions": "Basic Phrases:\n1. Say \"Alexa, start Roll Some Dice and roll a die.\" Alexa will generate a random number between 1 and 6 and say, for example, \"You said roll 1 dice. I rolled a three.\"\n2. Say \"Alexa, start Roll Some Dice and roll 10 dice.\" Alexa will generate 10 random numbers between 1 and 6 and report the results, for example, \"You said roll 10 dice. I rolled 3 ones, 4 threes, a four, a five and a six.\"\nWith a modifier:\n1. Say \"Alexa, start Roll Some Dice and roll a die plus one.\" Alexa will generate a random number between 1 and 6 and add 1, and say, for example, \"You said roll 1 dice plus 1. I rolled a two.\"\n2. Say \"Alexa, start Roll Some Dice and roll a die minus one.\" Alexa will generate a random number between 1 and 6 and subtract 1, and say, for example, \"You said roll 1 dice minus 1. I rolled a three.\"\nWith a modifier using synonyms:\n1. Say \"Alexa, start Roll Some Dice and roll a die add one.\" Alexa will generate a random number between 1 and 6 and add 1, and say, for example, \"You said roll 1 dice plus 1. I rolled a six.\"\n2. Say \"Alexa, start Roll Some Dice and roll a die subtract one.\" Alexa will generate a random number between 1 and 6 and subtract 1, and say, for example, \"You said roll 1 dice minus 1. I rolled a three.\"\nWith a modifier, testing the edge/limits we put in:\n1. Say \"Alexa, start Roll Some Dice and roll a die plus seven.\" Alexa will generate a random number between 1 and 6 and add 7, maxing out at 6, and say, for example, \"You said roll 1 dice plus 7. I rolled a six.\"\n2. Say \"Alexa, start Roll Some Dice and roll a die minus seven.\" Alexa will generate a random number between 1 and 6 and subtract 7, with a minimum value of 0, and say, for example, \"You said roll 1 dice minus 1. I rolled a zero.\"\nTesting missing slots and default values:\n1. Say \"Alexa, start Roll Some Dice and roll dice.\" Alexa will generate a random number between 1 and 6 and say, for example, \"You said roll 1 dice. I rolled a three.\"\n2. Say \"Alexa, start Roll some Dice and roll a die plus.\" Alexa will generate a random number between 1 and 6 and say, for example, \"You said roll 1 dice. I rolled a three.\"\n3. Say \"Alexa, start Roll some Dice and roll 1 die frog 3.\" Alexa will not understand and should respond, \"Sorry, I can't understand the command.\"\n",
"category": "GAME_INFO_AND_ACCESSORY",

Now, with all that in place, you should be able to push the skill to Amazon again. At a PowerShell command prompt, from the root folder of your skill, enter the following command:

ask deploy --profile "default" --target "all"

Assuming your skill deployed properly and passes all your tests, we are ready to go through the Distribution and Certification steps in the Alexa Developer Console.

On the first page of Distribution, we can upload the icon files we found earlier. Simply add them here:

Now click Save and Continue.

Then, because we already filled all this in the skill.json, you can just click Save and Continue again.

It passes!! Your skill is ready for Submission. Go ahead. Click that Submit button and relax for a bit. Depending on the promotions and backlog, your skill may or may not get reviewed within the next 1-3 business days.

Finally, the last post in the series. Here, we will show Alexa how to Roll Some Dice with a modifier so that we can get our skill working properly.

We’re going to do this in two steps:

Create a function that will take the diceCount, plusMinus and modifier parameters and return the results as speech text.

We’ll modify the RollSomeDiceIntentHandler to pull those parameters from the Request and call the function we created in the first step.

Create a Function that can Roll Some Dice

To contain our function, we’ll create a new JavaScript file in the lambda\custom folder of our project. Right-click on the lambda\custom folder and select New File from the menu. Enter rollSomeDiceFunction.js as the file name.

In the new file, let’s stub out our function. We need to export the function to be able to access it from the other file, index.js. It will accept three parameters. Like so:

Then, we need to convert the string parameters into numbers. Slot values are always provided as strings. We need to verify that the diceCount and modifier contain numeric values and parse the strings to actual numbers.

Now, we’ve completed the for loop that loops over the diceCount and we can start putting together the speech phrases that we want Alexa to say in her response. First, we’ll tackle the buckets so she can say “I rolled 3 ones, 2 twos, a four and 3 sixes.” Note: This code snippet uses apostrophes ( ‘ ‘ ) and backward tick marks ( ` ` ) to create the right strings.

The above code handles the fact that six is the only plural that ends in ‘es’. And that six is the last number in the set, so put an ‘and’ in front of it. It also differentiates between ‘a six’ and ‘two sixes’.

The next phrase to put together is the entire speech that we want Alexa to say. We have two options: with modifier and without, so the code looks like this:

Wait a moment while the ASK initializes, then select the default profile:

Then select “All”:

Now, it will try, and probably fail, to deploy. If it succeeds, great. If it fails, you probably need to change the working directory in the Terminal window at the bottom right of VS Code. This is done with the CD command, like so:

Once you’ve changed the directory to the one with your skill in it, press the up arrow on the keyboard a couple of times to get the “ask deploy” command back. Then press enter.

If all goes well, a few moments later, your skill will be deployed:

Now that your skill is deployed, we can switch over to the Alexa Developer Console to test it. If you still have your template project open from earlier, click “Your Skills” in the top left corner. Then you will see your deployed skill at the top of the list:

Click the Edit link on the far right. On the Build tab, you should see a little popup saying your build was successful:

Click on the Test tab. If it’s not enabled, enable testing for this skill:

In the Alexa Simulator, type in “start Roll Some Dice and roll 2 dice”. Press enter.

Alexa should say that she rolled some dice and list the results:

I just realized, there’s one last step: Submitting Your Skill for Amazon Approval. This will be covered in my next blog entry.

So far we’ve defined, gathered and installed the requisite tools in Part 1. We’ve defined the Skill we’re creating in Part 2. And, we’ve created the Intents for our skill in Part 3.

Now, we will code the Lambda function that is the brains of our skill in this entry, Part 4.

What is a Lambda Function?

Amazon Web Services (AWS) calls the functions you create in their cloud “Lambda Functions.” For the purposes of Alexa skills, these functions are the brains behind the skill. Alexa takes care of the speech part of the skill, and figures out how to interpret the Alexa User’s spoken words and which intent to choose and slots to fill based on those words, but you then have to make your Alexa skill actually do something to fulfill the intent you created on the Alexa side of your Skill development process. In my case, that means writing a function that can roll some dice and add or subtract and specified modifier to the rolls.

Lambda functions can be written in a variety of languages. I’ve blogged before about using C# to do this. (Note: Using C# is now SOOO much easier as the Lambda Function tools in AWS have been updated to use .Net Core as a standard platform.) Today, I am using JavaScript (node.js). Other options include Python, Java and Go.

A Little More Cleanup First

In our VS Code project, in the \lambda\custom folder is a file named package.json. We need to correct the name of our package here. My skill is called “Roll Some Dice” so I’ll have to name my code package “roll-some-dice”. Note the lower case and replacing spaces with dashes.

In that same folder, is a file named package-lock.json. We need to make the same edit to that file. So:

{
"name": "hello-world",
"version": "1.0.0",
"lockfileVersion": 1,

Becomes:

{
"name": "roll-some-dice",
"version": "1.0.0",
"lockfileVersion": 1,

One More Thing Before We Can Code

In order to roll a dice, we need a random number generator. This can be found in the node.js module named i18next. We will also need the module named i18next-sprintf-postprocessor. To get these, we will use the npm package manager.

On the left side of the VS Code screen, right click on the “custom” folder in the basic skill template and choose “Open in Terminal”:

In the bottom right of the VS Code screen is the Terminal panel. When you get to the command prompt:

Type in the commands “npm install i18next” and then “npm install i18next-sprintf-postprocessor“:

Once completed, you should have a couple of new folders in the “custom\node_modules” folder of your project:

Finally, the Brains of the Operation (index.js)

Since we just added the modules above to the project, let’s also add them to index.js, then I’ll discuss what’s in there and what we need to do.

Include the i18next Modules in index.js

At the top of the index.js file, we need to include the i18next modules. This is done by adding new constants for them below the Alexa constant, like so:

Each of the Handler functions handles one specific request from the user to Alexa. In this case, it the LaunchRequestHandler can handle requests with a type of “LaunchRequest”. When this Handler is fired, it builds a response that is sent back to the user. This response includes some speech (what Alexa will say), a reprompt (what she will say to remind the user what to do, and a Card (to be displayed on the Echo Show and other devices with screens).

The other Handler functions are set up to handle the different intents of the skill:

HelloWorldIntentHandler – The main intent handler

HelpIntentHandler – Handles the case where the user asks Alexa for help

CancelAndStopIntentHandler – Handles Alexa, Stop and Alexa, Cancel\

SessionEndedRequestHandler – Handles the final request sent to the skill when the session ends

ErrorHandler – Handles any error situations

Next, we get to the lines that export the various Handlers so that the Alexa SkillBuilder knows which functions to call:

Next, we will completely change the HelloWorldIntentHandler. We will do this in stages. First, we need to change the name of the Handler and its corresponding entry in the SkillBuilder at the bottom of the file, like so:

It turns out, that with the ASK in VS Code, deploying our Skill to Alexa and Amazon is quite easy. Open the Command Palette (View | Command Palette…). Type ASK. Select Deploy the skill.

Wait a moment while the ASK initializes, then select the default profile:

Then select “All”:

Now, it will try, and probably fail, to deploy. If it succeeds, great. If it fails, you probably need to change the working directory in the Terminal window at the bottom right of VS Code. This is done with the CD command, like so:

Once you’ve changed the directory to the one with your skill in it, press the up arrow on the keyboard a couple of times to get the “ask deploy” command back. Then press enter.

If all goes well, a few moments later, your skill will be deployed:

Now that your skill is deployed, we can switch over to the Alexa Developer Console to test it. If you still have your template project open from earlier, click “Your Skills” in the top left corner. Then you will see your newly deployed skill at the top of the list:

Click the Edit link on the far right. On the Build tab, you should see a little popup saying your build was successful:

Click on the Test tab. If it’s not enabled, enable testing for this skill:

In the Alexa Simulator, type in “start Roll Some Dice and roll 2 dice”. Press enter.

Alexa should say, “Hello World”. (Remember, we haven’t actually told her how to roll some dice yet.)

Notice the JSON Output from your Skill code in index.js:

And scroll down to see the Card visual that would be shown on the Echo Show:

That’s it for now. In the final post in this series, I will teach Alexa to roll dice with a modifier and report the results.

First, the invocation name. This is the name by which users will invoke your skill and it should be the same as the name of the skill you put in the skill manifest. In my case, in Part 2 I named the skill “Roll some dice”. The invocation name has to follow these rules:

Using the Alexa Developer Console to build the JSON for an Intent

1. Log in and click Create Skill. Enter the name “My Template”. Pick Custom as the type. On the next page, click Start from Scratch as the template. You should end up here:

2. Next to Intents, click Add. Intent name can only contain case-insensitive alphabetical characters and underscores, and it must begin and end with an alphabetic character. Numbers, spaces, or other special characters are not allowed. I will name my intent “RollSomeDiceIntent”:

3. Next, you enter the sample utterances. This is what the Alexa User needs to say to make your skill work. In my case, I have entered four utterances:

Notice how I used braces { } to create “slots” (or variables). These slots are placeholders for where the user can say a matching word. For example, “Roll 10 dice plus 1” matches the second utterance “roll {diceCount} dice {plusMinus}{modifier}“.

4. Now we need to define the slot types for the slots we named in the utterances. This is done at the bottom of the sample utterances page. Scroll down a bit and you will see this:

For the Slot Type, the first and third slot (diceCount and modifier) are both numeric, so pick AMAZON.Number from the drop down. You can type AMAZON.N and it will show AMAZON.Number as the only choice if you want to save on scrolling.

For the other slot, plusMinus, we will want to make a custom slot type where it only responds to “plus” and “minus”. Do this by clicking the Add button next to the Slot Type menu on the left side of the screen:

Give your new slot a name. Note: You cannot use a period in your name. Amazon can, but you can’t. So use an underscore. I will name my slot: OMWTM_PlusMinus:

Next, enter the words that are valid in your slot. For me, that is plus and minus. I will also add the synonyms add and subtract, just in case the user gets creative. Note: Make sure you click the plus sign next to the synonym so it actually gets saved into the slot. The slot ends up looking like this:

Finally, click on a the {plusMinus} slot in the left panel and select your custom slot type as the slot type:

Now we’ve defined the intent, with sample utterances and slots. Next, we need to get the JSON for the intent and copy it over to the en-US.json model file in VS Code. The JSON for your intent is in the Alexa console under the JSON Editor menu option on the left side:

We want ONLY the custom intent and the slots, so scroll down past the AMAZON intents and find the section that defines your intent:

Copy the highlighted section over to the model file in VS Code. Note: When you paste it in, you will be replacing the last braces of the intents section. If you don’t, your JSON file won’t have the right number of braces. I.e. Delete the HelloWorldIntent in its entirety and delete the extra square brace below it that ends the set of intents:

Also, the basic skill template inserts a blank types section at the top. Delete this too:

Now, back at the bottom of the file, paste in the copied text from the Alexa console:

What’s in the Basic Project?

The lambda folder contains your JavaScript files that are the code behind your skill. The node_modules folder contains the downloaded node modules you use. index.js is the main code file for your skill. package.json and package-lock.json are files that describe some of the technical aspects of your code, such as dependencies.

The models folder contains the various language versions of your Json skill description, including the intents and slots.

The skill.json file is the skill manifest and is where you describe the skill for your end users and the Amazon publishing process.

Where to Start?

In the image above, we’ll start at the bottom with the skill manifest, then the model, then a couple of minor changes to the package files, then we’ll write a couple of lines of JavaScript code and finally check the .ask\config.

The Skill Manifest (skill.json)

Open the skill.json file. Notice the areas I’ve highlighted in bold, red text. These are things we will change.

The “summary” entry should be a short description of your skill, for example:

"summary": "Roll some dice, optionally adding a modifier to each die",

The “examplePhrases”: section contains 3, and only 3, sample phrases. I’ll have two main intents: “Roll {diceCount} dice” and “Roll {diceCount} dice {plusMinus} {modifier}”, so I want to show those in the example phrases. For example:

The “name” entry should be the plain, human-readable, name of your skill that people see in the Alexa Skills Catalog. Note: This does not have to be unique in the Catalog. For example:

"name": "Roll Some Dice",

The “description” entry should describe your skill. This can be a paragraph or two and will also display in the Alexa Skills Catalog. Notice the description is all on one line. In VS Code, you can turn on Word Wrap (View | Toggle Word Wrap) to see the entire description on screen. For example:

"description": "Roll Some Dice will roll any number of standard dice (d 6's) and optionally add or subtract a modifier from each dice. Alexa will then tell you the total of the rolls plus or minus the modifiers. For example, you might say 'Roll 3 dice plus 1' and Alexa will roll 3 d 6, getting, say, 3, 4, and 6, then add 1 to each roll, getting 4, 5, and 7, and will tell you the total, 16.",

“testingInstructions” is something we’ll come back to later. This is the instructions for the Alexa Skill evaluators to follow to test your skill intents thoroughly. For now, I’ll leave it as is.

Lastly, the “category” entry is used to classify your skill in the Alexa Skills Catalog. For this skill, I will pick:

"category": "GAME_INFO_AND_ACCESSORY",

There are a couple of additional settings you will want to add to your skill, if appropriate. After the “manifest” setting, add this code:

So I finally decided to stop fighting it… Building Alexa Skills in C# is just difficult. With the newly released Visual Studio Code plugin for Alexa ( ) the language of choice is JavaScript. Ugh. But, it turns out that Google is still my friend (even though the Google Home is a horrible platform for voice skill development). A quick search turned up all sorts of free JavaScript training. A few hours of interaction later and I’m a pro beginning to be barely capable in JavaScript. So, what’s a Microsoft Developer to do to code an Alexa Skill?

AWS Lambda Credentials

For this example, I’m going to Attach existing policies directly and select Administrator Access, but this is NOT best practice. (I should create a user group that has the specific policies this account needs, but that’s a different blog entry.) Click Next.

Click Create User.

Download the .csv. Do this.

IMPORTANT: This is the ONLY time you can Download the .csv, so do it now.

Starting the Alexa Skill

Enter: ASK in the palette and choose the “ASK: Create a basic skill package” option.

It should come back with an option to select your AWS profile. Choose the profile you created above. This profile needs to be linked to an IAM user who has the right to publish Lambda functions. (Which is why I cheated above and gave it AdministratorAccess.)

Now it will ask you to enter a skill name. I’ll be calling mine “OMWTM Roll A Dice”.

ASK will then create and run a command in the Terminal window at the bottom right of VS Code:

Once it’s finished, VS Code will open a folder with your basic skill defined:

In the next blog entry, we’ll go through the basic skill definition and customize it.

In Step 3, we created the Lambda function that will provide the functionality of the Alexa Skill we defined in Step 1, we wired everything up and then we tested our Skill. So far so good. However, that’s an awful long way round to test the Skill Request and Response. It would be nice if we could set up a unit test project and unit test our Lambda function without having to deploy it.

It turns out, we can.

When we created the Lambda function project in Step 3, we selected the AWS Lambda Project with Tests template. So we already have a Tests project and a stubbed out xunit test. (Note: Because we are using the .Net Core for our Lambda function, the normal Microsoft Unit Testing Framework doesn’t work (because it uses the full .Net platform) and so the AWS template uses xunit.)

The tricky part of Unit Testing our Lambda function is that we need to test them FunctionHandler method, which takes a SkillRequest and a Context as parameters: