Giter VIP home page Giter VIP logo

hello-alexa's Introduction

Build Your Own Alexa Skill

Introduction

In this Lesson, you’ll learn how to create an Amazon Alexa Skill. You’ll see how to set up and configure the voice interactions, and also how to create an AWS Lambda function that handles the requests and responses that users initiate.

Prerequisites

You’ll need a few things before you can follow this lesson:

  • You’ll need to be comfortable with using your computer’s terminal or command prompt and know how to create and edit plain text files.

Setting up your skill

With all the prerequisites in place, you’re ready to define your skill. There are several steps in this process. First, log into the Amazon Developer Portal, and then click the Alexa link at the top of the page. You’ll be prompted to choose a starting point (Alexa Skills Kit or Alexa Voice Service). Click Get Started under the Alexa Skills Kit option:

alexa skills portal

Step 1: Add the New Skill

  • Click the Add a New Skill button

In this step, you’ll define the basic characteristics of the skill: its name, the name that people use to invoke it, and a couple of other settings.

add new skill
  • Set the following options:

    Skill type

    Make sure this is set to Custom Interaction Model.

    Name

    This is what appears in the Alexa app. Call it "Tide Pooler."

    Invocation Name

    This is how users will activate the skill. Use "Tide Pooler" here as well.

    Audio Player

    You can leave this set to No for this skill. If you were playing audio, such a music, that you wanted to allow users to stop or pause, you’d need this. You won’t need it here.

  • Click Next.

set skill information

Step 2: Define the Skill’s Interaction Model

Now you’re in the Interaction Model section of the setup process. This is where you describe what sorts of things you can say to the skill. The first part is the intent schema, which defines the intents, or kinds of interactions your skill has. A given intent corresponds to a function that you’ll define later; it will look up tide info, format it into a nice result, and that will be read back to the user. The second part is a collection of utterances, and they are (mostly) human-readable sentences with optional slots for one or more parameters. Not all skills will need a parameter, but Tide Pooler needs to know what city the user is curious about.

Note
You can also copy this schema from this Lesson’s GitHub repository.

Put the following schema into the Intent Schema. The first intent is GetTideIntent, which is the intent for asking about the high tide. The other intents allow users to ask the skill for help, or to stop or cancel it.

{
  "intents": [
    {
      "intent": "GetTideIntent",
      "slots": [
        {
          "name": "City",
          "type": "AMAZON.US_CITY"
        }
      ]
    },
    {
      "intent": "AMAZON.HelpIntent"
    },
    {
      "intent": "AMAZON.StopIntent"
    },
    {
      "intent": "AMAZON.CancelIntent"
    }
  ]
}

Now you’re ready to get into the actual things you can ask the skill. Put the following text into the Sample Utterances field. Note how each utterance refers to the City slot:

GetTideIntent when is high tide in {City}
GetTideIntent when will it be high tide in {City}
GetTideIntent what time is high tide for {City}
GetTideIntent what time is high tide in {City}
Note
You can also copy the list of utterances from this Lesson’s GitHub repository.

The GetTideIntent signifies that the user wants to know when high tide is. They can ask it in several ways:

  • When is high tide in Newport, Rhode Island?

  • When will it be high tide in New Bedford, Massachusetts?

  • What time is high tide for Gloucester, Massachusetts?

  • What time is high tide in Gloucester, Massachusetts?

Because this skill is only using the built-in AMAZON.US_CITY slot type, you won’t need to define any Custom Slot Types.

Click Save, and wait while the interaction model is built. When it’s done, the message below the Save button should read "Successfully updated the interaction model."

Building the Sample Skill

Now you’re ready to build an AWS Lambda function that you’ll install in AWS. It will be called on demand, when it’s needed.

Step 1: Create the package.json File

Open a Terminal or Command Prompt, create a new directory named tide-pooler, and cd into it. Next, create a file named package.json in the tide-pooler directory and add these lines to it:

{
  "name": "tide-pooler",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "dependencies": {
    "alexa-sdk": "^1.0.5",
    "dotenv": "^2.0.0",
    "node-lambda": "^0.8.9"
  }
}

