loading...
Cover image for How To Code An Alexa Skill!

How To Code An Alexa Skill!

lukegarrigan profile image Luke Garrigan 9 min read

Introduction

In this blog, I'll take you through the fundamentals of coding an Alexa skill to hopefully give you the foundation you'll need to create anything!

Let's dive right into it.

What is an Alexa skill

Alexa skills are just voice-driven apps for Alexa, that's it.

What we'll be creating

In this blog we'll be creating an Alexa skill that gives us the word of the day Alexa already has word of the day built-in but it'll be a good exercise. Our Alexa skill will be called Logomaniac Pursuit, logomaniac meaning one who is obsessed with words, clever, I know.

A bit of terminology

In natural language and more specifically Alexa development, there are a few keywords that crop up that you'll need to understand.

  • Utterance: what the user says to Alexa
  • Invocation word: the word that boots up your Alexa skill, for example a user might say something like "Alexa open Logomaniac Pursuit" to open our skill.
  • Intent: An intent represents an action that'll fulfill a user's request.
  • Slot: input values provided in a user's request. For example "Alexa, what was the word of the day of the ninth of august", We could use the ninth of august as a date slot (This will all become clear when we start developing!)

Getting started

Signing up

The first thing you'll need to do is create an Alexa development account. Then when you've done that go to https://developer.amazon.com/alexa/console/ask which is the main development console where you'll see all your skills.

Creating a skill

Let's create a skill, in the development console click the Create Skill button Create a skill

Give your skill the name Logomaniac Pursuit or some equally brilliant name:
Naming your Alexa Skill

Our skill is going to be a custom skill, the other options provide prebuilt development kits for Smart Home, Video, and Flash briefing but this won't be covered in this blog, so choose custom!

Choosing the custom skill option

Next, we need to choose what backend we're going to use, in this tutorial we're going to be using the Alexa-host (Node.js) option, this way we don't need to worry about hosting and we can also use the pretty brilliant code editor within the Alexa development area.

Choosing node.js hosted

Scroll up and click Create skill!

Next, choose the basic Hello World skill, we'll modify this to create our skill!

Hello world skill

Hit continue with template.

Setting an invocation name

Go to Build | Invocation (on the left panel)

As explained earlier the invocation name is the word that the user will include in their request to open the skill.

Changing the invocation name to logomaniac pursuit

"Alexa, open logomaniac pursuit" as an example.

Hit Save Model then Build Model, once built we should be able to invoke our skill with that invocation name, let's try it.

Testing your skill

Go to Test and set the testing for your skill to Development
Setting the Alexa skill testing to development

