Alexa, how do I make you smarter

Search Options
Blog Search
Sign up for our monthly marketing trends enewsletter
  • 12/18/2017

    We recently had the opportunity to work on a custom Alexa skill for internal use. In this post we’ll give you the back story of the skill we developed, an overview of custom Alexa skill development, a description of the skill that we developed and some after thoughts about Alexa skill development.

    Our support team uses the Zendesk support ticket service to manage our support requests. Over the past few years we have developed tools that integrate with the Zendesk API to gain insight on the functionality of our support services. The Alexa skill that we developed allows us to ask Alexa how the support team is doing which results in Alexa rattling off support ticket information like number of new, open, solved, and closed tickets.

    It’s straight-forward to get started with Alexa skill development. First you need an Amazon developer account which is free and as easy to set up as any online account. Next you need an Amazon Web Services (AWS) account, which is about as easy to set up as the Amazon developer account. Once you have an Amazon developer account you can go to your dashboard and find the Alexa tab. Then you can get started with the Alexa Skills Kit.

    From there you can create a new skill. At this point you’ll need to give your skill a name as well as an invocation name. The invocation name is what your users will say to Alexa to initiate the skill. In our case the invocation name was “how is support doing.” The next major step is setting up the interaction model. The interaction model defines how your users will interact with Alexa. You can define the model using JSON or the Skill Builder. The model consists of elements called Intents. These are essentially the commands that users will give to Alexa. In our case we created a “Rundown” intent. Once you create an Intent you can define Utterances for the Intent. Utterances are words and phrases that users can say to activate the Intent. The main Utterance for our Rundown intent is “give me the rundown.”

    While we didn’t use this functionality, you can include variables called Slots in your Utterances. Slots provide a way for you to collect information from your users that is necessary to fulfill their request. A simple example would be “give me the rundown for {Timespan}” where {Timespan} is a Slot. There are several data types available for Slots, but the most sensible type for Timespan would likely be Amazon.DATE, which supports phrases like “this week,” “last month,” etc. For the built-in data types Alexa will convert the user’s speech into something your code can use. For example, “this week” would be converted to something like “2017-w40.”

    Once you’ve configured, saved and built your interaction model you’re ready to write some code. The code, of course will have to live somewhere and you have two options. You can host the code yourself which requires an SSL, or you host the code as a function in AWS Lambda which doesn’t require an SSL. Getting a function started is super easy and requires you to log into the AWS console, navigate to the lambda service, create a function and follow the steps you’re presented with.

    During the setup you will have to select a Runtime to use. The current options are C#, Node.js 4.3, Node.js 6.10, Python 2.7, and Python 3.6. We used C# (.NET Core v1.0) for our skill, but having some options is nice. Once your function has been created you’ll need some code. Node.js and Python code can be entered into a text area in the Lambda function web interface but C# code must be packaged and uploaded. There is an AWS Toolkit available for Visual Studio which makes publishing to Lambda super easy. Another useful item for C# Alexa skill development is the Alexa.NET library by Tim Heuer, which is available via NuGet.

    By now you’re probably wondering what the skill code looks like. The code is basically an Intent handler. A user initiates the skill then expresses their intent. Alexa identifies the intent and requests that your code provide a response to satisfy the user’s intent. Here is a simple example:

    public SkillResponse FunctionHandler(SkillRequest input, ILambdaContext context)
    {
        var log = context.Logger;
     
        SkillResponse response = new SkillResponse();
     
        response.Response = new ResponseBody
        {
            ShouldEndSession = false
        };
     
        IOutputSpeech innerResponse = null;
        IOutputSpeech repromptResponse = null;
     
        log.LogLine($"First Line");
     
        if (input.GetRequestType() == typeof(LaunchRequest))
        {
            log.LogLine($"Default LaunchRequest made: 'Alexa, how is support doing?");
     
            innerResponse = new PlainTextOutputSpeech();
     
            (innerResponse as PlainTextOutputSpeech).Text = DefaultIntentResponses[LaunchIntent];
        }
        else if (input.GetRequestType() == typeof(IntentRequest))
        {
            var intentRequest = (IntentRequest)input.Request;
            switch (intentRequest.Intent.Name)
            {
                case CancelIntent:
                    log.LogLine($"AMAZON.CancelIntent: send StopMessage");
                    innerResponse = new PlainTextOutputSpeech();
                    (innerResponse as PlainTextOutputSpeech).Text = DefaultIntentResponses[CancelIntent];
                    response.Response.ShouldEndSession = true;
                    break;
                case StopIntent:
                    log.LogLine($"AMAZON.StopIntent: send StopMessage");
                    innerResponse = new PlainTextOutputSpeech();
                    (innerResponse as PlainTextOutputSpeech).Text = DefaultIntentResponses[StopIntent];
                    response.Response.ShouldEndSession = true;
                    break;
                case HelpIntent:
                    log.LogLine($"AMAZON.HelpIntent: send HelpMessage");
                    innerResponse = new PlainTextOutputSpeech();
                    (innerResponse as PlainTextOutputSpeech).Text = DefaultIntentResponses[HelpIntent];
                    break;
                case SupportRundownIntent:
                    log.LogLine($"supportRundown");
                    innerResponse = new PlainTextOutputSpeech();
                    (innerResponse as PlainTextOutputSpeech).Text = getSupportRundown();
                    response.Response.Reprompt = new Reprompt();
                    repromptResponse = new PlainTextOutputSpeech();
                    (repromptResponse as PlainTextOutputSpeech).Text = "Can I tell you about anything else?";
                    break;
                default:
                    log.LogLine($"Unknown intent: " + intentRequest.Intent.Name);
                    innerResponse = new PlainTextOutputSpeech();
                    (innerResponse as PlainTextOutputSpeech).Text = DefaultIntentResponses[HelpIntent];
                    break;
            }
        }
     
        response.Response.OutputSpeech = innerResponse;
       
        if (response.Response.Reprompt != null)
        {
            response.Response.Reprompt.OutputSpeech = repromptResponse;
        }
     
        response.Version = "1.0";
     
        return response;
    }

    You can see that the function is basically a switch statement with each case being a different Intent. The Cancel, Stop,, and Help Intents are included with all skills and you’ll need to handle them. The SupportRundownIntent is our custom Intent. The getSupportRundown function is the meat of handling the Intent and collects all of the information it needs from Zendesk to construct a sentence for Alexa to respond with. Once your code is written and published within Lambda you can finish the Configuration step on your skill in the Amazon Developer portal. All you need to do is point your skill to the Lambda function using the function’s ARN. The ARN should be at the top of your function’s configuration page within the Lambda web interface. Once your function and skill are connected you can test the skill on the Test step in the Amazon Developer portal. You probably want to test the skill out on an Alexa device afterward. All you have to do is use the Alexa app to tie your device to your Amazon Developer account. Once that is done you should be able to start talking to Alexa to test your skill.

    You already know the basics of the skill that we developed so here is some technical stuff. As I mentioned earlier we’ve developed some custom integrations with the Zendesk API.

    Specifically, we have a custom API client which can get all kinds of information from Zendesk. For our skill we needed basic ticket information such as the number of tickets and the status of each ticket. No problem, the client already gets that information.

    There was one minor problem. The ticket client library targets .NET 4.5 and not .NET Core v1.0, which meant we couldn’t plop the client library into our Lambda function solution. In favor of getting something up and running with the least amount of work we set up a generic HTTP handler on an Azure App Service. The handler uses our ticket client to get the information our skill needs and responds to the skill with a JSON object. Here is a diagram:

    This configuration worked fine, but seemed a bit slow at times. The extra hop to the HTTP handler probably wasn’t helping so we eventually refactored the ticket client for .NET Core v1.0 and the performance improved a bit. Other than the .NET framework issue there weren’t any other hurdles. One thing that was a bit frustrating was debugging. Another great feature of Visual Studio is debugging. We currently don’t know of a way to debug a Lambda function while Alexa makes requests to the function. Instead, we put together a console application that did most of what the Lambda function does and had that interact with the HTTP Handler. There is supposedly some logging functionality with Lambda functions, but we were not able to see any of the log entries in the CloudWatch logs. Another approach our team took at times was to have Alexa respond with values that we were interested in, which was kind of interesting when she read exception messages to us.

    Hopefully you now have a good sense for how to get started with Alexa Skill development. Keep in mind that your C# function needs to support .NET Core v1.0. Watch out for dependencies on .NET Core v1.1 packages. Be prepared to get creative with debugging. We hope you can see from how our skill is configured that once you get the basics of your Intent handler function together, the possibilities for integration are pretty much endless.

    Of course, if you think you want a custom Alexa skill but most of this post may as well have been written in Greek then we can do the heavy lifting for you. Drop us a note or tweet us, @thundertech.
  • Best SEO Tools from 2017
  • 928
  • Trends 2018
Sign up for our monthly marketing newsletters