How To Code An Alexa Skill! 🤖
Published: 2020-08-30 14:47:11

# 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](https://www.amazon.com/ap/signin?openid.pape.preferred_auth_policies=Singlefactor&clientContext=135-3176288-4481625&openid.pape.max_auth_age=7200&openid.return_to=https%3A%2F%2Fdeveloper.amazon.com%2Falexa%2Fconsole%2Fask&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.assoc_handle=amzn_dante_us&openid.mode=checkid_setup&marketPlaceId=ATVPDKIKX0DER&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&). Then when you've done that go to [https://developer.amazon.com/alexa/console/ask](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](https://i.imgur.com/gXwuf3X.png)


Give your skill the name Logomaniac Pursuit or some equally brilliant name:
![Naming your Alexa Skill](https://i.imgur.com/qA3MWaX.png)


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](https://i.imgur.com/m3u3Ygy.png)


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](https://i.imgur.com/gBd4trm.png)


Scroll up and click **Create skill**!


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


![Hello world skill](https://i.imgur.com/PBmMpdh.png)


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](https://i.imgur.com/Xgrmrzt.png)


"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](https://i.imgur.com/8MoG5Eg.png)


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](https://i.imgur.com/IJkPO4R.png)


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](https://i.imgur.com/DxySZ1F.png)


## 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  &mdash; the code bit &mdash; 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](https://i.imgur.com/v6M31QM.png)

### 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](https://i.imgur.com/Wgt6cwx.png)

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](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](https://i.imgur.com/q9Lfx5M.png)

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](https://developer.amazon.com/en-US/docs/alexa/custom-skills/slot-type-reference.html). 

Add a date slot.

![Alexa skill slot type](https://i.imgur.com/mPVKYcw.png)

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

![New utterances with the slot values](https://i.imgur.com/yLKK1zZ.png)

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](https://i.imgur.com/TFo9ai2.png)

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](https://codeheir.com)



## This blog is sponsored by <a href="https://www.codecanvases.com">Code Canvases</a>

Make your room come alive  with the coolest programming/coding canvases on the market.<a href="https://www.w3schools.com"> codecanvases.com</a> 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/)](https://cdn.shopify.com/s/files/1/0311/0151/7955/products/jqbr8djyof6ktl8qopmkpvy4_480x480.png?v=1585483987)