# An Alexa Skill in Javascript – Part 4

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.

{
"name": "hello-world",
"version": "1.0.0",
"description": "",
"main": "index.js",

I’m going to simply replace “hello-world” with “roll-some-dice” and save and close the file.

{
"name": "roll-some-dice",
"version": "1.0.0",
"description": "",
"main": "index.js",

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:

const Alexa = require('ask-sdk-core');
const i18n = require('i18next');
const sprintf = require('i18next-sprintf-postprocessor');

### A Brief Tour of index.js

After the constants declared at the top of the file to include the required modules, there are several “Handler” functions.  The first is the LaunchRequestHandler:

const LaunchRequestHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
},
handle(handlerInput) {
const speechText = 'Welcome to the Alexa Skills Kit, you can say hello!';
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.withSimpleCard('Hello World', speechText)
.getResponse();
},
};

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:

const skillBuilder = Alexa.SkillBuilders.custom();
exports.handler = skillBuilder
.addRequestHandlers(
LaunchRequestHandler,
HelloWorldIntentHandler,
HelpIntentHandler,
CancelAndStopIntentHandler,
SessionEndedRequestHandler
)
.addErrorHandlers(ErrorHandler)
.lambda();

### What We Need to Change

First, we will change the LaunchRequestHandler, as shown in bold, blue text below:

const LaunchRequestHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
},
handle(handlerInput) {
const speechText = 'Welcome to Roll Some Dice.  You can say, Roll 2 Dice, or Roll 4 Dice plus 1!';
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.withSimpleCard('Roll Some Dice', speechText)
.getResponse();
},
};

Next, we will fix the Card lines in all the other intents so that this:

.withSimpleCard('Hello World', speechText)

becomes:

.withSimpleCard('Roll Some Dice', speechText)

Next, we will change the Help Speech Text in the HelpIntentHandler to:

const speechText = 'You can say roll 2 dice, roll 3 dice plus 1, roll 6 dice minus 1 or any number of dice with any modifier.';

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:

const RollSomeDiceIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'RollSomeDiceIntent';
},
handle(handlerInput) {
var speechText = 'Hello World!';
return handlerInput.responseBuilder
.speak(speechText)
.withSimpleCard('Roll Some Dice', speechText)
.getResponse();
},
};

...

const skillBuilder = Alexa.SkillBuilders.custom();
exports.handler = skillBuilder
.addRequestHandlers(
LaunchRequestHandler,
RollSomeDiceIntentHandler,
HelpIntentHandler,
CancelAndStopIntentHandler,
SessionEndedRequestHandler
)
.addErrorHandlers(ErrorHandler)
.lambda();

Now, we have a Handler for our Intent that doesn’t actually do what it needs to do.
But, we do have a Handler.  At this point, we can deploy and test our Skill.

## Deploying Your Skill to Alexa Developer Console and Amazon Web Services

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.

# An Alexa Skill in Javascript – Part 3

## The Skill Model (en-US.json)

Open the en-US.json file in the models folder.  Notice the areas I’ve highlighted in bold, red text.  These are things we will change.

{
"interactionModel": {
"languageModel": {
"invocationName": "greeter",
"types": [
],
"intents": [
{
"name": "AMAZON.CancelIntent",
"samples": [
]
},
{
"name": "AMAZON.HelpIntent",
"samples": [
]
},
{
"name": "AMAZON.StopIntent",
"samples": [
]
},
{
"name": "HelloWorldIntent",
"slots": [
],
"samples": [
"hello",
"say hello",
"say hello world"
]
}
]
}
}
}

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:

1. Your invocation name should be two or more words
2. Can contain only lower-case alphabetic characters, spaces between words, possessive apostrophes (for example, “sam’s science trivia”), or periods used in abbreviations (for example, “a. b. c.”).
3. Other characters like numbers must be spelled out. For example, “twenty one”.
4. Invocation names cannot contain any of the Alexa skill launch phrases.

I will enter the invocation name as “roll some dice”.

"invocationName": "roll some dice",

There are three AMAZON intents in the basic skill template.  Those are fine the way they are and should not be modified.

The meat of the skill model is your intent.  In the basic skill template, this is the HelloWorldIntent.  We will change this.

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

The easiest way to get the correct syntax for the Skill Intent is to use the Alexa Developer Console.

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:

1. 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:

The finished intent model should look like this:

