Alexa Skills with Custom Slot Types

Alexa Skills

In the Sequoia blog we have seen previous development of Alexa skills. In this post the concept of Alex slots was introduced. If you recall a slot is basically the user utterance input to the Alexa skill. Amazon provides many basic types of user input. In this post I'll create a skill that uses several slots and one of them being a custom type.

Guitar Note Finder

The skill I made here is called Guitar Note Finder. It passed Amazon certification process this morning.

You can ask Alexa a phrase of the form "what note is on the fourth string fret number 7?" The key point about this phrase is the slots. The Alexa utterance of this phrase is literally Alexa which note is on the {string} string fret number {fret}. The {fret} slot is just a generic type of number but the {string} slot is a custom slot. Before you can use a custom slot type in your user utterance you need to define the custom type.

Custom Slots

The {string} slot here is is a custom type called theString. It's a type defined by enumeration. Here is what it looks like it in the Alexa developer console.

Once you have defined the custom slot you can now use it as a permissible slot in your utterance. Here is my "intent"

and now you can map the slots in the utterance to the intent slots with standard type for fret AMAZON.NUMBER and custom type theString for string. This can be easily extended with further intents.

The New Testing Console

Alexa has released a new test console that let's you test your skill against either verbal utterances or text. This is a must if you intend on releasing your skill in the marketplace. Before you get on with your testing you'll need to remember your invocation phrase to prepare Alexa to accept your input. Here is one test for the Guitar Note Finder skill.

Alexa now also has visual versions of skills. The testing console will also show you the visual output of your skill to verify it's accuracy.

. The Alexa developer console has vastly improved since it's initial release. The new testing interface makes it easy to test your skill for it's most popular uses cases but also verify it's accuracy on on some edge cases. For example, this skill is prepared to handle a 22 fret guitar. It's unusual to play that high on the neck, but still a guitar enthusiast can use the skill in that case.

The code

Here is the actual code behind this skill.

'use strict';

var Alexa = require('alexa-sdk');

var APP_ID =<REDACTED>;  
var notes=['a',"a sharp",'b', 'c', "c sharp", 'd', "d sharp", 'e', 'f', "f sharp", 'g', "g sharp"];  
var strings = ["1st","2nd", "3rd", "4th", "5th", "6th"] ;

var first = {} ;  
var second = {};  
var third = {};  
var fourth = {};  
var fifth = {};  
var sixth = {};

//open strings
first[0] = 'e';  
second[0] = 'b';  
third[0] = 'g';  
fourth[0] = 'd';  
fifth[0] = 'a';  
sixth[0] = 'e';  
for( var j =1 ; j < 23 ; j++){ first[j] = notes[(j+7)%12]}  
for(  j =1 ; j < 23 ; j++){ second[j] = notes[(j+2)%12]}  
for(  j =1 ; j < 23 ; j++){ third[j] = notes[(j+10)%12]}  
for(  j =1 ; j < 23 ; j++){ fourth[j] = notes[(j+5)%12]}  
for(  j =1 ; j < 23 ; j++){ fifth[j] = notes[(j)%12]}  
sixth = first ;  
var translation = {};  
translation["1st"]=first;  
translation["2nd"]=second;  
translation["3rd"]=third;  
translation["4th"]=fourth;  
translation["5th"]=fifth;  
translation["6th"]=sixth;  
exports.handler = function(event, context, callback) {  
    var alexa = Alexa.handler(event, context);
    alexa.APP_ID = APP_ID;
    alexa.registerHandlers(handlers);
    alexa.execute();
};
var handlers = {  
    'LaunchRequest': function () {
        this.emit('AMAZON.HelpIntent');
    },
    'identify': function () {
        var string = this.event.request.intent.slots.string.value;
        var fret = this.event.request.intent.slots.fret.value;
         if(string == "second"){
         string = "2nd";
    }
        var error = '';
        if (!string) {
            error = "I did not hear what code you wanted me to identify.";
            this.emit(':tellWithCard', error, "guitar", error);
            return;
        }

        if (strings.indexOf(string)==-1) {
            error = "I did not understand which string you are referencing.";
            this.emit(':tellWithCard', error, "guitar", error);
            return;
        }
       if (fret < 0 || fret > 22) {
            error = "Please give a valid fret up to 22 ";
            this.emit(':tellWithCard', error, "guitar", error);
            return;
    }
     var note_data =  translation[string][fret];
    this.emit(':tellWithCard', note_data, "guitar",note_data);
    },
    'AMAZON.HelpIntent': function () {
        this.emit(':ask', "You can say, what note is on the 4th string fret number 5?", "What can I help you with?");
    },
    'AMAZON.StopIntent': function () {
        this.emit(':tell', "OK!");
    },
    'AMAZON.CancelIntent': function () {
        this.emit(':tell', "OK!");
    }
};

The code here isn't breath taking but you can see how I model the guitar neck lay out. There are actually only 12 notes on a guitar and they are declared in the array var notes=['a',"a sharp",'b', 'c', "c sharp", 'd', "d sharp", 'e', 'f', "f sharp", 'g', "g sharp"]; Each string just cycles through them at the appropriate starting and stopping points.

Custom Slot Validation

One piece of the code worth looking at is the validation of the custom slot. Recall the string slot used a custom type. We need to be sure that an utterance of the form "what note is the {choclate} string fret number 6?" returns a validation error. To handle something like this we first define a list of acceptable strings

var strings = ["1st","2nd", "3rd", "4th", "5th", "6th"];  

and then verify the uttered string is actually in that list.

if (strings.indexOf(string)==-1)  
            error = "I did not understand which string you are referencing.";
            this.emit(':tellWithCard', error, "guitar", error);

` Validating a custom slot like this is a must. Your skill will not pass the certification process without it.

Have Fun

Using custom slot types in your skill opens the door for a much richer interaction with the user. This can extend your skills to games and conversational skills.