Save the file, and in your terminal or command prompt, run this command to pull down all the dependencies you need for your skill: npm install. Now you should see a node_modules directory alongside the package.json file:

$ ls -l
total 8
drwxr-xr-x  40 bjepson  staff  1360 Sep  9 15:28 node_modules
-rw-r--r--   1 bjepson  staff   197 Sep  9 15:28 package.json

Step 2: Create the JavaScript Handlers

Next, create a file named index.js, and put the following code in it:

Note
You can also copy this file from this Lesson’s GitHub repository.
'use strict';

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

require('dotenv').config(); // (2)

var SKILL_NAME = 'Tide Pooler'; // (3)

exports.handler = function(event, context, callback) { // (4)
    var alexa = Alexa.handler(event, context);
    alexa.APP_ID = APP_ID;
    alexa.registerHandlers(handlers);
    alexa.execute();
};

var handlers = {
    'LaunchRequest': function () { // (5)
        this.emit('AMAZON.HelpIntent');
    },
    'GetTideIntent': function () {
        var citySlot = this.event.request.intent.slots.City; // (6)
        var cityName;
        if (citySlot && citySlot.value) { // (7)
            cityName = citySlot.value;

            var cardTitle = SKILL_NAME + " High Tide For - " + cityName; // (8)
            var time = "5:00pm";
            var speechOutput = "It will be high tide in " +
                               cityName + " at " + time;
            this.emit(':tellWithCard', speechOutput, SKILL_NAME, // (9)
                      cardTitle, time);

          } else { // (10)
            var speechOutput =
                'I\'m sorry, I don\'t know when high tide is for that location';
            this.emit(':tell', speechOutput);
          }
    },
    'AMAZON.HelpIntent': function () { // (11)
        var speechOutput = "You can say when is high tide in city name, or, " +
                           "you can say exit... What can I help you with?";
        var reprompt = "What can I help you with?";
        this.emit(':ask', speechOutput, reprompt);
    },
    'AMAZON.CancelIntent': function () { // (12)
        this.emit(':tell', 'Goodbye!');
    },
    'AMAZON.StopIntent': function () {
        this.emit(':tell', 'Goodbye!');
    }
};
  1. This brings in the Node.js Alexa SDK. When you upload this function to AWS Lambda, you’ll be sending a zip file that includes index.js as well as the node_modules directory, which includes the Alexa SDK and many other dependencies.

  2. The dotenv module is a helper utility that will pull in the code from the .env file, which you’ll create later. This file will contain your AWS API and app keys.

  3. You’ll use the name of the skill in various places, so it’s in a handy variable here.

  4. This function sets things up so that all requests are routed to the appropriate handlers, defined next.

  5. LaunchRequest is called if the skill is invoked without a command. Since you need a city name to do anything, this handler just calls the help handler.

  6. Inside the handler for the GetTideIntent, the code tries to obtain the city the user asked about.

  7. If there was indeed a city in the request, and it has a name, the handler can do its job.

  8. Here, the handler creates three strings: one for the card title (which will be displayed in the Alexa app), another for the high tide time (hardcoded for now), and the speech output that Alexa will speak to the user.

  9. This causes Alexa to speak her response, and to display a card in the user’s Alexa app.

  10. If the handler couldn’t discern a city name, Alexa will ask the user to try again.

  11. This causes Alexa to speak the help text for this skill.

  12. These last two handlers take care of a user stopping or cancelling the skill. In most skills, these will have the same behavior. See Implementing the Built-in Intents for more information.

Step 3: Set up Your API Keys

Create a file called .env to store all the various keys you’ll need. For now, you’ll just need your App Id. Return to https://developer.amazon.com, sign in, and then click the Alexa link. Click the Get Started link under Alexa Skills Kit, and choose Tide Pooler from the list of skills. You should see the application id; copy that value into the .env file as shown, replacing <your app id> with the app ID from Amazon:

APP_ID=<your app id>

In your program, you’ll refer to this as process.env.APP_ID.

Note
If you are putting this into a Git repo, you should be sure to add a line for the .env file to your .gitignore file so that you don’t accidentally check your keys into a public repository, which would be bad!

Now you need to zip up everything in the folder into a zip file called hello-alexa.zip. Using the command line version of zip, run this command:

