loading...
Cover image for Alexa goes Azure: How to write a skill with Azure Functions

Alexa goes Azure: How to write a skill with Azure Functions

tsjdevapps profile image Sebastian | tsjdev-apps.de ・7 min read

This article is part of #ServerlessSeptember. 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/.

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 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

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

New Azure Function

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.

[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.

[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

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. You can login with your normal Amazon account or if you want you can create a new account.

Amazon Developer Console

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

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

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

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

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

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

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

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

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 to our Azure Function project.

NuGet Package

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:

[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:

{
  "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

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.

Posted on by:

tsjdevapps profile

Sebastian | tsjdev-apps.de

@tsjdevapps

I'm a Software Developer and currently working mostly with Xamarin, UWP, Azure and AWS.

Discussion

markdown guide