Scaffolding an Alexa Skills project is fairly straightfoward if you have experience with the Node.js ecosystem and JavaScript. However once you have the skeleton it's not completely clear how all of the parts relate.
This post goes through building a Hello world Alexa skill in depth, so it's more obvious how the various parts fit together.
Before we get started I should note that Phillipsoft does Alexa consulting. If your company wants to enter the world of voice assistants or IoT, we can help. See the consulting page for more information.
Prerequisites
You can build Alexa Skills using any of the languages supported by AWS Lambda, but most documentation you find online will be for JavaScript, which means Node.js. If you don't already have it, download Node.js.
Once Node.js is installed you can verify that you have a recent enough version with the following command. We recommend at least Node.js 10.
node -v
You'll need the ask-cli which is used for scaffolding new projects and deploying your skills to the cloud. Install with the following:
npm install -g ask-cli
Once you've installed this you can verify that the ask
command is available:
ask -v
And that's it, you have all of the required tools to build an Alexa skill.
Creating the project
To scaffold a new project the ask new
command is used. Run the following command:
ask new --skill-name alexa-hello-world
Which will ask you a few questions. For the runtime select Node.js. For the template select Hello World.
This will create a alexa-hello-world/
folder in your current directory. If you cd into the directory and open it in a text editor you can see some interesting files.
cd alexa-hello-world
You'll see the following directory structure:
.ask/
.github/
hooks/
instructions/
lambda/
├── custom/
│ ├── index.js
│ ├── package.json
│ └── utils.js
models/
├── en-US.json
└── ...
skill.json
The important parts here are:
- .ask/config: Configuration for the ask-cli. When you run a deployment for the first time this file will update. Most likely you'll never need to touch this file.
- hooks/: A folder that contains scripts that are run before and after a deployment. It's unlikely that you'll need to ever modify these, but if you do here's where they are.
- lambda/custom/: This is the JavaScript source for the Alexa skill and where you'll spend most of your time. If you need to add a dependency from npm, install it in this folder. The
index.js
file is the entry point, and we'll go over it in another section.
- models/: The models are mappings to tell Alexa which code to run given certain circumstances. This will be covered more below.
- skill.json: This is the root configuration file for the skill. It provides the name of your skill, a description that will show up in the skills store, and lists the supported languages.
Internationalization
One of the first things you might notice when looking at the various files is that the skill is set up to work in multiple languages. You'll see this in the skill.json
file in the manifest.publishingInformation.locales
section:
"en-US": {
"name": "alexa-hello-world",
"summary": "Sample Short Description",
"description": "Sample Full Description",
"examplePhrases": [
"Alexa open hello world",
"hello",
"help"
],
"keywords": []
},
"en-GB": {
"name": "alexa-hello-world",
"summary": "Sample Short Description",
"description": "Sample Full Description",
"examplePhrases": [
"Alexa open hello world",
"hello",
"help"
],
"keywords": []
},
...
You'll also see this in lambda/custom/languageStrings.js
which is a mapping of intents to the message to reply with. This is set up to use by an interceptor in lamda/custom/index.js
:
const LocalisationRequestInterceptor = {
process(handlerInput) {
i18n.init({
lng: Alexa.getLocale(handlerInput.requestEnvelope),
resources: languageStrings
}).then((t) => {
handlerInput.t = (...args) => t(...args);
});
}
};
This is a function that runs before the intents receive the command. It can be used to set up functionality that all intents will need to use. In this case it sets up the handlerInput.t
function.
While this is really useful, adding internationalization to your first app can be overwhelming when trying to learn a new platform. You can safely ignore this for now, but just know that this Hello world template is a good starter for when you are building an internationalized skill.
Intents
The core of how Alexa skills work is through intents. Inside of the models/
folder there are JSON files for each language you support. Open models/en-US.json
and take a look. They look like this:
{
"name": "AMAZON.StopIntent",
"samples": []
},
Each intent has a name and an array of samples. A sample is a phrase in the given language that should prompt the intent to run. Intents named AMAZON.
are special intents that Alexa always recognizes. They don't need samples. If the user says Alexa, stop, the AMAZON.StopIntent
will run.
You can find the intents in lambda/custom/index.js
. For example the StopIntent is this:
const CancelAndStopIntentHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& (Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.CancelIntent'
|| Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.StopIntent');
},
handle(handlerInput) {
const speakOutput = handlerInput.t('GOODBYE_MSG');
return handlerInput.responseBuilder
.speak(speakOutput)
.getResponse();
}
};
There are two methods you must implement:
canHandle
- Should return true
if the intent can handle the input. In this case you see that this intent handler handlers both AMAZON.StopIntent
and AMAZON.CancelIntent
intents.
handle
- This is the method that responds to the input. In this case its using the handlerInput.t
to do translation. This gives you a string. You could also directly do handlerInput.responseBuilder.speak('Hello world').getResponse()
here.
This handler will speak the GOODBYE_MSG
which is Goodbye! in english (you can find this in the languageStrings.js file).
The HelloWorldIntentHandler
is another good handler to look at in the index.js file. This is the one that handles when someone tells Alexa, Alexa, say hello, or any of the phrases from the models file.
Deploying and Testing
To deploy to the Alexa cloud you first need an Alexa developer account, when you can get from the Alexa Developer Console. Then you can deploy with:
ask deploy
It might take a minute or two the first time. Once complete go to the Alex Developer Console and click on your skill. At the top of the page click the Test tab. You should see a screen that looks like this:
Click and hold the microphone and tell it "say Hello" and it should respond with the message from the languageStrings.js file. You can try any of the intents this way.
You can also test on your own Alexa if it is registered to the same account that you used for the Alexa Developer account.
Conclusion
And that's it! Getting started with Alexa skills development is relatively simple thanks to the tools like ask
and the Developer Console that Amazon built. There's still some learning curve to really get how to build a robust skill, but for a weekend project, just to get your feet wet everything you need is created from this template.
This post is the first in a series on building for Alexa. Stay tuned for more on topics such as:
- Building Voice User Interfaces (VUIs) and how they differ from other types of UIs.
- Building for hardware with the Alexa Connect Kit.
- And more!
And again, if your company needs experienced consultants for Alexa or any IoT project, please contact me and let's chat.