Author avatar

Tyler Steck

Alexa Tutorial 2016

Tyler Steck

  • Dec 15, 2018
  • 12 Min read
  • 12,655 Views
  • Dec 15, 2018
  • 12 Min read
  • 12,655 Views
Node.js

Important information about how Alexa works. - WORK IN PROGRESS!

Alexa is based on a question->response similar to Siri and Google Now services.

description

To create a skill we will need to Create an Alexa skill to capture the request like "Alexa, Ask HackGuides what time is it?"

This will then get translated from the Alexa Skill API into a method call into the Amazon AWS Lambda Services that is is then sent back to the user through the Alexa Skill.

Alexa Question Response

Lets get started

To create a skill you will need to create for developer.amazon.com::

Now that you have an account you can begin to Add a new Skill:

Alexa Skill Kit

This is the list of all your skills and you can click the top right button to Add New SKill

Skill Information

description

  • Update the Name with "Hack Guides SKill Demo"
  • Update the Invocation Name with "code hack" (so it's easy to pronounce)

Interaction Model

description

description

Back to "Configuration" in Alexa SKill Kit

description

Test

1{
2  "intents": [
3    {
4      "intent": "GetChoresIntent",
5      "slots": [
6        {
7          "name": "firstName",
8          "type" : "AMAZON.US_FIRST_NAME"
9        }
10      ]
11    },
12    {
13      "intent": "AMAZON.HelpIntent"
14    },
15    {
16      "intent": "AMAZON.StopIntent"
17    },
18    {
19      "intent": "AMAZON.CancelIntent"
20    }
21  ]
22}
json
1GetChoresIntent what chore is for {firstName}
2GetChoresIntent {firstName} needs a chore
3GetChoresIntent give me a chore for {firstName}

Configuration

  • First we need to create a Lambda Expression before filling out this part description

Navigate to this website and create the necessary account Lambda Expression Website

You can see your list of existing functions or description

Select Blueprint

Search for "Alexa" and click on the title of the "alexa-skills-kit-color-expert"description

Configure event sources

description

Configure Function

description

You will probably need to create a new Role so click to "Create new role".

description

Review

Finally you are read with your lambda expression and click: description

In the top right corner of your Lambda Function you will now have a ARN that provides the connction for Alexa Skill.

description

1// Route the incoming request based on type (LaunchRequest, IntentRequest,
2// etc.) The JSON body of the request is provided in the event parameter.
3exports.handler = function (event, context) {
4    try {
5        console.log("event.session.application.applicationId=" + event.session.application.applicationId);
6
7        /**
8         * Uncomment this if statement and populate with your skill's application ID to
9         * prevent someone else from configuring a skill that sends requests to this function.
10         */
11        /*
12        if (event.session.application.applicationId !== "amzn1.echo-sdk-ams.app.[unique-value-here]") {
13             context.fail("Invalid Application ID");
14        }
15        */
16
17        if (event.session.new) {
18            onSessionStarted({requestId: event.request.requestId}, event.session);
19        }
20
21        if (event.request.type === "LaunchRequest") {
22            onLaunch(event.request,
23                event.session,
24                function callback(sessionAttributes, speechletResponse) {
25                    context.succeed(buildResponse(sessionAttributes, speechletResponse));
26                });
27        } else if (event.request.type === "IntentRequest") {
28            onIntent(event.request,
29                event.session,
30                function callback(sessionAttributes, speechletResponse) {
31                    context.succeed(buildResponse(sessionAttributes, speechletResponse));
32                });
33        } else if (event.request.type === "SessionEndedRequest") {
34            onSessionEnded(event.request, event.session);
35            context.succeed();
36        }
37    } catch (e) {
38        context.fail("Exception: " + e);
39    }
40};
41
42/**
43 * Called when the session starts.
44 */
45function onSessionStarted(sessionStartedRequest, session) {
46    console.log("onSessionStarted requestId=" + sessionStartedRequest.requestId +
47        ", sessionId=" + session.sessionId);
48}
49
50/**
51 * Called when the user launches the skill without specifying what they want.
52 */
53function onLaunch(launchRequest, session, callback) {
54    console.log("onLaunch requestId=" + launchRequest.requestId +
55        ", sessionId=" + session.sessionId);
56
57    // Dispatch to your skill's launch.
58    getWelcomeResponse(callback);
59}
60
61/**
62 * Called when the user specifies an intent for this skill.
63 */
64function onIntent(intentRequest, session, callback) {
65    console.log("onIntent requestId=" + intentRequest.requestId +
66        ", sessionId=" + session.sessionId);
67
68    var intent = intentRequest.intent,
69        intentName = intentRequest.intent.name;
70
71    // Dispatch to your skill's intent handlers
72    if ("GetChoresIntent" === intentName) {
73        getChoreResponse(intent, session, callback);
74    } else if ("AMAZON.HelpIntent" === intentName) {
75        getWelcomeResponse(callback);
76    } else if ("AMAZON.StopIntent" === intentName || "AMAZON.CancelIntent" === intentName) {
77        handleSessionEndRequest(callback);
78    } else {
79        throw "Invalid intent";
80    }
81}
82
83/**
84 * Called when the user ends the session.
85 * Is not called when the skill returns shouldEndSession=true.
86 */
87function onSessionEnded(sessionEndedRequest, session) {
88    console.log("onSessionEnded requestId=" + sessionEndedRequest.requestId +
89        ", sessionId=" + session.sessionId);
90    // Add cleanup logic here
91}
92
93// --------------- Functions that control the skill's behavior -----------------------
94
95function getWelcomeResponse(callback) {
96    // If we wanted to initialize the session to have some attributes we could add those here.
97    var sessionAttributes = {};
98    var cardTitle = "Welcome";
99    var speechOutput = "Welcome to the Hack Guides demo. " +
100        "Please ask for a chore by saying: give me a chore for name";
101    var repromptText = "Please ask for a chore by saying: give me a chore for name";
102    var shouldEndSession = false;
103
104    callback(sessionAttributes,
105        buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
106}
107
108function handleSessionEndRequest(callback) {
109    var cardTitle = "Session Ended";
110    var speechOutput = "Thank you for trying the Hack Guides demo. Have an Amazon day!";
111    // Setting this to true ends the session and exits the skill.
112    var shouldEndSession = true;
113
114    callback({}, buildSpeechletResponse(cardTitle, speechOutput, null, shouldEndSession));
115}
116
117/**
118 * Sets the color in the session and prepares the speech to reply to the user.
119 */
120function getChoreResponse(intent, session, callback) {
121    var cardTitle = intent.name;
122    var fistNameSlot = intent.slots.firstName;
123    var repromptText = "";
124    var sessionAttributes = {};
125    var shouldEndSession = false;
126    var speechOutput = "";
127
128    if (fistNameSlot) {
129        
130        var miscResponses = [
131    'I think <break time="1s"/> {firstNameSlot} should work on Sweeping and moping!',
132    'I think {firstNameSlot} should work on <break time="1s"/> dishes!',
133    '{firstNameSlot}! should work on making their bed!',
134    'Maybe, nope definitely {firstNameSlot} should work on vacuuming the house',
135    'I think this time {firstNameSlot} should work on cleaning the toilets!',
136    '{firstNameSlot} should <break time="1s"/> work on clearing the table'
137    ];
138        
139        var firstNameValue = fistNameSlot.value;
140        var randomInt = getRandomInt(0, miscResponses.length - 1);
141        console.log(randomInt);
142        speechOutput = miscResponses[randomInt].replace(/{firstNameSlot}/g, firstNameValue);
143        repromptText = "Please ask for a chore by saying: give me a chore for name";
144    } else {
145        speechOutput = "I didn't catch that name you tell me again";
146        repromptText = "Please ask for a chore by saying: give me a chore for name";
147    }
148
149    callback(sessionAttributes,
150         buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
151}
152
153function getRandomInt(min, max) {
154    console.log("max:" + max + " min:" + min);
155    return Math.floor(Math.random() * (max - min + 1)) + min;
156}
157
158// --------------- Helpers that build all of the responses -----------------------
159
160function buildSpeechletResponse(title, output, repromptText, shouldEndSession) {
161    return {
162        outputSpeech: {
163            type: "PlainText",
164            text: output
165        },
166        card: {
167            type: "Simple",
168            title: "SessionSpeechlet - " + title,
169            content: "SessionSpeechlet - " + output
170        },
171        reprompt: {
172            outputSpeech: {
173                type: "PlainText",
174                text: repromptText
175            }
176        },
177        shouldEndSession: shouldEndSession
178    };
179}
180
181function buildResponse(sessionAttributes, speechletResponse) {
182    return {
183        version: "1.0",
184        sessionAttributes: sessionAttributes,
185        response: speechletResponse
186    };
187}
js

Test