zip -r hello-alexa.zip index.js package.json .env node_modules

Deploy the Lambda Function

Next, sign into the AWS Console. Click Lambda from the list of services. Then:

  • In the upper right, click the menu to the right of your name, and make sure your availability zone is set to N. Virginia, as this is the only zone with support for Alexa Skills:

availability zones
  • Next, click Get Started Now. You’ll be prompted to choose a Blueprint. Scroll down to the bottom of the screen and click Skip.

select blueprint
  • Now you’re prompted to configure the trigger for this function. Click the dotted shape to the left of Lambda, and choose Alexa Skills Kit, then click Next:

configure triggers
  • On the next screen, configure your function as follows:

    Name

    Call it TidePooler

    Description

    Give it a short description like "High Tide Lookup".

    Runtime

    Leave this set at Node.js 4.3

    Code Entry Type

    Select Upload a Zip File from the menu.

configure function
  • Click the Upload button, and select the hello-alexa.zip file you created earlier. Scroll down, and under Role, select Create a New Custom Role. The IAM manager will open in a new tab. Make sure Create a New IAM Role is selected, and that the Role Name is lambda_basic_execution. Click Allow to create the role and you’ll return to the previous tab.

new role
  • Leave the other values at their defaults, scroll down, and click Next. You’ll be prompted to review your function, as shown here:

review function
  • Click Create Function, and you’ll be taken to the AWS dashboard page for the function. The Lambda function’s ARN will appear in the upper right, and begins with arn:aws:lambda:us-east. Copy the entire ARN. You will need it in the next step.

Connect the Alexa Skill to the Lambda function

Return to https://developer.amazon.com, sign in, and then click the Alexa link. Click the Get Started link under Alexa Skills Kit, and choose Tide Pooler from the list of skills. Click Configuration from the list on the left, then:

  • Under the Endpoint section, choose Lambda ARN.

  • Paste your Lambda function’s ARN into the field.

connect lambda
  • Leave Account Linking set to No, and click Next. You’ll be taken to the service simulator.

Now you’re ready to test the skill. Scroll down to the Enter Utterance field, and type in a supported utterance, such as "When is high tide in Boston?" Click Ask Tide Pooler, and you should see the JSON for both the request and response appear in the text fields below. You can click the Play button to the right of the Listen label to hear the response:

test skill

Where Next?

There is a lot more you can do from here. The most obvious upgrade is to actually look up high tide information by calling a web service like the Weather Underground API. Right now, Alexa is just telling us that high tide is always at 5pm.

One thing you didn’t learn how to do was test this on your own Amazon Echo. To do this, you’ll need to register your device for testing, among other things. See Testing a Custom Skill for more details.

What if you don’t have an Amazon Echo? You could build your own with the $35 Rapsberry Pi: https://www.raspberrypi.org/blog/amazon-echo-homebrew-version/

Testing Locally

You might get tired of having to upload a zip file every time you want to test. To test locally, you can install lambda-local, which allows you to send a JSON file containing a request to a Lambda function.

Install it according to the instructions, then create a file called event-sample.js with the following contents:

module.exports = {
  "session": {
    "application": {
      "applicationId": "TEST"
    },
    "user": {
      "userId": "Anonymous"
    }
  },
  "request": {
    "type": "IntentRequest",
    "intent": {
      "name": "GetTideIntent",
      "slots": {
        "City": {
          "name": "City",
          "value": "Boston"
        }
      }
    }
  }
}
Note
You can also copy this file from this Lesson’s GitHub repository.

Save that in the same folder as index.js, and test it with this command:

lambda-local -l index.js -h handler -e event-sample.js

In the output, you’ll see the response that would have been spoken:

{
  "version": "1.0",
  "response": {
    "outputSpeech": {
      "type": "SSML",
      "ssml": "<speak> It will be high tide in Boston at 5:00pm </speak>"
    },
    "shouldEndSession": true,
    "card": {
      "type": "Simple",
      "title": "Tide Pooler",
      "content": "Tide Pooler High Tide For - Boston"
    }
  },
  "sessionAttributes": {}
}

hello-alexa's People

Contributors

bjepson avatar odewahn avatar

Watchers

 avatar James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.