{
"interactionModel": {
"languageModel": {
"invocationName": "roll some dice",
"intents": [{
"name": "AMAZON.CancelIntent",
"samples": [
]
},
{
"name": "AMAZON.HelpIntent",
"samples": [

]
},
{
"name": "AMAZON.StopIntent",
"samples": [

]
},
{
"name": "RollSomeDiceIntent",
"slots": [{
"name": "diceCount",
"type": "AMAZON.NUMBER"
},
{
"name": "plusMinus",
"type": "OMWTM_PlusMinus"
},
{
"name": "modifier",
"type": "AMAZON.NUMBER"
}
],
"samples": [
"roll a die {plusMinus} {modifier}",
"roll {diceCount} dice {plusMinus} {modifier}",
"roll {diceCount} dice",
"roll a die"
]
}
],
"types": [{
"name": "OMWTM_PlusMinus",
"values": [{
"name": {
"value": "minus",
"synonyms": [
"subtract"
]
}
},
{
"name": {
"value": "plus",
"synonyms": [
"add"
]
}
}
]
}]
}
}
}

That’s it for now.  In the next post, we’ll start looking at the Lambda function files and what needs to be changed there to get this skill working.

Bye for now.

# An Alexa Skill in JavaScript – Part 2

Now that we have the tools and a basic project, let’s see what the Alexa Skills Kit (ASK) has created for us.

# What’s in the Basic Project?

The ASK Config file contains the info the ASK needs to publish your skill.

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.

{
"manifest": {
"publishingInformation": {
"locales": {
"en-US": {
"summary": "Sample Short Description",
"examplePhrases": [
"Alexa open hello world",
"Alexa tell hello world hello",
"Alexa ask hello world say hello"
],
"name": "omwtm-roll-a-dice",
"description": "Sample Full Description"
}
},
"isAvailableWorldwide": true,
"testingInstructions": "Sample Testing Instructions.",
"category": "EDUCATION_AND_REFERENCE",
"distributionCountries": []
},
"apis": {
"custom": {
"endpoint": {
"sourceDir": "lambda/custom"
}
}
},
"manifestVersion": "1.0"
}
}

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:

"examplePhrases": [
"Alexa open roll some dice",
"Alexa tell roll some dice to roll 2 dice",
"Alexa ask roll some dice to roll 3 dice plus 1"
],

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:

"manifestVersion": "1.0",
"permissions": [],
"privacyAndCompliance": {
"allowsPurchases": false,
"isExportCompliant": true,
"containsAds": false,
"isChildDirected": false,
"usesPersonalInfo": false
}

So, the completed file looks like this for now:

{
"manifest": {
"publishingInformation": {
"locales": {
"en-US": {
"summary": "Roll some dice, optionally adding a modifier to each die",
"examplePhrases": [
"Alexa open roll some dice",
"Alexa tell roll some dice to roll 2 dice",
"Alexa ask roll some dice to roll 3 dice plus 1"
],
"name": "Roll Some Dice",
"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."
}
},
"isAvailableWorldwide": true,
"testingInstructions": "Sample Testing Instructions.",
"category": "GAME_INFO_AND_ACCESSORY",
"distributionCountries": []
},
"apis": {
"custom": {
"endpoint": {
"sourceDir": "lambda/custom"
}
}
},
"manifestVersion": "1.0",
"permissions": [],
"privacyAndCompliance": {
"allowsPurchases": false,
"isExportCompliant": true,
"containsAds": false,
"isChildDirected": false,
"usesPersonalInfo": false
}
}
}

Next up, the skill model, where you define your intents and slots.

Bye for now.

# An Alexa Skill in JavaScript – Part 1

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?

## Getting the Tools

Step 1 – From the command line (Start | cmd in Windows), run npm to install the ASK CLI:

npm install -g ask-cli

This command takes 2-5 minutes to run and doesn’t appear to be doing anything while it’s running.

TIP:  It’s a good idea to run that npm command every month or so to get the latest version of the ASK-CLI.  It is updated quite frequently.

Step 2 – Install Git, if you haven’t already.

Step 2 – Install Visual Studio Code if you haven’t already.  (I recommend the 64-bit User version for Windows developers.)

Step 3 – In VS Code, select the Help | Welcome menu.  On the right-hand side, under Customize, under Tools and languages, install support for JavaScript.

Step 4 – In VS Code, select the View | Extensions menu.  Search for Alexa Skills Kit (currently – 09/15/18 – in beta).  Install it.

I think that’s all I had to do to get the tools.

## Configuring for Alexa Skill Development

### AWS Lambda Credentials

Since we will be using an AWS Lambda function as the back-end for our skill, we need to set up the credentials in AWS IAM.

Add a User.  Give the user a name.  Select Programmatic access.  Click Next.

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.

Click Close.

### Initialize ASK CLI

In VS Code, view the Command Palette (Ctrl-Shift-P) or select the View | Command Palette menu.  Enter:  ASK in the palette and choose the “ASK: Initialize / Configure the ASK CLI” option.

Accept the default profile name.  Sign in to Amazon in the browser provided USING THE ACCOUNT YOU JUST CREATED ABOVE.  It should say “Profile [default] initialized successfully.”

If not, go here for assistance.

## Starting the Alexa Skill

Create a folder for Alexa Skills.

View the Command Palette (Ctrl-Shift-P) or select the View | Command Palette menu.

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.

Bye for now.