Alexa goes Azure: How to write a skill with Azure Functions
Tags: serverless, alexa, azure, skill
Published: 2019-09-09 12:38:44

> This article is part of [#ServerlessSeptember](https://dev.to/azure/serverless-september-content-collection-2fhb). You'll find other helpful articles, detailed tutorials, and videos in this all-things-Serverless content collection. New articles are published every day — that's right, every day — from community members and cloud advocates in the month of September.

> Find out more about how Microsoft Azure enables your Serverless functions at [https://docs.microsoft.com/azure/azure-functions/](https://docs.microsoft.com/azure/azure-functions/?WT.mc_id=servsept_devto-blog-cxa).


# Introduction

In this article I want to show you how easy it is to extend your Alexa device with custom functionality by writing different skills as Azure Functions.

### Alexa?!

But first let's talk about Alexa. Alexa is a virtual assistant developed by Amazon, first used in the Amazon Echo and the Amazon Echo Dot smart speakers. It is capable of voice interaction, music playback, making to-do lists, setting alarms, streaming podcasts, playing audiobooks, and providing weather, traffic, sports, and other real-time information, such as news. But you can easily extend the basic features by writing your custom skills with your own functionality.


# Wording

I want to give a brief introduction into the wording so that everybody is able to follow the code samples later.

### Skill

A *skill* is a voice experience, which can be developed by third parties. It extends the available functions and can be activated or deactived via voice commands or companion apps. From a technical point of view a skill is an exchange on JSON.


### Invocation Name

An *invocation name* is a word or a phrase to trigger a skill. It is the equivalent of an app icon and usually matches the skill's name.


### Intent

What a user is trying to accomplish is called *intent*. Here the developer is able to define the functionality and a skill can have many different intents.


### Utterances

*Utterances* are specific phrases that people will use when making a request. They have to be coded to tell Alexa what to expect. Sometimes this means typing out dozens of very slight variations.


### Slot

A *slot* is a variable that relates to an intent. Amazon provides a number of built in slot types, like dates, numbers, durations or time. A developer can create custom slots for variables which are specific for the own skill.


# First Alexa Skill

Each skill consists of two parts. The meta information we need to provide in the [Developer Console of Amazon](https://developer.amazon.com) and the business logic we will host on Azure. Let's start with the business logic.

Open Visual Studio and create a new Azure Functions project. Select a name for example *AlexaSkillAzureFunctions* and a location to store the files. Be sure that *Azure Functions v2 (.NET Core)* is selected and select *Empty* as application. 

![Create a new Azure Functions Application](https://thepracticaldev.s3.amazonaws.com/i/pzksuhqhlo8bf3a6nh6a.png)

Now let's create our first Azure Function. Select as **trigger** *Http Trigger* and as **Authorization level** *Anonymous*.

![New Azure Function](https://thepracticaldev.s3.amazonaws.com/i/zjjvxpb8aaebou2148jn.png)

Remove the whole content of the *Run* method, because we will create our own content. Also remove the **get** from the *HttpTrigger* attribute and insert *alexa/helloworld* as **Route**. Last but not least change the return type to *object*.

```csharp
[FunctionName("AlexaHelloWorld")]
public static object Run(
  [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "alexa/helloworld")] 
  HttpRequest req)
{
            
}
```

Now we want to return a valid skill response by creating an anonymous object in C# containing our response object.

```csharp
[FunctionName("AlexaHelloWorld")]
public static object Run(
  [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "alexa/helloworld")] 
  HttpRequest req)
{
  return new
  {
    version = "1.0",
    response = new
    {
      outputSpeech = new
      {
        type = "PlainText",
        text = "Hello World from an Azure Function!"
      },
      shouldEndSession = true
    }
  };            
}
```

In this sample we will return a speech output. So Alexa will say the provided sentence.

Now we are ready to publish the Azure Function to Azure. Let's do this by clicking *Publish* in the context menu of our project within Visual Studio.

![Upload Azure Function to Azure](https://thepracticaldev.s3.amazonaws.com/i/0tcp8dze6ag2cwujh7cn.png)

The first part containing the business logic is ready and we need to provide some meta information for our skill. The meta information are provided in the [Developer Console of Amazon](https://developer.amazon.com). You can login with your normal Amazon account or if you want you can create a new account.

![Amazon Developer Console](https://thepracticaldev.s3.amazonaws.com/i/3fj7wu7u0cgq6td6ooy2.png)

Here we slect *Alexa* from the navigation bar and than *Alexa Skill Kit* from the popup menu to navigate to the Skill Dashboard.

![Dashboard: Alexa Skill Kit](https://thepracticaldev.s3.amazonaws.com/i/wn7i8rpuhj3cdndqkk1j.png)

From this dashboard we are able to create a new skill by clicking the blue button **Create Skill** in the top right corner. We need to provide a *name*, the *default language*, a *model* and a *hosting option*.

For our *Hello World Skill* we will use **Hello World**, **English (US)**, **Custom** and **Provision your own**.

![New Alexa Skill](https://thepracticaldev.s3.amazonaws.com/i/41lakoc79210it55dwp1.png)

In the next step we can select a template. We will select **Start from scratch**, because we will set up everything on our own.

![Template for Alexa Skill](https://thepracticaldev.s3.amazonaws.com/i/pjo866vbwpwmh1iw8vjg.png)

Now our skill is already created but not functional. As you can see there is a *Skill builder checklist* and we need to check all of the points on the list.

![Skill Dashboard](https://thepracticaldev.s3.amazonaws.com/i/54ea6t5jabq252uj0rm1.png)

Let's start with the **Invocation Name**. As you might remeber this is the phrase to start our skill. It is automatically set to the selected name of the skill, which makes sense. So the user is able to invoke our skill by saying **Alexa, open Hello World**.

The next step is **Intents, Samples, and Slots**. Due to the fact that we always return the same response we can skip this step. But currently there is an issue with the dashboard. So we open in the left pane *AMAZON.CancelIntent* and insert *Cancel* as **Sample Utterance** and confirm by clicking **Save Model**.

![Sample Utterances](https://thepracticaldev.s3.amazonaws.com/i/9ghtnwzh2cbt34bth3hi.png)

Last but not least we need to update the **Endpoint**. Select **HTTPS** and insert your *Azure Function* endpoint. From the dropdown select the value **My development endpoint is a sub-domain that has a wildcard certificate from a certificate authority**.

![Skill Endpoint](https://thepracticaldev.s3.amazonaws.com/i/tc9roxh38yd75cen9wlz.png)

Confirm the selection by clicking **Save Endpoints** and click once again on **Invocation**. Now click the **Build Model** button to start the building process.

![Building your Skill](https://thepracticaldev.s3.amazonaws.com/i/089lk6okqtvaijpr78u7.png)

Now we are ready to test our skill. If you have an Echo device registered with the same mail address for the Developer Console you can test your skill directly on the device otherwise use the **Test** option from the dashboard. In both cases you need to enable testing by selecting **Development** from the drop down menu.

You can either use a microphone to communicate with your skill or you can chat with it. In my case I'm using the chat functionality and insert *open hello world* to start our new skill.

![Testing your Skill](https://thepracticaldev.s3.amazonaws.com/i/rebyheabdryysuoq5p1o.png)

Congratulations you've developed your first Alexa Skill using Azure Functions. 


# Working with Slots

I will share another skill with you, showing how you can work with slots. 

I'm writing my skills in C# and luckily there is a NuGet package to handle requests and responses easily. So let's add [Alexa.NET](https://www.nuget.org/packages/Alexa.NET/) to our Azure Function project.

![NuGet Package](https://thepracticaldev.s3.amazonaws.com/i/dm5xhrfiop8ptvqy09gm.png)

Now let's create a new Azure Function called *AlexaHelloName*. As **trigger** select *Http trigger* and as **Authorization level** select *Anonymous*. Update the logic of the function by the following code:

```csharp
[FunctionName("AlexaHelloName")]
public static async Task<SkillResponse> Run(
  [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "alexa/helloname")] 
  HttpRequest req)
{
  // read content as skill request
  var payload = await req.ReadAsStringAsync();
  var skillRequest = JsonConvert.DeserializeObject<SkillRequest>(payload);

  // get type of request
  var requestType = skillRequest.GetRequestType();

  // handle launchrequest
  if (requestType == typeof(LaunchRequest))
  {
      return ResponseBuilder
        .Ask("Welcome. I can great people. Please give me a name.",
             new Reprompt("Whom shall I welcome?"));
  }

  // handle intentrequest
  if (requestType == typeof(IntentRequest))
  {
    var intentRequest = skillRequest.Request as IntentRequest;

    // handle greetingintent
    if (intentRequest.Intent.Name == "GreetingIntent")
    {
      var name = intentRequest.Intent.Slots["name"].Value;
      return ResponseBuilder.TellWithCard($"Hello {name}. I am pleased to meet you.",
        "Hello!", $"{name.ToUpper()}");
    }
  }

  // default response
  return ResponseBuilder.Tell("Oops, something went wrong here.");
}
```

As you can see as a first step we will deserialize the JSON request into a `SkillRequest` object. We check if the user just launched our request by checking the `RequestType`. It is either `LaunchRequest` or `IntentRequest`. If it is an `IntentRequest` we extract the *name* from the slots and create a response.

Let's go back to the Developer Console and add a new skill with the name *Hello Name*. The settings are the same like for our first skill. I prepared a JSON file containing all the meta data for our skill. So you click in the left pane on *JSON Editor* and replace the content by the following JSON definition:

```json
{
  "interactionModel": {
    "languageModel": {
      "invocationName": "hello name",
      "intents": [
        {
          "name": "AMAZON.FallbackIntent",
          "samples": []
        },
        {
          "name": "AMAZON.CancelIntent",
          "samples": []
        },
        {
          "name": "AMAZON.HelpIntent",
          "samples": []
        },
        {
          "name": "AMAZON.StopIntent",
          "samples": []
        },
        {
          "name": "AMAZON.NavigateHomeIntent",
          "samples": []
        },
        {
          "name": "GreetingIntent",
          "slots": [
            {
              "name": "name",
              "type": "AMAZON.US_FIRST_NAME"
            }
          ],
          "samples": [
            "Please welcome {name}",
            "Welcome {name}",
            "Please greet {name}",
            "Greet {name}",
            "I'm {name}",
            "My name is {name}"
          ]
        }
      ],
      "types": []
    }
  }
}
```

Click **Save Model** and **Build Model** to apply our changes. Now you need to add the endpoint and select the correct SSL handling like in our first skill and we can start testing our skill.

![Testing the Skill](https://thepracticaldev.s3.amazonaws.com/i/6htkubed3scofiv0to7o.png)

There are to ways to work with our skill. The first one is to launch the skill: *open hello name* and than provide a *name*. Or you can pass the name directly to our skill: *launch hello name and greet sebastian*.


# Conclusion

Now you know the basics of creating your custom skills using Azure FUnctions. The advantages are that you can use any programming language, because a skill is only an exchange of JSON. 

I can't wait to read about your first skills for Alexa. Just share the idea or the released version with me in the comments.