This testing area is where we will come to try out our skill, you can either type out the text yourself within the text box or you can talk to it using your microphone. The wake word is not required for testing (We don't need to say Alexa).

Let's give this a go:

Saying to Alexa open logomaniac pursuit

Alexa returns the default Hello World response that is prebuilt into the template we chose, but nonetheless it is using our invocation name, so that's a win!

The code editor

Go to the Code section, here you'll see the code that was generated from the template we chose. You'll notice that each object is split up like the following:

const LaunchRequestHandler = {
    canHandle(handlerInput) {
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'LaunchRequest';
    },
    handle(handlerInput) {
        const speakOutput = 'Welcome, you can say Hello or Help. Which would you like to try?';

        return handlerInput.responseBuilder
            .speak(speakOutput)
            .reprompt(speakOutput)
            .getResponse();
    }
};

The code in this example is the LaunchRequestHandler which is what gets called when the user invokes our skill.

Each object is a handler that is split into two functions:

  • canHandle() is called first, this checks to see whether the request matches the condition of the handler
  • handle() does the actual handling of the request, which ultimately decides what to say back to the user. We build up a response using the responseBuilder the speak() function is the message that gets played to the user. If the skill is supposed to listen for the user's response then we will use the reprompt() function.

Let's change the speakOutput line to our own phrase:

const speakOutput = 'Welcome, if you would like to hear the word of the day or the word of the day for a previous date, just ask';

And let's also add a reprompt phrase:

const repromptOutput = 'If you would like to hear the word of the day or the word of the day for a previous date, just ask';
Remember to change the argument of the reprompt() function to repromptOutput. The handle code now should look like:

    handle(handlerInput) {
        const speakOutput = 'Welcome, if you would like to hear the word of the day or the word of the day for a previous date, just ask';
        const repromptOutput = 'If you would like to hear the word of the day or the word of the day for a previous date, just ask';

        return handlerInput.responseBuilder
            .speak(speakOutput)
            .reprompt(repromptOutput)
            .getResponse();
    }

Hit Save then Deploy.

You can then go to the Test section and see whether the new phrase is being returned when you invoke your skill!

Updated phrase

Adding a new intent

When building an Alexa skill it is good to think of it as having a front-end and a back-end, the front-end is the part that matches the user's utterances to intents and the back-end the code bit decides how to handle the user's intent.

Go to Build | Intents, you'll notice that a few Intents already exist, any prefixed with AMAZON are required and should not be deleted, you'll also notice that a HelloWorldIntent exists, which was created with the template, this is no longer needed and can be deleted.

Click Add Intent.
It is good practice to keep intents with no spaces and the first letter of words capitalised, also appending the word Intent at the end seems to be commonplace.

WordOfTheDayIntent

Adding utterances

In order for an Intent to be invoked the user must say something that you specify, this is where you specify what the user has to say.

Adding utterances to an Alexa skill

So for my WordOfTheDayIntent to be invoked, the user must say a phrase that more or less matches one of the utterances I've provided, Alexa does the heavy, natural language lifting here, it'll build a model and if the user's utterance is close enough, it'll make the decision to invoke my intent.

Click Save Model then Build Model.

Handling an intent in code

We now have an intent, but we don't actually return anything when that intent is invoked, we need to do that in code!

Go back to the Code section.

In the code there is a HelloWorldIntentHandler

https://i.imgur.com/Gj5iLfp.png

Let's modify this for our intent.
Change the name of the handler to WordOfTheDayIntentHandler. Scroll down to the bottom and add WordOfTheDayIntentHandler to the exports.handler(You can also get rid of the HelloWorldIntentHandler we're replacing). Your code should look something like this:

exports.handler = Alexa.SkillBuilders.custom()
    .addRequestHandlers(
        LaunchRequestHandler,
        WordOfTheDayIntentHandler,
        HelpIntentHandler,
        CancelAndStopIntentHandler,
        FallbackIntentHandler,
        SessionEndedRequestHandler,
        IntentReflectorHandler)
    .addErrorHandlers(
        ErrorHandler)
    .withCustomUserAgent('sample/hello-world/v1.2')
    .lambda();

Next, back to the handler, let's modify this so that it uses our intent name. Change HelloWorldIntent to WordOfTheDayIntent, this is saying now that when the canhandle() function gets called it'll check to see whether the intent name that's been invoked is WordOfTheDayIntent and if it is, it'll call the handle() function.

Let's add our word of the day! In this example I'll just hardcode the word of the day, but here you might want to call an API to get some information.

Your code should look something like this:

const WordOfTheDayIntentHandler = {
    canHandle(handlerInput) {
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
            && Alexa.getIntentName(handlerInput.requestEnvelope) === 'WordOfTheDayIntent';
    },
    handle(handlerInput) {
        const speakOutput = 'The word of the day is countenance. countenance is a persons facial expression. If you would like to hear the word of the day for a previous date, just ask';
        const speakReprompt = 'If you would like to hear the word of the day for a previous date, just ask';

        return handlerInput.responseBuilder
            .speak(speakOutput)
            .reprompt(speakReprompt)
            .getResponse();
    }
};

Testing an intent

Next, let's go back to Test and see if we can get our word of the day!

Getting the word of the day in testing an Alexa skill

Bloody brilliant!

Slots

As explained earlier slots are input values provided in a user's request. As in our example, we want to have a slot so that we can gather the date the user has specified for retrieving the word of the day for that date, example:
"Alexa, what was the word of the day on the ninth of august".

We will be modifying our WordOfTheDayIntent for this, we could potentially create a whole new intent for previous words of the day, but I think it fits nicely into this intent. So basically, if the user provides the date slot, we will return them the word of the day for that date!

Adding a slot

Go to Build | Intents | WordOfTheDayIntent next let's add some slots and new utterances. To add a slot you can just click a word in one of your utterances that will be replaced with the slot, or you can scroll down and click add new slot.

Alexa has a tonne of built-in slot types, in our example we're going to use the Amazon.Date slot type. For more information on slot types.

Add a date slot.

Alexa skill slot type

Here's an example of what your new utterances with the slot will look like!

New utterances with the slot values

Hit Save Model then Build Model

Handling slots in code

Now that we can gather information from a slot we can handle this in our code, so if a user specifies a date for the word of the day, we can call a different API or perform some other function.

Go back to our code editor and back to our WordOfTheDayIntentHandler.

We can retrieve our slot value using the following code:

const date = handlerInput.requestEnvelope.request.intent.slots.date.value;

we can do a check to see if that date has been filled and if so we can perform some other action, in this case, I'm simply going to change the reply to the user. So the final code will look like this:

const WordOfTheDayIntentHandler = {
    canHandle(handlerInput) {
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
            && Alexa.getIntentName(handlerInput.requestEnvelope) === 'WordOfTheDayIntent';
    },
    handle(handlerInput) {
        let speakOutput = 'The word of the day is countenance. countenance is a persons facial expression. If you would like to hear the word of the day for a previous date, just ask';
        const speakReprompt = 'If you would like to hear the word of the day for a previous date, just ask';

        const day = handlerInput.requestEnvelope.request.intent.slots.date.value;

        if (date) {
            speakOutput = `The word of the day on ${date} was clinomania. clinomania is an excessive desire to remain in bed`;
        }

        return handlerInput.responseBuilder
            .speak(speakOutput)
            .reprompt(speakReprompt)
            .getResponse();
    }
};


So if the user has specified a date, then we will output the word of the day being clinomania.

Testing our slot

Let's go back to the test environment and see if we can get the word of the day for a specific date!

Image of successfully using slots in Alexa skill

Awesome!

Conclusion

And that's pretty much it, we've created our own Intents, Utterances and Slots and coded to handle them!

Hopefully this blog has put you in a position where you feel confident to have a crack at your own Alexa skill, I'd love to hear of some skill ideas you guys have in the comments, let me know if this blog has helped!

codeheir.com

If you happen to enjoy my writing, I'd bloody love it if you'd check out my personal programming blogging site, I blog a lot more on there!
https://codeheir.com

This blog is sponsored by Code Canvases

Make your room come alive with the coolest programming/coding canvases on the market. codecanvases.com is the number 1 seller for programming prints with 100% exclusively designed canvases. Get them now whilst they're 20% off!!

[https://codecanvases.com/](https://codecanvases.com/)

Discussion

pic
Editor guide