SlideShare ist ein Scribd-Unternehmen logo
1 von 65
Downloaden Sie, um offline zu lesen
RICK WARGO - MAR 2017
BUILD AN ALEXA SKILL
STEP-BY-STEP
1
BUILD AN ALEXA SKILL STEP-BY-STEP
Introduction
▸ This tutorial will guide you step-by-step to create a new Alexa skill
▸ This example skill will interface with Twitter and read recent tweets from a query
▸ The aim is to be able to extend this workflow for your own use
▸ This skill will be called Twitter News and will be private
▸ This tutorial will not cover publishing a new skill - there is plenty of available
documentation on how to publish
▸ Please let me know if you use this to build a new skill — I welcome feedback!
2
BUILD AN ALEXA SKILL STEP-BY-STEP
Sample Interactions — Define Prior to Building New Skill
▸ The critical path to creating a great skill is pre-visualization of the skill
▸ Try to define the interactions as much as possible and maintain in a file, for example, Examples.txt
▸ Q: What's the latest news?
▸ A: The last 1 tweet was: Rick Wargo tweeted: Join me this Sat at 11:30am - we'll build an Alexa skill that interfaces with Twitter at #PhillyCode @PhillyDotNet.
▸ Q: What's the latest popular tweet?
▸ A: There were no matching tweets.
▸ Q: What is the last 5 tweets?
▸ A: The last 5 tweets were: Rick Wargo tweeted: Join me this Sat at 11:30am - we'll build an Alexa skill that interfaces with Twitter at #PhillyCode @PhillyDotNet. Alina retweeted
Stratisplatform's tweet: #Stratis are gold sponsors @PhillyDotNet on 24th-25th February explaining our #blockchain t…
▸ Q: What is the last tweet from Rick?
▸ A: The last 1 tweet was: Rick Wargo tweeted: Join me this Sat at 11:30am - we'll build an Alexa skill that interfaces with Twitter at #PhillyCode @PhillyDotNet.
▸ Q: Who tweeted?
▸ A: Recent tweets were from: Rick Wargo, Kucilo Oro, Alina, XTexplorer, and Mohammad Khalid.
▸ Q: Who shared?
▸ A: Recent tweets were from: Rick Wargo, Kucilo Oro, Alina, XTexplorer, and Mohammad Khalid.
3
BUILD AN ALEXA SKILL STEP-BY-STEP
Assumptions
▸ Implementing on OSX 10.12.3
▸ Using AWS Lambda and Node.js 4.3 to host code
▸ Linux-style commands used throughout
# Commands to be executed at the command line are in this style
▸ Input from interactive commands is in bold text
▸ References to files point to the completed version of the twitter-news-skill in Github
▸ Depending on copy/paste, some files may require retouching, mostly white-space, for lint to succeed
▸ All commands to be executed from skill directory unless otherwise noted
▸ Should work with slight modifications on Windows
4
BUILD AN ALEXA SKILL STEP-BY-STEP
User Interaction Flow
5
Twitter API
User
Voice Request Audio Stream
Twitter-News
Skill
Lambda
JSON Request
Node.js
JSON Response
(SSML+Card)
Response (Audio)
Response (Text/Graphics)
Audio Response
App/Web
JSON Response
(statuses)
GET search/tweets
BUILD AN ALEXA SKILL STEP-BY-STEP
Prerequisites — Follow Links to Install
▸ Node.js
▸ Gulp
▸ AWS Developer Account
▸ AWS CLI
▸ Twitter Account
6
BUILD AN ALEXA SKILL STEP-BY-STEP
AWS Credentials
‣ For command line access to AWS, store credentials in ~/.aws/credentials
$ cat ~/.aws/credentials
[default]
aws_access_key_id = OATLIM5W7KKX1V6PQ792
aws_secret_access_key = I2WiUyTkPI7b36PQnin11oUqgZVX575tSUAB1FOm
‣ This may already be done when setting up the AWS CLI
‣ Development on Windows will require a different approach to storing this file
Not my real credentials :)
7
BUILD AN ALEXA SKILL STEP-BY-STEP
Create the Directory Structure
▸ Create a directory where both the Alexa skills and the Alexa App Server will live. All new
skills will live under here.
▸ For this tutorial, we’ll use ~/Code/alexa-js
▸ In that directory:
cd ~/Code/alexa-js
git clone https://github.com/rickwargo/alexa-app-root
mkdir alexa-js-apps†
▸ Install the node modules for alexa-app-root
cd alexa-app-root
npm install
8
†If you choose to call this directory something else, you’ll need
to update filesPath.server in gulpfile.js. You’ll
also need to update server.js and change app_dir to
point to the directory.
BUILD AN ALEXA SKILL STEP-BY-STEP
Create Certificate for HTTPS (if using)
▸ Install a self-signed certificate for HTTPS
gulp make-cert
[18:06:51] Using gulpfile ~/Code/alexa-js/test/alexa-app-root/gulpfile.js
[18:06:51] Starting 'make-cert'...
Generating RSA private key, 1024 bit long modulus
...++++++
.............++++++
e is 65537 (0x10001)
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:Pennsylvania
Locality Name (eg, city) []:Blue Bell
Organization Name (eg, company) [Internet Widgits Pty Ltd]:epicminds
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:Rick Wargo
Email Address []:cert@epicminds.com
[18:07:21] Finished 'make-cert' after 30 s
9
BUILD AN ALEXA SKILL STEP-BY-STEP
Test Web Server is Running
▸ Browse to http://localhost:8003/test
▸ Also test https://localhost:8003/test
10
BUILD AN ALEXA SKILL STEP-BY-STEP
Start a New Skill
▸ Fork the alexa-app starter template, if desired
https://github.com/rickwargo/alexa-app-template
▸ Clone into a directory under alexa-js-apps
cd ~/Code/alexa-js/alexa-js-apps
git clone https://github.com/rickwargo/alexa-app-template twitter-news
▸ Alternately, all code is available from Github (don’t do this if you want to code by
hand)
cd ~/Code/alexa-js/alexa-js-apps
git clone https://github.com/rickwargo/twitter-news
11
BUILD AN ALEXA SKILL STEP-BY-STEP
Install Node Modules
▸ Use npm install to download and install all modules in package.json
cd twitter-news
npm install
12
BUILD AN ALEXA SKILL STEP-BY-STEP
Test Fresh Installation
▸ Run the default tests using gulp
▸ test-mock runs the test runner framework (mocha, chai is the test framework) — only a few tests are shown below
gulp test-mock
[12:14:16] Using gulpfile ~/Code/alexa-js/alexa-js-apps/twitter-news/gulpfile.js
[12:14:16] Starting 'test-mock'...
App Starter Tests
starting up
✓ should fail if an unknown application id is provided
✓ should fail if a missing application is provided
...
My Intents
the story intent
✓ tells you the whole story
✓ tells a partial story when asked
Text
for exception message
✓ returns exception message if supplied
✓ returns message if supplied
21 passing (23ms)
[12:14:16] Finished 'test-mock' after 569 ms
13
BUILD AN ALEXA SKILL STEP-BY-STEP
Create an AWS IAM Role for Lambda Code Execution
▸ Name should be function name (later we’ll name it twitter-news-skill) followed by “-role”
aws iam create-role --role-name twitter-news-skill-role --assume-role-policy-document file://assets/json/aws/trust-policy.json
{
"Role": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": {
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
}
}
},
"RoleId": "ZG7523QZS8J7R951Y3C0J",
"CreateDate": "2017-02-27T17:59:56.785Z",
"RoleName": "twitter-news-skill-role",
"Path": "/",
"Arn": "arn:aws:iam::123456789012:role/twitter-news-skill-role"
}
}
▸ From the create-role output, copy Arn JSON value and update the role in config/aws-config.js
14
BUILD AN ALEXA SKILL STEP-BY-STEP
Attach Policy to Newly Created Role
▸ Attach an Amazon-managed policy to the twitter-news-skill-role
aws iam attach-role-policy --role-name twitter-news-skill-role --policy-arn
arn:aws:iam::aws:policy/AWSLambdaFullAccess
▸ Access can be changed by choosing a different policy below or roll your own
✦ AWSLambdaFullAccess
✦ AWSLambdaDynamoDBExecutionRole
✦ AWSLambdaBasicExecutionRole
15
BUILD AN ALEXA SKILL STEP-BY-STEP
Give the Alexa Service Access
▸ This is the same as adding the Alexa Skills Kit as a trigger to the Lambda
function
aws lambda add-permission --function-name twitter-news-skill --statement-id 1 --action
lambda:invokeFunction --principal alexa-appkit.amazon.com --region us-east-1
{
"Statement": "{"Sid":"1","Resource":"arn:aws:lambda:us-
east-1:100866613345:function:twitter-news-skill","Effect":"Allow","Principal":
{"Service":"alexa-appkit.amazon.com"},"Action":["lambda:invokeFunction"]}"
}
▸ More information can be found in the AWS Lambda Developer Guide
16
BUILD AN ALEXA SKILL STEP-BY-STEP
Edit config/aws-config.js prior to Pushing Lambda Code to AWS
▸ Ensure role is updated per Create an AWS IAM Role for Lambda Code Execution
▸ The region defaults to us-east-1 — update as necessary
▸ If you use a specific AWS credentials profile, update the profile value — defaults
to “default”.
▸ Update timeout and memorySize, if needed. The defaults of 3 seconds and
128MB are usually sufficient.
▸ Runtime should be nodejs4.3, unless a newer version was released after this
documentation
17
BUILD AN ALEXA SKILL STEP-BY-STEP
Update config/app-config.js prior to Pushing Lambda Code to AWS
▸ The applicationId can be left as-is until the skill is created on the Amazon
Alexa Developer Portal
▸ Update the applicationName to “twitter-news”
▸ Update the functionName to be the applicationName followed by 

“-skill”, so it would be “twitter-news-skill”
▸ Update the description to reflect the skill’s intent, i.e. “Grabs the latest or
popular tweets about a specific topic”
18
BUILD AN ALEXA SKILL STEP-BY-STEP
Update Config Tests in test/test_config.js
▸ Due to changes to some default settings, tests need to be updated to reflect the change(s)
▸ Update AWS Config —> Property —> region test if changed from us-east-1
▸ Update AWS Config —> Property —> runtime test if changed from nodejs4.3
▸ Update AWS Config —> Property —> applicationName test to reflect the new application
name
▸ For example, change test/test_config.js (around line 47) such that it reads:
it('applicationName is twitter-news', function () {

var result = config.applicationName;

return result.should.equal('twitter-news');

});
19
BUILD AN ALEXA SKILL STEP-BY-STEP
Push Code to AWS Lambda
▸ Upload the code to AWS Lambda using “gulp push”
gulp push
▸ Upon successful completion, the test-lambda gulp task will pass all tests
20
BUILD AN ALEXA SKILL STEP-BY-STEP
Connect to the Alexa Developer Portal
▸ Browse to the Alexa Developer Portal
▸ Press Get Started > on the Alexa Skills Kit button
21
BUILD AN ALEXA SKILL STEP-BY-STEP
Create The Skill on the Alexa Developer Portal
▸ Press Add a New Skill in the top-right of the following page
22
BUILD AN ALEXA SKILL STEP-BY-STEP
Fill Out the Skill Information
▸ Keep the Skill Type as Custom
Interaction Model
▸ Set the Name to the application name
(defined previously), Twitter News
▸ Set the invocation name to the
application name (in lower case),
twitter news
▸ Leave Audio Player defaulted to No
▸ Press the Save button
23
BUILD AN ALEXA SKILL STEP-BY-STEP
Get the AWS Lambda ARN for the Lambda Function
▸ In the terminal window, get the function definition
aws lambda get-function --function-name twitter-news-skill
{
"Code": {
"RepositoryType": "S3",
"Location": “https://prod-04-2014-tasks.s3.amazonaws.com/snapshots/123456789012/twitter-news-
skill-00000000-0000-0000-0000-000000000000?X-Amz-Security-Token=..."
},
"Configuration": {
"Version": "$LATEST",
"CodeSha256": "JZKRixkiCQ5NQwHt5/tUna61fqDDfnWGKfgsWnyUJKA=",
"FunctionName": "twitter-news-skill",
"MemorySize": 128,
"CodeSize": 6575734,
"FunctionArn": "arn:aws:lambda:us-east-1:123456789012:function:twitter-news-skill",
"Handler": "index.handler",
"Role": "arn:aws:iam::123456789012:role/twitter-news-skill-role",
"Timeout": 3,
"LastModified": "2017-02-27T18:40:44.411+0000",
"Runtime": "nodejs4.3",
"Description": "Grabs the latest or popular tweets about a specific topic"
}
}
24
BUILD AN ALEXA SKILL STEP-BY-STEP
Configure the New Skill
▸ Click Configuration to set the skill’s endpoint
▸ We’ll skip the Interaction Model for now until we
develop the code
▸ Select AWS Lambda ARN for the Service
Endpoint Type and select the North America
region
▸ Copy the FunctionARN value from the previous
step into the text box under North America
▸ Keep the default of No in Account Linking
▸ Press Save
25
BUILD AN ALEXA SKILL STEP-BY-STEP
Update the Skill’s Application Id in config/applicationid.json
▸ From the previous step, copy the ID in the top-left of the page (under the
application name Twitter News) and paste it into the value for applicationId
in config/applicationid.json
▸ application.json is not stored in Github to keep the Id private
{

"applicationId": "amzn1.ask.skill.00000000-0000-0000-0000-000000000000"

}
26
BUILD AN ALEXA SKILL STEP-BY-STEP
Update package.json
▸ Update package.json to set alexa.applicationId to the value Id found in
Configure the New Skill
▸ Update name to “twitter-news” (the name of the application specified in config/
app-config.js)
▸ Update the version, description, author, license, and other URLs as necessary
27
BUILD AN ALEXA SKILL STEP-BY-STEP
Remove Sample Code
▸ Remove the sample StoryIntent and supporting dictionary and custom slot type
in index.js:
▸ Delete the block beginning with: Object.assign(app.dictionary, {
▸ Delete the block beginning with: app.customSlotType('STORY_TYPE',
▸ Delete the block beginning with: app.intent('StoryIntent', {
▸ Remove all the tests in test/test_intents.js — these were for the sample code
28
BUILD AN ALEXA SKILL STEP-BY-STEP
Create a New Twitter Application
▸ A new Twitter application is needed to gain keys
and secrets for API access
▸ Browse to https://apps.twitter.com/
▸ Press Create New App and fill out details
▸ Name: My-Twitter-News
▸ Note the name may be taken by another
application. Try to prefix with your organization
or initials. This name is not important for the skill
- only the access tokens and keys are necessary.
▸ Description: Grabs the latest or popular tweets
about a specific topic
▸ Website: http://example.com/twitternews
29
BUILD AN ALEXA SKILL STEP-BY-STEP
Grant Permissions to Twitter Application
▸ For this skill, we’ll only need read permission
▸ On the Permissions tab, select Read only
and press Update Settings
30
BUILD AN ALEXA SKILL STEP-BY-STEP
Twitter Application Keys and Access Tokens
▸ You’ll need both consumer and access token
▸ Click on the Keys and Access Tokens tab
▸ Near the bottom of the page press Create my access token. This will
provide the Access Token and Access Token Secret necessary to
connect to the Twitter API.
▸ Save the values and add to your environment under the following
environment variable names:
▸ TWITTER_CONSUMER_KEY
▸ TWITTER_CONSUMER_SECRET
▸ TWITTER_ACCESS_TOKEN_KEY
▸ TWITTER_ACCESS_TOKEN_SECRET
31
Not my real keys :)
Don’t skip the step! You’ll need to take appropriate actions
depending on your OS. For example, on Linux and OS X:



# Keys for twitter-news-skill

export TWITTER_CONSUMER_KEY='consumer key'

export TWITTER_CONSUMER_SECRET='consumer secret'

export TWITTER_ACCESS_TOKEN_KEY='token key'

export TWITTER_ACCESS_TOKEN_SECRET='token secret'
BUILD AN ALEXA SKILL STEP-BY-STEP
Configure Your Environment for Access to the Twitter
‣ Configure environment for keys for access to the Twitter API
‣ For OS X and Linux, add to ~/.bash_profile (or ~/.bashrc)
# Keys for twitter-news-skill
export TWITTER_CONSUMER_KEY=hSYvOtda3Ri74PkyuTOHrLMdf
export TWITTER_CONSUMER_SECRET=LXHvTRShADq0s8lOlHCPodPw1smNeJ5p6E8GyOlY9cM0Ti5QSX
export TWITTER_ACCESS_TOKEN_KEY=WVUXxMzZPrszP2AO3eQIogJNFIA2vqkO5bmRkCiO1zCdr7KSt6
export TWITTER_ACCESS_TOKEN_SECRET=tMOuVnb3nrlwtNgUtr9qCZTdEqj6SpqbJrt7uysGuf5oU
‣ Log out and log in again to set up environment
Not my real keys :)
32
BUILD AN ALEXA SKILL STEP-BY-STEP
Set Lambda Environment Variables for Access to Twitter
▸ After configuring a New
Twitter App, two pairs of
Keys/Secrets are available
for use
▸ Copy them and paste into
the Environment variables
section
▸ Enable encryption helpers
for more security
33
Not my real keys :)
BUILD AN ALEXA SKILL STEP-BY-STEP
Create Twitter Module to Gain Access to Twitter API
▸ Create lib/twitter.js and add the following code:
var Twitter = require('twitter');



/**

* Connect to the Twitter API. Gain access via environment variables.

* Optionally replace with actual strings (not recommended).

*/

var client = new Twitter({

consumer_key: process.env.TWITTER_CONSUMER_KEY,

consumer_secret: process.env.TWITTER_CONSUMER_SECRET,

access_token_key: process.env.TWITTER_ACCESS_TOKEN_KEY,

access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET

});



module.exports = client;
34
BUILD AN ALEXA SKILL STEP-BY-STEP
Add Tests for Twitter Module
▸ Create test/test_twitter.js and add the following code:
/*global describe, it, beforeEach */



'use strict';



var chai = require('chai'),

chaiAsPromised = require('chai-as-promised');



chai.use(chaiAsPromised);

chai.should();



////////////// Tests Twitter //////////////



describe('Twitter', function () {

describe('New Client', function () {

var twitter;

beforeEach(function () {

// here for code coverage

twitter = require('../lib/twitter');

});



it('should return an object', function () {

return twitter.should.be.an('object');

});

it('should have a version of at least 1.7.0', function () {

var versionCompare = require('./../vendor/version_compare');

var comparison = versionCompare(twitter.VERSION, '1.7.0');

return comparison.should.be.at.least(0); // same or higher version

});

});

});
35
BUILD AN ALEXA SKILL STEP-BY-STEP
Run Twitter Tests
▸ Run tests again, testing recently added Twitter tests
gulp test-mock # (or simply use the alias test, gulp test)
...
Twitter
New Client
✓ should return an object
✓ should have a version of at least 1.7.0
21 passing (32ms)
[10:59:20] Finished 'test-mock' after 338 ms
36
BUILD AN ALEXA SKILL STEP-BY-STEP
Create the Intent — WhosTweeted
▸ This intent is designed to return the last N unique twitterers from tweets matching our search criteria
▸ This is a simple intent: it doesn’t take any slot values
▸ It is invoked when the Echo understands one of the following utterances while in the skill:
▸ Who tweeted recently
▸ Who shared recently
▸ Who recently tweeted
▸ Who recently shared
▸ It depends on being able to grab the latest tweets
▸ It depends on a function to take the latest tweets and find the last N unique twitterers (uniqueTwitterers)
▸ It depends on a function to take the last N unique twitterers and format them for output (recentTweetsFrom)
37
BUILD AN ALEXA SKILL STEP-BY-STEP
Create Unique Twitterers Function and Associated Tests
▸ Create the following files using the code available in https://github.com/
rickwargo/twitter-news
▸ lib/helpers/unique_twitterers.js
▸ lib/constants.js
▸ test/test_unique_twitterers.js
38
BUILD AN ALEXA SKILL STEP-BY-STEP
Run Twitter Tests for Unique Twitterers Function
▸ Run tests again, testing recently added Twitter tests
gulp test
...
Unique Twitterers
Users
of no length
✓ should be an empty list
of one unique user
✓ should be list of length one
✓ should be list of length one if duplicates
of multiple unique users
✓ should be a list of the unique users
✓ should be list of the unique users
26 passing (34ms)
39
BUILD AN ALEXA SKILL STEP-BY-STEP
Create Recent Tweets From Function and Associated Tests
▸ Create the following functions using the code available in https://github.com/rickwargo/twitter-news/blob/master/lib/text.js
▸ recentTweetsFrom
▸ noRecentTweets
▸ Add tests for recentTweetsFrom in test/test_text.js
describe('for recent tweets from', function () {

it('returns no one if no recent tweets', function () {

var result = Text.recentTweetsFrom([]);

return result.should.equal(Text.noRecentTweets);

});

it('returns one user if only one user', function () {

var result = Text.recentTweetsFrom(['alpha']);

return result.should.equal('Recent tweets were from: alpha.');

});

it('returns one user if only one user', function () {

var result = Text.recentTweetsFrom(['alpha', 'beta', 'gamma']);

return result.should.equal('Recent tweets were from: alpha, beta, and gamma.');

});

});
▸ Run tests using “gulp test” — there should now be 29 passing tests
40
BUILD AN ALEXA SKILL STEP-BY-STEP
Create the WhoTweeted Intent Handler in index.js
▸ Add the following code into index.js
app.intent('WhoTweeted', {

utterances: [

'Who {tweeted|shared} {recently|}',

'Who recently {tweeted|shared}'

]

}, function (ignore, response) {

return Twitter.get('search/tweets', TwitterParams)

.then(function (tweets) {

var users = uniqueTwitterers(tweets.statuses, Constants.MAX_USERS);

var msg = Text.recentTweetsFrom(users);



response.say(msg);

});

});
▸ Add the following requires to index.js
Twitter = require('./lib/twitter'),

Text = require('./lib/text'),

Constants = require('./lib/constants'),

uniqueTwitterers = require('./lib/helpers/unique_twitterers');

41
BUILD AN ALEXA SKILL STEP-BY-STEP
alexa-utterances
▸ Utterances are kept with the skill definition in the code
▸ Utterances are condensed using alternation, being able to expand the
utterance with each word in the curly braces using the alexa-utterances node
module
▸ This module is installed by default with the starter template
▸ For more information refer to the project’s README
42
BUILD AN ALEXA SKILL STEP-BY-STEP
Add Tests for WhosTweeted in test/test_intents.js
▸ For testing, stub the Twitter.get() function with “sinon” returning a promise as the stub result instead of a call to the Twitter API
▸ To stub Twitter.get(), Add the following code before the tests
var sinon = require('sinon');

var sinonStubPromise = require('sinon-stub-promise');

sinonStubPromise(sinon);
▸ Add the following require’s
Text = require('./lib/text'),

Twitter = require(‘./lib/twitter');
▸ Add the following tests
▸ Include code block from around line 41 starting with describe('#WhoTweeted', function () {
▸ Wrap the preceding code block with:
describe('using a mock client', function () {

var get;

beforeEach(function () {

get = sinon.stub(Twitter, 'get').returnsPromise();

});

afterEach(function () {

get.restore();

});
// #WhoTweeted tests go here
});
▸ Run tests using “gulp test” — there should now be 32 passing tests
43
BUILD AN ALEXA SKILL STEP-BY-STEP
Create the Intent — LatestTweets
▸ This intent is designed to return the last N tweets matching our search criteria
▸ This intent takes three slot values, two standard Amazon slot types and one custom slot type
▸ It is invoked when the Echo understands one of the following utterances while in the skill:
▸ What’s the most recent tweet
▸ For the news
▸ What are the last three tweets
▸ The last tweet from Rick
▸ It depends on being able to grab the latest tweets
▸ It depends on a function to take the last N tweets and format them for output (tweet2say)
44
BUILD AN ALEXA SKILL STEP-BY-STEP
Create Text Functions and Associated Tests
▸ Create the following functions using the code available in https://github.com/rickwargo/twitter-news/blob/master/lib/text.js
▸ lastTweets
▸ noMatchingTweets
▸ Add tests for lastTweets in test/test_text.js
describe('for LastTweet', function () {

describe('of a single item', function () {

it('is singular in its response', function () {

var result = Text.lastTweets(1);

return result.should.equal('The last 1 tweet was: ');

});

it('is plural in its response', function () {

var result = Text.lastTweets(2);

return result.should.equal('The last 2 tweets were: ');

});

});

});
▸ Run tests using “gulp test” — there should now be 34 passing tests
45
BUILD AN ALEXA SKILL STEP-BY-STEP
Create tweet2say Function and Associated Tests
▸ Create the tweet2say function using the code available in https://github.com/
rickwargo/twitter-news/blob/master/lib/helpers/tweet2say.js
▸ Create tests for the tweet2say function using the code available in https://
github.com/rickwargo/twitter-news/blob/master/test/test_tweet2say.js
▸ Run tests using “gulp test” — there should now be 41 passing tests
46
BUILD AN ALEXA SKILL STEP-BY-STEP
Prepare the LatestTweets Intent Handler in index.js
▸ Add the require for tweet2say to index.js
tweet2say = require('./lib/helpers/tweet2say'),
▸ Add dictionary near the top of index.js
Object.assign(app.dictionary, {

tweet: ['tweet', 'tweets', 'item', 'items', 'story', 'stories', 'news', 'news item', 

'news items', 'news story', 'news stories', 'post', 'posts', 'update', 'updates', 

'message', 'messages'],

whats: ['what is', 'what are', 'what's', 'about', 'give me', 'tell me'],

the: ['the', 'a', 'an']

});
▸ Add the custom slot for the intent handler to index.js
app.customSlotType('TWEET_CATEGORIES', ['popular', 'latest', 'recent', 'last']);

47
BUILD AN ALEXA SKILL STEP-BY-STEP
Create the LatestTweets Intent Handler in index.js
▸ Add the following code to index.js
var TwitterParams = {

q: '#PhillyCode OR #PhillyCC OR @PhillyDotNet',

result_type: 'recent', // options: 'recent', 'mixed', or 'popular'

since_id: '',

include_entities: false

};

app.intent('LatestTweets', {

slots: {

Count: 'AMAZON.NUMBER',

User: 'AMAZON.US_FIRST_NAME',

TweetCategory: 'TWEET_CATEGORIES'

},

utterances: [

'{whats|} {the} {tweet}',

'{whats|} {-|Count} {tweet}',

'{whats|} {the} {most|} {-|TweetCategory} {tweet}',

'{whats|} {the} {most|} {-|TweetCategory} {-|Count} {tweet}',

'{whats|} {the} {most|} {-|TweetCategory} {tweet} from {-|User}'

]

}, function (request, response) {
48
BUILD AN ALEXA SKILL STEP-BY-STEP
Create the LatestTweets Intent Handler in index.js (cont’d)
▸ Add the following code to the end of the intent handler for LatestTweets in index.js
}, function (request, response) {

var max_tweets = Math.min(request.slot('Count') || 1, Constants.MAX_TWEETS);

var user = request.slot('User') || null;

var tweetCategory = request.slot('TweetCategory') || 'recent';



TwitterParams.result_type = tweetCategory.toLowerCase() === 'popular'

? 'popular'

: 'recent';

return Twitter.get('search/tweets', TwitterParams)

.then(function (tweets) { // Filter

var counter = 0;

return tweets.statuses.filter(function (tweet) {

// select if within max tweets and user matches, if specified

var select = (counter < max_tweets) && (!user || tweet.user.name.toLowerCase().indexOf(user.toLowerCase()) > -1);

if (select) {

counter += 1;

}

return select;

});

})

.then(function (tweets) { // Say matching tweets

var msg;

if (tweets.length > 0) {

msg = Text.lastTweets(tweets.length) + tweet2say(tweets);

} else {

msg = Text.noMatchingTweets;

}

response.say(msg);

});

});
49
BUILD AN ALEXA SKILL STEP-BY-STEP
Add Tests for LatestTweets in test/test_intents.js
▸ Add the following tests
▸ Include code block from around line 79 starting with describe('#LatestTweets', function () {
▸ Run tests using “gulp test” — there should now be 52 passing tests
▸ Add a test against the Twitter API instead of a mock
describe('against the Twitter API', function () {

describe('#LatestTweets', function () {

describe('response', function () {

it('contains the latest tweets', function () {

var result = request.intentRequest({name: 'LatestTweets'});

return result.should.eventually.match(/<speak>The last 1 tweet was:/);

});

});

});

});
▸ Run tests again using “gulp test” — there should now be 53 passing tests
50
BUILD AN ALEXA SKILL STEP-BY-STEP
Start Web Server for Testing Using the Web-based Interface
▸ Start the server with “npm start”
npm start
> alexa-app-root@1.0.0 start /Users/rick/Code/alexa-js/alexa-app-root
> node server.js --start
serving static content from: /Users/rick/Code/alexa-js/alexa-app-root/public_html
loading server-side modules from: /Users/rick/Code/alexa-js/alexa-app-root/server
loaded /Users/rick/Code/alexa-js/test/alexa-app-root/server/.gitkeep
loading apps from: /Users/rick/Code/alexa-js/alexa-js-apps/
loaded app [twitter-news] at endpoint: /alexa/twitter-news
enabling https
listening on https port 8443
listening on http port 8003
51
BUILD AN ALEXA SKILL STEP-BY-STEP
Test Using the Web-based Interface
▸ Browse to http://localhost:8003/test/
▸ There should only be one app loaded:
twitter-news
▸ Click on Launch Request and press
submit; the welcome message should
appear. You can update the welcome
message in lib/text.js at
onLaunchPrompt.
▸ Experiment with the various intents to see
if they work as expected
52
BUILD AN ALEXA SKILL STEP-BY-STEP
Finalize Alexa Skill Configuration — Intent Schema
▸ Populate Interaction Model
▸ Using the test web page, copy the Schema (click on Schema in top-right and
then clock Copy to Clipboard) and paste into Intent Schema in Alexa Skill
page
53
BUILD AN ALEXA SKILL STEP-BY-STEP
Finalize Alexa Skill Configuration — Custom Slot Types
▸ Add a Custom Slot Type by pressing Add Slot Type and enter
TWEET_CATEGORIES for the type and the list of slot types from the test web
page under Values
54
BUILD AN ALEXA SKILL STEP-BY-STEP
Finalize Alexa Skill Configuration — Sample Utterances
▸ Add to Sample Utterances the list of utterances generated from the test web
page. Note how only a few lines of utterances in the code expanded to over
2,600 different utterances!
55
BUILD AN ALEXA SKILL STEP-BY-STEP
Build the Alexa Skill Interaction Model
▸ When all three areas are populated, press Save to build the interaction model
▸ You’ll see a message while it is building. It may take up to a minute to build the
model.
56
BUILD AN ALEXA SKILL STEP-BY-STEP
Test Skill from Lambda - Create Test Event
▸ Select Configure test event from the Actions menu
57
BUILD AN ALEXA SKILL STEP-BY-STEP
Test Skill from Lambda - Input Test Event
▸ Do not select a Sample event template -
just paste over what is there
▸ Copy the JSON from the Request tab on
the web test page and paste into the
code area
▸ Press Save
58
BUILD AN ALEXA SKILL STEP-BY-STEP
Test Skill from Lambda - Perform the Test
▸ Press Test
▸ The Execution result should
show succeeded
59
BUILD AN ALEXA SKILL STEP-BY-STEP
Test Skill from Alexa Skill Portal - Select Test Pane
▸ Press Test in the left panel to bring up the testing pane
60
BUILD AN ALEXA SKILL STEP-BY-STEP
Test Skill from Alexa Skill Portal - Perform Test
▸ In the Service Simulator, enter what
is the latest news under Enter
Utterance and press Ask Twitter
News
▸ A valid Lambda Response should
appear
61
BUILD AN ALEXA SKILL STEP-BY-STEP
Test Skill using echosim.io
▸ Go to https://echosim.io and sign in
to Echosim.io using your Amazon
account
▸ Don’t worry, it’s safe as it uses
OAUTH
62
BUILD AN ALEXA SKILL STEP-BY-STEP
Test Skill using echosim.io by Speaking
▸ Press the record button and say Ask
Twitter News for the latest
▸ You should hear the latest tweet
▸ Try testing other utterances
63
BUILD AN ALEXA SKILL STEP-BY-STEP
Test on Your Own Device
▸ If your Echo is linked to the same account as your Amazon developer account,
the skill is automatically enabled on your Echo and any other devices linked to
the same account
▸ Repeat the same questions to your Amazon Echo
▸ The skill is now ready for your enjoyment and tweaking!
64
BUILD AN ALEXA SKILL STEP-BY-STEP
Contact Me
▸ https://www.rickwargo.com/
▸ https://github.com/rickwargo
▸ https://linkedin.com/in/rickwargo
▸ contact@epicminds.com
▸ @rickwargo
▸ https://github.com/rickwargo/twitter-news
▸ https://github.com/rickwargo/alexa-app-root
▸ https://github.com/rickwargo/alexa-app-template
65

Weitere ähnliche Inhalte

Was ist angesagt?

An Introduction to Using AWS and ASK to Build Voice Driven Experiences
An Introduction to Using AWS and ASK to Build Voice Driven ExperiencesAn Introduction to Using AWS and ASK to Build Voice Driven Experiences
An Introduction to Using AWS and ASK to Build Voice Driven ExperiencesAmazon Web Services
 
David Isbitski - Enabling new voice experiences with Amazon Alexa and AWS Lambda
David Isbitski - Enabling new voice experiences with Amazon Alexa and AWS LambdaDavid Isbitski - Enabling new voice experiences with Amazon Alexa and AWS Lambda
David Isbitski - Enabling new voice experiences with Amazon Alexa and AWS LambdaWithTheBest
 
Voice enable all the things with Alexa
Voice enable all the things with AlexaVoice enable all the things with Alexa
Voice enable all the things with AlexaMark Bate
 
AWS re:Invent 2016: Voice-enabling Your Home and Devices with Amazon Alexa an...
AWS re:Invent 2016: Voice-enabling Your Home and Devices with Amazon Alexa an...AWS re:Invent 2016: Voice-enabling Your Home and Devices with Amazon Alexa an...
AWS re:Invent 2016: Voice-enabling Your Home and Devices with Amazon Alexa an...Amazon Web Services
 
Creating IoT Solutions with Serverless Architecture & Alexa
Creating IoT Solutions with Serverless Architecture & AlexaCreating IoT Solutions with Serverless Architecture & Alexa
Creating IoT Solutions with Serverless Architecture & AlexaAmazon Web Services
 
Serverless Workflows on AWS - A Journey from SWF to Step Functions
Serverless Workflows on AWS - A Journey from SWF to Step FunctionsServerless Workflows on AWS - A Journey from SWF to Step Functions
Serverless Workflows on AWS - A Journey from SWF to Step FunctionsForrest Brazeal
 
Amazon Alexa Development Overview
Amazon Alexa Development OverviewAmazon Alexa Development Overview
Amazon Alexa Development OverviewJohn Brady
 
Building Smart Home skills for Alexa
Building Smart Home skills for AlexaBuilding Smart Home skills for Alexa
Building Smart Home skills for AlexaAWS Germany
 
Advanced Serverless Apps With Step Functions
Advanced Serverless Apps With Step FunctionsAdvanced Serverless Apps With Step Functions
Advanced Serverless Apps With Step FunctionsAmazon Web Services
 
Writing Alexa Voice Skills With NodeJS (with a little IoT)
Writing Alexa Voice Skills With NodeJS (with a little IoT)Writing Alexa Voice Skills With NodeJS (with a little IoT)
Writing Alexa Voice Skills With NodeJS (with a little IoT)David Janes
 
Serverless Development Deep Dive
Serverless Development Deep DiveServerless Development Deep Dive
Serverless Development Deep DiveAmazon Web Services
 
Why your next serverless project should use AWS AppSync
Why your next serverless project should use AWS AppSyncWhy your next serverless project should use AWS AppSync
Why your next serverless project should use AWS AppSyncYan Cui
 
Building Advanced Serverless Applications
Building Advanced Serverless ApplicationsBuilding Advanced Serverless Applications
Building Advanced Serverless ApplicationsAmazon Web Services
 
ALX315_Test Automation for Alexa Skills
ALX315_Test Automation for Alexa SkillsALX315_Test Automation for Alexa Skills
ALX315_Test Automation for Alexa SkillsAmazon Web Services
 
Do more with less code in serverless
Do more with less code in serverlessDo more with less code in serverless
Do more with less code in serverlessjeromevdl
 
DIY Your Amazon Echo
DIY Your Amazon EchoDIY Your Amazon Echo
DIY Your Amazon EchoVictor Sue
 
Building Chatbots with Amazon Lex
Building Chatbots with Amazon LexBuilding Chatbots with Amazon Lex
Building Chatbots with Amazon LexAmazon Web Services
 
Getting Started with AWS Lambda & Serverless Computing
Getting Started with AWS Lambda & Serverless ComputingGetting Started with AWS Lambda & Serverless Computing
Getting Started with AWS Lambda & Serverless ComputingAmazon Web Services
 
Building APIs with Amazon API Gateway: re:Invent 2018 Recap at the AWS Loft -...
Building APIs with Amazon API Gateway: re:Invent 2018 Recap at the AWS Loft -...Building APIs with Amazon API Gateway: re:Invent 2018 Recap at the AWS Loft -...
Building APIs with Amazon API Gateway: re:Invent 2018 Recap at the AWS Loft -...Amazon Web Services
 
Serverless Architectural Patterns
Serverless Architectural PatternsServerless Architectural Patterns
Serverless Architectural PatternsAmazon Web Services
 

Was ist angesagt? (20)

An Introduction to Using AWS and ASK to Build Voice Driven Experiences
An Introduction to Using AWS and ASK to Build Voice Driven ExperiencesAn Introduction to Using AWS and ASK to Build Voice Driven Experiences
An Introduction to Using AWS and ASK to Build Voice Driven Experiences
 
David Isbitski - Enabling new voice experiences with Amazon Alexa and AWS Lambda
David Isbitski - Enabling new voice experiences with Amazon Alexa and AWS LambdaDavid Isbitski - Enabling new voice experiences with Amazon Alexa and AWS Lambda
David Isbitski - Enabling new voice experiences with Amazon Alexa and AWS Lambda
 
Voice enable all the things with Alexa
Voice enable all the things with AlexaVoice enable all the things with Alexa
Voice enable all the things with Alexa
 
AWS re:Invent 2016: Voice-enabling Your Home and Devices with Amazon Alexa an...
AWS re:Invent 2016: Voice-enabling Your Home and Devices with Amazon Alexa an...AWS re:Invent 2016: Voice-enabling Your Home and Devices with Amazon Alexa an...
AWS re:Invent 2016: Voice-enabling Your Home and Devices with Amazon Alexa an...
 
Creating IoT Solutions with Serverless Architecture & Alexa
Creating IoT Solutions with Serverless Architecture & AlexaCreating IoT Solutions with Serverless Architecture & Alexa
Creating IoT Solutions with Serverless Architecture & Alexa
 
Serverless Workflows on AWS - A Journey from SWF to Step Functions
Serverless Workflows on AWS - A Journey from SWF to Step FunctionsServerless Workflows on AWS - A Journey from SWF to Step Functions
Serverless Workflows on AWS - A Journey from SWF to Step Functions
 
Amazon Alexa Development Overview
Amazon Alexa Development OverviewAmazon Alexa Development Overview
Amazon Alexa Development Overview
 
Building Smart Home skills for Alexa
Building Smart Home skills for AlexaBuilding Smart Home skills for Alexa
Building Smart Home skills for Alexa
 
Advanced Serverless Apps With Step Functions
Advanced Serverless Apps With Step FunctionsAdvanced Serverless Apps With Step Functions
Advanced Serverless Apps With Step Functions
 
Writing Alexa Voice Skills With NodeJS (with a little IoT)
Writing Alexa Voice Skills With NodeJS (with a little IoT)Writing Alexa Voice Skills With NodeJS (with a little IoT)
Writing Alexa Voice Skills With NodeJS (with a little IoT)
 
Serverless Development Deep Dive
Serverless Development Deep DiveServerless Development Deep Dive
Serverless Development Deep Dive
 
Why your next serverless project should use AWS AppSync
Why your next serverless project should use AWS AppSyncWhy your next serverless project should use AWS AppSync
Why your next serverless project should use AWS AppSync
 
Building Advanced Serverless Applications
Building Advanced Serverless ApplicationsBuilding Advanced Serverless Applications
Building Advanced Serverless Applications
 
ALX315_Test Automation for Alexa Skills
ALX315_Test Automation for Alexa SkillsALX315_Test Automation for Alexa Skills
ALX315_Test Automation for Alexa Skills
 
Do more with less code in serverless
Do more with less code in serverlessDo more with less code in serverless
Do more with less code in serverless
 
DIY Your Amazon Echo
DIY Your Amazon EchoDIY Your Amazon Echo
DIY Your Amazon Echo
 
Building Chatbots with Amazon Lex
Building Chatbots with Amazon LexBuilding Chatbots with Amazon Lex
Building Chatbots with Amazon Lex
 
Getting Started with AWS Lambda & Serverless Computing
Getting Started with AWS Lambda & Serverless ComputingGetting Started with AWS Lambda & Serverless Computing
Getting Started with AWS Lambda & Serverless Computing
 
Building APIs with Amazon API Gateway: re:Invent 2018 Recap at the AWS Loft -...
Building APIs with Amazon API Gateway: re:Invent 2018 Recap at the AWS Loft -...Building APIs with Amazon API Gateway: re:Invent 2018 Recap at the AWS Loft -...
Building APIs with Amazon API Gateway: re:Invent 2018 Recap at the AWS Loft -...
 
Serverless Architectural Patterns
Serverless Architectural PatternsServerless Architectural Patterns
Serverless Architectural Patterns
 

Ähnlich wie Build an Alexa Skill Step-by-Step

Containerizing your Security Operations Center
Containerizing your Security Operations CenterContainerizing your Security Operations Center
Containerizing your Security Operations CenterJimmy Mesta
 
What Is AWS Elastic Kubernetes Service
 What Is AWS Elastic Kubernetes Service What Is AWS Elastic Kubernetes Service
What Is AWS Elastic Kubernetes ServiceAMELIAOLIVIA2
 
How to build an event-driven, polyglot serverless microservices framework on ...
How to build an event-driven, polyglot serverless microservices framework on ...How to build an event-driven, polyglot serverless microservices framework on ...
How to build an event-driven, polyglot serverless microservices framework on ...Animesh Singh
 
Docker for developers on mac and windows
Docker for developers on mac and windowsDocker for developers on mac and windows
Docker for developers on mac and windowsDocker, Inc.
 
Laravel, docker, kubernetes
Laravel, docker, kubernetesLaravel, docker, kubernetes
Laravel, docker, kubernetesPeter Mein
 
DCEU 18: Docker Containers in a Serverless World
DCEU 18: Docker Containers in a Serverless WorldDCEU 18: Docker Containers in a Serverless World
DCEU 18: Docker Containers in a Serverless WorldDocker, Inc.
 
Cloud-native applications with Java and Kubernetes - Yehor Volkov
 Cloud-native applications with Java and Kubernetes - Yehor Volkov Cloud-native applications with Java and Kubernetes - Yehor Volkov
Cloud-native applications with Java and Kubernetes - Yehor VolkovKuberton
 
From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...
From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...
From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...Alexander Dean
 
OpenFaaS JeffConf 2017 - Milan
OpenFaaS JeffConf 2017 - MilanOpenFaaS JeffConf 2017 - Milan
OpenFaaS JeffConf 2017 - MilanAlex Ellis
 
Containers as a Service with Docker
Containers as a Service with DockerContainers as a Service with Docker
Containers as a Service with DockerDocker, Inc.
 
Docker Container As A Service - March 2016
Docker Container As A Service - March 2016Docker Container As A Service - March 2016
Docker Container As A Service - March 2016Patrick Chanezon
 
GDG-ANDROID-ATHENS Meetup: Build in Docker with Jenkins
GDG-ANDROID-ATHENS Meetup: Build in Docker with Jenkins GDG-ANDROID-ATHENS Meetup: Build in Docker with Jenkins
GDG-ANDROID-ATHENS Meetup: Build in Docker with Jenkins Mando Stam
 
Kubernetes workshop -_the_basics
Kubernetes workshop -_the_basicsKubernetes workshop -_the_basics
Kubernetes workshop -_the_basicsSjuul Janssen
 
Docker Security workshop slides
Docker Security workshop slidesDocker Security workshop slides
Docker Security workshop slidesDocker, Inc.
 
Zero to Continuous Delivery on Google Cloud
Zero to Continuous Delivery on Google CloudZero to Continuous Delivery on Google Cloud
Zero to Continuous Delivery on Google CloudJames Heggs
 
Ansible Automation to Rule Them All
Ansible Automation to Rule Them AllAnsible Automation to Rule Them All
Ansible Automation to Rule Them AllTim Fairweather
 
Paul Angus (ShapeBlue) - Push infrastructure with Ansible #DOXLON
Paul Angus (ShapeBlue) - Push infrastructure with Ansible #DOXLONPaul Angus (ShapeBlue) - Push infrastructure with Ansible #DOXLON
Paul Angus (ShapeBlue) - Push infrastructure with Ansible #DOXLONOutlyer
 
Into The Box | Alexa and ColdBox Api's
Into The Box | Alexa and ColdBox Api'sInto The Box | Alexa and ColdBox Api's
Into The Box | Alexa and ColdBox Api'sOrtus Solutions, Corp
 

Ähnlich wie Build an Alexa Skill Step-by-Step (20)

Helm intro
Helm introHelm intro
Helm intro
 
Containerizing your Security Operations Center
Containerizing your Security Operations CenterContainerizing your Security Operations Center
Containerizing your Security Operations Center
 
What Is AWS Elastic Kubernetes Service
 What Is AWS Elastic Kubernetes Service What Is AWS Elastic Kubernetes Service
What Is AWS Elastic Kubernetes Service
 
How to build an event-driven, polyglot serverless microservices framework on ...
How to build an event-driven, polyglot serverless microservices framework on ...How to build an event-driven, polyglot serverless microservices framework on ...
How to build an event-driven, polyglot serverless microservices framework on ...
 
Docker for developers on mac and windows
Docker for developers on mac and windowsDocker for developers on mac and windows
Docker for developers on mac and windows
 
Laravel, docker, kubernetes
Laravel, docker, kubernetesLaravel, docker, kubernetes
Laravel, docker, kubernetes
 
DCEU 18: Docker Containers in a Serverless World
DCEU 18: Docker Containers in a Serverless WorldDCEU 18: Docker Containers in a Serverless World
DCEU 18: Docker Containers in a Serverless World
 
Salesforce CLI
Salesforce CLISalesforce CLI
Salesforce CLI
 
Cloud-native applications with Java and Kubernetes - Yehor Volkov
 Cloud-native applications with Java and Kubernetes - Yehor Volkov Cloud-native applications with Java and Kubernetes - Yehor Volkov
Cloud-native applications with Java and Kubernetes - Yehor Volkov
 
From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...
From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...
From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...
 
OpenFaaS JeffConf 2017 - Milan
OpenFaaS JeffConf 2017 - MilanOpenFaaS JeffConf 2017 - Milan
OpenFaaS JeffConf 2017 - Milan
 
Containers as a Service with Docker
Containers as a Service with DockerContainers as a Service with Docker
Containers as a Service with Docker
 
Docker Container As A Service - March 2016
Docker Container As A Service - March 2016Docker Container As A Service - March 2016
Docker Container As A Service - March 2016
 
GDG-ANDROID-ATHENS Meetup: Build in Docker with Jenkins
GDG-ANDROID-ATHENS Meetup: Build in Docker with Jenkins GDG-ANDROID-ATHENS Meetup: Build in Docker with Jenkins
GDG-ANDROID-ATHENS Meetup: Build in Docker with Jenkins
 
Kubernetes workshop -_the_basics
Kubernetes workshop -_the_basicsKubernetes workshop -_the_basics
Kubernetes workshop -_the_basics
 
Docker Security workshop slides
Docker Security workshop slidesDocker Security workshop slides
Docker Security workshop slides
 
Zero to Continuous Delivery on Google Cloud
Zero to Continuous Delivery on Google CloudZero to Continuous Delivery on Google Cloud
Zero to Continuous Delivery on Google Cloud
 
Ansible Automation to Rule Them All
Ansible Automation to Rule Them AllAnsible Automation to Rule Them All
Ansible Automation to Rule Them All
 
Paul Angus (ShapeBlue) - Push infrastructure with Ansible #DOXLON
Paul Angus (ShapeBlue) - Push infrastructure with Ansible #DOXLONPaul Angus (ShapeBlue) - Push infrastructure with Ansible #DOXLON
Paul Angus (ShapeBlue) - Push infrastructure with Ansible #DOXLON
 
Into The Box | Alexa and ColdBox Api's
Into The Box | Alexa and ColdBox Api'sInto The Box | Alexa and ColdBox Api's
Into The Box | Alexa and ColdBox Api's
 

Kürzlich hochgeladen

AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?XfilesPro
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 

Kürzlich hochgeladen (20)

AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 

Build an Alexa Skill Step-by-Step

  • 1. RICK WARGO - MAR 2017 BUILD AN ALEXA SKILL STEP-BY-STEP 1
  • 2. BUILD AN ALEXA SKILL STEP-BY-STEP Introduction ▸ This tutorial will guide you step-by-step to create a new Alexa skill ▸ This example skill will interface with Twitter and read recent tweets from a query ▸ The aim is to be able to extend this workflow for your own use ▸ This skill will be called Twitter News and will be private ▸ This tutorial will not cover publishing a new skill - there is plenty of available documentation on how to publish ▸ Please let me know if you use this to build a new skill — I welcome feedback! 2
  • 3. BUILD AN ALEXA SKILL STEP-BY-STEP Sample Interactions — Define Prior to Building New Skill ▸ The critical path to creating a great skill is pre-visualization of the skill ▸ Try to define the interactions as much as possible and maintain in a file, for example, Examples.txt ▸ Q: What's the latest news? ▸ A: The last 1 tweet was: Rick Wargo tweeted: Join me this Sat at 11:30am - we'll build an Alexa skill that interfaces with Twitter at #PhillyCode @PhillyDotNet. ▸ Q: What's the latest popular tweet? ▸ A: There were no matching tweets. ▸ Q: What is the last 5 tweets? ▸ A: The last 5 tweets were: Rick Wargo tweeted: Join me this Sat at 11:30am - we'll build an Alexa skill that interfaces with Twitter at #PhillyCode @PhillyDotNet. Alina retweeted Stratisplatform's tweet: #Stratis are gold sponsors @PhillyDotNet on 24th-25th February explaining our #blockchain t… ▸ Q: What is the last tweet from Rick? ▸ A: The last 1 tweet was: Rick Wargo tweeted: Join me this Sat at 11:30am - we'll build an Alexa skill that interfaces with Twitter at #PhillyCode @PhillyDotNet. ▸ Q: Who tweeted? ▸ A: Recent tweets were from: Rick Wargo, Kucilo Oro, Alina, XTexplorer, and Mohammad Khalid. ▸ Q: Who shared? ▸ A: Recent tweets were from: Rick Wargo, Kucilo Oro, Alina, XTexplorer, and Mohammad Khalid. 3
  • 4. BUILD AN ALEXA SKILL STEP-BY-STEP Assumptions ▸ Implementing on OSX 10.12.3 ▸ Using AWS Lambda and Node.js 4.3 to host code ▸ Linux-style commands used throughout # Commands to be executed at the command line are in this style ▸ Input from interactive commands is in bold text ▸ References to files point to the completed version of the twitter-news-skill in Github ▸ Depending on copy/paste, some files may require retouching, mostly white-space, for lint to succeed ▸ All commands to be executed from skill directory unless otherwise noted ▸ Should work with slight modifications on Windows 4
  • 5. BUILD AN ALEXA SKILL STEP-BY-STEP User Interaction Flow 5 Twitter API User Voice Request Audio Stream Twitter-News Skill Lambda JSON Request Node.js JSON Response (SSML+Card) Response (Audio) Response (Text/Graphics) Audio Response App/Web JSON Response (statuses) GET search/tweets
  • 6. BUILD AN ALEXA SKILL STEP-BY-STEP Prerequisites — Follow Links to Install ▸ Node.js ▸ Gulp ▸ AWS Developer Account ▸ AWS CLI ▸ Twitter Account 6
  • 7. BUILD AN ALEXA SKILL STEP-BY-STEP AWS Credentials ‣ For command line access to AWS, store credentials in ~/.aws/credentials $ cat ~/.aws/credentials [default] aws_access_key_id = OATLIM5W7KKX1V6PQ792 aws_secret_access_key = I2WiUyTkPI7b36PQnin11oUqgZVX575tSUAB1FOm ‣ This may already be done when setting up the AWS CLI ‣ Development on Windows will require a different approach to storing this file Not my real credentials :) 7
  • 8. BUILD AN ALEXA SKILL STEP-BY-STEP Create the Directory Structure ▸ Create a directory where both the Alexa skills and the Alexa App Server will live. All new skills will live under here. ▸ For this tutorial, we’ll use ~/Code/alexa-js ▸ In that directory: cd ~/Code/alexa-js git clone https://github.com/rickwargo/alexa-app-root mkdir alexa-js-apps† ▸ Install the node modules for alexa-app-root cd alexa-app-root npm install 8 †If you choose to call this directory something else, you’ll need to update filesPath.server in gulpfile.js. You’ll also need to update server.js and change app_dir to point to the directory.
  • 9. BUILD AN ALEXA SKILL STEP-BY-STEP Create Certificate for HTTPS (if using) ▸ Install a self-signed certificate for HTTPS gulp make-cert [18:06:51] Using gulpfile ~/Code/alexa-js/test/alexa-app-root/gulpfile.js [18:06:51] Starting 'make-cert'... Generating RSA private key, 1024 bit long modulus ...++++++ .............++++++ e is 65537 (0x10001) You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:US State or Province Name (full name) [Some-State]:Pennsylvania Locality Name (eg, city) []:Blue Bell Organization Name (eg, company) [Internet Widgits Pty Ltd]:epicminds Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []:Rick Wargo Email Address []:cert@epicminds.com [18:07:21] Finished 'make-cert' after 30 s 9
  • 10. BUILD AN ALEXA SKILL STEP-BY-STEP Test Web Server is Running ▸ Browse to http://localhost:8003/test ▸ Also test https://localhost:8003/test 10
  • 11. BUILD AN ALEXA SKILL STEP-BY-STEP Start a New Skill ▸ Fork the alexa-app starter template, if desired https://github.com/rickwargo/alexa-app-template ▸ Clone into a directory under alexa-js-apps cd ~/Code/alexa-js/alexa-js-apps git clone https://github.com/rickwargo/alexa-app-template twitter-news ▸ Alternately, all code is available from Github (don’t do this if you want to code by hand) cd ~/Code/alexa-js/alexa-js-apps git clone https://github.com/rickwargo/twitter-news 11
  • 12. BUILD AN ALEXA SKILL STEP-BY-STEP Install Node Modules ▸ Use npm install to download and install all modules in package.json cd twitter-news npm install 12
  • 13. BUILD AN ALEXA SKILL STEP-BY-STEP Test Fresh Installation ▸ Run the default tests using gulp ▸ test-mock runs the test runner framework (mocha, chai is the test framework) — only a few tests are shown below gulp test-mock [12:14:16] Using gulpfile ~/Code/alexa-js/alexa-js-apps/twitter-news/gulpfile.js [12:14:16] Starting 'test-mock'... App Starter Tests starting up ✓ should fail if an unknown application id is provided ✓ should fail if a missing application is provided ... My Intents the story intent ✓ tells you the whole story ✓ tells a partial story when asked Text for exception message ✓ returns exception message if supplied ✓ returns message if supplied 21 passing (23ms) [12:14:16] Finished 'test-mock' after 569 ms 13
  • 14. BUILD AN ALEXA SKILL STEP-BY-STEP Create an AWS IAM Role for Lambda Code Execution ▸ Name should be function name (later we’ll name it twitter-news-skill) followed by “-role” aws iam create-role --role-name twitter-news-skill-role --assume-role-policy-document file://assets/json/aws/trust-policy.json { "Role": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": { "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" } } }, "RoleId": "ZG7523QZS8J7R951Y3C0J", "CreateDate": "2017-02-27T17:59:56.785Z", "RoleName": "twitter-news-skill-role", "Path": "/", "Arn": "arn:aws:iam::123456789012:role/twitter-news-skill-role" } } ▸ From the create-role output, copy Arn JSON value and update the role in config/aws-config.js 14
  • 15. BUILD AN ALEXA SKILL STEP-BY-STEP Attach Policy to Newly Created Role ▸ Attach an Amazon-managed policy to the twitter-news-skill-role aws iam attach-role-policy --role-name twitter-news-skill-role --policy-arn arn:aws:iam::aws:policy/AWSLambdaFullAccess ▸ Access can be changed by choosing a different policy below or roll your own ✦ AWSLambdaFullAccess ✦ AWSLambdaDynamoDBExecutionRole ✦ AWSLambdaBasicExecutionRole 15
  • 16. BUILD AN ALEXA SKILL STEP-BY-STEP Give the Alexa Service Access ▸ This is the same as adding the Alexa Skills Kit as a trigger to the Lambda function aws lambda add-permission --function-name twitter-news-skill --statement-id 1 --action lambda:invokeFunction --principal alexa-appkit.amazon.com --region us-east-1 { "Statement": "{"Sid":"1","Resource":"arn:aws:lambda:us- east-1:100866613345:function:twitter-news-skill","Effect":"Allow","Principal": {"Service":"alexa-appkit.amazon.com"},"Action":["lambda:invokeFunction"]}" } ▸ More information can be found in the AWS Lambda Developer Guide 16
  • 17. BUILD AN ALEXA SKILL STEP-BY-STEP Edit config/aws-config.js prior to Pushing Lambda Code to AWS ▸ Ensure role is updated per Create an AWS IAM Role for Lambda Code Execution ▸ The region defaults to us-east-1 — update as necessary ▸ If you use a specific AWS credentials profile, update the profile value — defaults to “default”. ▸ Update timeout and memorySize, if needed. The defaults of 3 seconds and 128MB are usually sufficient. ▸ Runtime should be nodejs4.3, unless a newer version was released after this documentation 17
  • 18. BUILD AN ALEXA SKILL STEP-BY-STEP Update config/app-config.js prior to Pushing Lambda Code to AWS ▸ The applicationId can be left as-is until the skill is created on the Amazon Alexa Developer Portal ▸ Update the applicationName to “twitter-news” ▸ Update the functionName to be the applicationName followed by 
 “-skill”, so it would be “twitter-news-skill” ▸ Update the description to reflect the skill’s intent, i.e. “Grabs the latest or popular tweets about a specific topic” 18
  • 19. BUILD AN ALEXA SKILL STEP-BY-STEP Update Config Tests in test/test_config.js ▸ Due to changes to some default settings, tests need to be updated to reflect the change(s) ▸ Update AWS Config —> Property —> region test if changed from us-east-1 ▸ Update AWS Config —> Property —> runtime test if changed from nodejs4.3 ▸ Update AWS Config —> Property —> applicationName test to reflect the new application name ▸ For example, change test/test_config.js (around line 47) such that it reads: it('applicationName is twitter-news', function () {
 var result = config.applicationName;
 return result.should.equal('twitter-news');
 }); 19
  • 20. BUILD AN ALEXA SKILL STEP-BY-STEP Push Code to AWS Lambda ▸ Upload the code to AWS Lambda using “gulp push” gulp push ▸ Upon successful completion, the test-lambda gulp task will pass all tests 20
  • 21. BUILD AN ALEXA SKILL STEP-BY-STEP Connect to the Alexa Developer Portal ▸ Browse to the Alexa Developer Portal ▸ Press Get Started > on the Alexa Skills Kit button 21
  • 22. BUILD AN ALEXA SKILL STEP-BY-STEP Create The Skill on the Alexa Developer Portal ▸ Press Add a New Skill in the top-right of the following page 22
  • 23. BUILD AN ALEXA SKILL STEP-BY-STEP Fill Out the Skill Information ▸ Keep the Skill Type as Custom Interaction Model ▸ Set the Name to the application name (defined previously), Twitter News ▸ Set the invocation name to the application name (in lower case), twitter news ▸ Leave Audio Player defaulted to No ▸ Press the Save button 23
  • 24. BUILD AN ALEXA SKILL STEP-BY-STEP Get the AWS Lambda ARN for the Lambda Function ▸ In the terminal window, get the function definition aws lambda get-function --function-name twitter-news-skill { "Code": { "RepositoryType": "S3", "Location": “https://prod-04-2014-tasks.s3.amazonaws.com/snapshots/123456789012/twitter-news- skill-00000000-0000-0000-0000-000000000000?X-Amz-Security-Token=..." }, "Configuration": { "Version": "$LATEST", "CodeSha256": "JZKRixkiCQ5NQwHt5/tUna61fqDDfnWGKfgsWnyUJKA=", "FunctionName": "twitter-news-skill", "MemorySize": 128, "CodeSize": 6575734, "FunctionArn": "arn:aws:lambda:us-east-1:123456789012:function:twitter-news-skill", "Handler": "index.handler", "Role": "arn:aws:iam::123456789012:role/twitter-news-skill-role", "Timeout": 3, "LastModified": "2017-02-27T18:40:44.411+0000", "Runtime": "nodejs4.3", "Description": "Grabs the latest or popular tweets about a specific topic" } } 24
  • 25. BUILD AN ALEXA SKILL STEP-BY-STEP Configure the New Skill ▸ Click Configuration to set the skill’s endpoint ▸ We’ll skip the Interaction Model for now until we develop the code ▸ Select AWS Lambda ARN for the Service Endpoint Type and select the North America region ▸ Copy the FunctionARN value from the previous step into the text box under North America ▸ Keep the default of No in Account Linking ▸ Press Save 25
  • 26. BUILD AN ALEXA SKILL STEP-BY-STEP Update the Skill’s Application Id in config/applicationid.json ▸ From the previous step, copy the ID in the top-left of the page (under the application name Twitter News) and paste it into the value for applicationId in config/applicationid.json ▸ application.json is not stored in Github to keep the Id private {
 "applicationId": "amzn1.ask.skill.00000000-0000-0000-0000-000000000000"
 } 26
  • 27. BUILD AN ALEXA SKILL STEP-BY-STEP Update package.json ▸ Update package.json to set alexa.applicationId to the value Id found in Configure the New Skill ▸ Update name to “twitter-news” (the name of the application specified in config/ app-config.js) ▸ Update the version, description, author, license, and other URLs as necessary 27
  • 28. BUILD AN ALEXA SKILL STEP-BY-STEP Remove Sample Code ▸ Remove the sample StoryIntent and supporting dictionary and custom slot type in index.js: ▸ Delete the block beginning with: Object.assign(app.dictionary, { ▸ Delete the block beginning with: app.customSlotType('STORY_TYPE', ▸ Delete the block beginning with: app.intent('StoryIntent', { ▸ Remove all the tests in test/test_intents.js — these were for the sample code 28
  • 29. BUILD AN ALEXA SKILL STEP-BY-STEP Create a New Twitter Application ▸ A new Twitter application is needed to gain keys and secrets for API access ▸ Browse to https://apps.twitter.com/ ▸ Press Create New App and fill out details ▸ Name: My-Twitter-News ▸ Note the name may be taken by another application. Try to prefix with your organization or initials. This name is not important for the skill - only the access tokens and keys are necessary. ▸ Description: Grabs the latest or popular tweets about a specific topic ▸ Website: http://example.com/twitternews 29
  • 30. BUILD AN ALEXA SKILL STEP-BY-STEP Grant Permissions to Twitter Application ▸ For this skill, we’ll only need read permission ▸ On the Permissions tab, select Read only and press Update Settings 30
  • 31. BUILD AN ALEXA SKILL STEP-BY-STEP Twitter Application Keys and Access Tokens ▸ You’ll need both consumer and access token ▸ Click on the Keys and Access Tokens tab ▸ Near the bottom of the page press Create my access token. This will provide the Access Token and Access Token Secret necessary to connect to the Twitter API. ▸ Save the values and add to your environment under the following environment variable names: ▸ TWITTER_CONSUMER_KEY ▸ TWITTER_CONSUMER_SECRET ▸ TWITTER_ACCESS_TOKEN_KEY ▸ TWITTER_ACCESS_TOKEN_SECRET 31 Not my real keys :) Don’t skip the step! You’ll need to take appropriate actions depending on your OS. For example, on Linux and OS X:
 
 # Keys for twitter-news-skill
 export TWITTER_CONSUMER_KEY='consumer key'
 export TWITTER_CONSUMER_SECRET='consumer secret'
 export TWITTER_ACCESS_TOKEN_KEY='token key'
 export TWITTER_ACCESS_TOKEN_SECRET='token secret'
  • 32. BUILD AN ALEXA SKILL STEP-BY-STEP Configure Your Environment for Access to the Twitter ‣ Configure environment for keys for access to the Twitter API ‣ For OS X and Linux, add to ~/.bash_profile (or ~/.bashrc) # Keys for twitter-news-skill export TWITTER_CONSUMER_KEY=hSYvOtda3Ri74PkyuTOHrLMdf export TWITTER_CONSUMER_SECRET=LXHvTRShADq0s8lOlHCPodPw1smNeJ5p6E8GyOlY9cM0Ti5QSX export TWITTER_ACCESS_TOKEN_KEY=WVUXxMzZPrszP2AO3eQIogJNFIA2vqkO5bmRkCiO1zCdr7KSt6 export TWITTER_ACCESS_TOKEN_SECRET=tMOuVnb3nrlwtNgUtr9qCZTdEqj6SpqbJrt7uysGuf5oU ‣ Log out and log in again to set up environment Not my real keys :) 32
  • 33. BUILD AN ALEXA SKILL STEP-BY-STEP Set Lambda Environment Variables for Access to Twitter ▸ After configuring a New Twitter App, two pairs of Keys/Secrets are available for use ▸ Copy them and paste into the Environment variables section ▸ Enable encryption helpers for more security 33 Not my real keys :)
  • 34. BUILD AN ALEXA SKILL STEP-BY-STEP Create Twitter Module to Gain Access to Twitter API ▸ Create lib/twitter.js and add the following code: var Twitter = require('twitter');
 
 /**
 * Connect to the Twitter API. Gain access via environment variables.
 * Optionally replace with actual strings (not recommended).
 */
 var client = new Twitter({
 consumer_key: process.env.TWITTER_CONSUMER_KEY,
 consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
 access_token_key: process.env.TWITTER_ACCESS_TOKEN_KEY,
 access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET
 });
 
 module.exports = client; 34
  • 35. BUILD AN ALEXA SKILL STEP-BY-STEP Add Tests for Twitter Module ▸ Create test/test_twitter.js and add the following code: /*global describe, it, beforeEach */
 
 'use strict';
 
 var chai = require('chai'),
 chaiAsPromised = require('chai-as-promised');
 
 chai.use(chaiAsPromised);
 chai.should();
 
 ////////////// Tests Twitter //////////////
 
 describe('Twitter', function () {
 describe('New Client', function () {
 var twitter;
 beforeEach(function () {
 // here for code coverage
 twitter = require('../lib/twitter');
 });
 
 it('should return an object', function () {
 return twitter.should.be.an('object');
 });
 it('should have a version of at least 1.7.0', function () {
 var versionCompare = require('./../vendor/version_compare');
 var comparison = versionCompare(twitter.VERSION, '1.7.0');
 return comparison.should.be.at.least(0); // same or higher version
 });
 });
 }); 35
  • 36. BUILD AN ALEXA SKILL STEP-BY-STEP Run Twitter Tests ▸ Run tests again, testing recently added Twitter tests gulp test-mock # (or simply use the alias test, gulp test) ... Twitter New Client ✓ should return an object ✓ should have a version of at least 1.7.0 21 passing (32ms) [10:59:20] Finished 'test-mock' after 338 ms 36
  • 37. BUILD AN ALEXA SKILL STEP-BY-STEP Create the Intent — WhosTweeted ▸ This intent is designed to return the last N unique twitterers from tweets matching our search criteria ▸ This is a simple intent: it doesn’t take any slot values ▸ It is invoked when the Echo understands one of the following utterances while in the skill: ▸ Who tweeted recently ▸ Who shared recently ▸ Who recently tweeted ▸ Who recently shared ▸ It depends on being able to grab the latest tweets ▸ It depends on a function to take the latest tweets and find the last N unique twitterers (uniqueTwitterers) ▸ It depends on a function to take the last N unique twitterers and format them for output (recentTweetsFrom) 37
  • 38. BUILD AN ALEXA SKILL STEP-BY-STEP Create Unique Twitterers Function and Associated Tests ▸ Create the following files using the code available in https://github.com/ rickwargo/twitter-news ▸ lib/helpers/unique_twitterers.js ▸ lib/constants.js ▸ test/test_unique_twitterers.js 38
  • 39. BUILD AN ALEXA SKILL STEP-BY-STEP Run Twitter Tests for Unique Twitterers Function ▸ Run tests again, testing recently added Twitter tests gulp test ... Unique Twitterers Users of no length ✓ should be an empty list of one unique user ✓ should be list of length one ✓ should be list of length one if duplicates of multiple unique users ✓ should be a list of the unique users ✓ should be list of the unique users 26 passing (34ms) 39
  • 40. BUILD AN ALEXA SKILL STEP-BY-STEP Create Recent Tweets From Function and Associated Tests ▸ Create the following functions using the code available in https://github.com/rickwargo/twitter-news/blob/master/lib/text.js ▸ recentTweetsFrom ▸ noRecentTweets ▸ Add tests for recentTweetsFrom in test/test_text.js describe('for recent tweets from', function () {
 it('returns no one if no recent tweets', function () {
 var result = Text.recentTweetsFrom([]);
 return result.should.equal(Text.noRecentTweets);
 });
 it('returns one user if only one user', function () {
 var result = Text.recentTweetsFrom(['alpha']);
 return result.should.equal('Recent tweets were from: alpha.');
 });
 it('returns one user if only one user', function () {
 var result = Text.recentTweetsFrom(['alpha', 'beta', 'gamma']);
 return result.should.equal('Recent tweets were from: alpha, beta, and gamma.');
 });
 }); ▸ Run tests using “gulp test” — there should now be 29 passing tests 40
  • 41. BUILD AN ALEXA SKILL STEP-BY-STEP Create the WhoTweeted Intent Handler in index.js ▸ Add the following code into index.js app.intent('WhoTweeted', {
 utterances: [
 'Who {tweeted|shared} {recently|}',
 'Who recently {tweeted|shared}'
 ]
 }, function (ignore, response) {
 return Twitter.get('search/tweets', TwitterParams)
 .then(function (tweets) {
 var users = uniqueTwitterers(tweets.statuses, Constants.MAX_USERS);
 var msg = Text.recentTweetsFrom(users);
 
 response.say(msg);
 });
 }); ▸ Add the following requires to index.js Twitter = require('./lib/twitter'),
 Text = require('./lib/text'),
 Constants = require('./lib/constants'),
 uniqueTwitterers = require('./lib/helpers/unique_twitterers');
 41
  • 42. BUILD AN ALEXA SKILL STEP-BY-STEP alexa-utterances ▸ Utterances are kept with the skill definition in the code ▸ Utterances are condensed using alternation, being able to expand the utterance with each word in the curly braces using the alexa-utterances node module ▸ This module is installed by default with the starter template ▸ For more information refer to the project’s README 42
  • 43. BUILD AN ALEXA SKILL STEP-BY-STEP Add Tests for WhosTweeted in test/test_intents.js ▸ For testing, stub the Twitter.get() function with “sinon” returning a promise as the stub result instead of a call to the Twitter API ▸ To stub Twitter.get(), Add the following code before the tests var sinon = require('sinon');
 var sinonStubPromise = require('sinon-stub-promise');
 sinonStubPromise(sinon); ▸ Add the following require’s Text = require('./lib/text'),
 Twitter = require(‘./lib/twitter'); ▸ Add the following tests ▸ Include code block from around line 41 starting with describe('#WhoTweeted', function () { ▸ Wrap the preceding code block with: describe('using a mock client', function () {
 var get;
 beforeEach(function () {
 get = sinon.stub(Twitter, 'get').returnsPromise();
 });
 afterEach(function () {
 get.restore();
 }); // #WhoTweeted tests go here }); ▸ Run tests using “gulp test” — there should now be 32 passing tests 43
  • 44. BUILD AN ALEXA SKILL STEP-BY-STEP Create the Intent — LatestTweets ▸ This intent is designed to return the last N tweets matching our search criteria ▸ This intent takes three slot values, two standard Amazon slot types and one custom slot type ▸ It is invoked when the Echo understands one of the following utterances while in the skill: ▸ What’s the most recent tweet ▸ For the news ▸ What are the last three tweets ▸ The last tweet from Rick ▸ It depends on being able to grab the latest tweets ▸ It depends on a function to take the last N tweets and format them for output (tweet2say) 44
  • 45. BUILD AN ALEXA SKILL STEP-BY-STEP Create Text Functions and Associated Tests ▸ Create the following functions using the code available in https://github.com/rickwargo/twitter-news/blob/master/lib/text.js ▸ lastTweets ▸ noMatchingTweets ▸ Add tests for lastTweets in test/test_text.js describe('for LastTweet', function () {
 describe('of a single item', function () {
 it('is singular in its response', function () {
 var result = Text.lastTweets(1);
 return result.should.equal('The last 1 tweet was: ');
 });
 it('is plural in its response', function () {
 var result = Text.lastTweets(2);
 return result.should.equal('The last 2 tweets were: ');
 });
 });
 }); ▸ Run tests using “gulp test” — there should now be 34 passing tests 45
  • 46. BUILD AN ALEXA SKILL STEP-BY-STEP Create tweet2say Function and Associated Tests ▸ Create the tweet2say function using the code available in https://github.com/ rickwargo/twitter-news/blob/master/lib/helpers/tweet2say.js ▸ Create tests for the tweet2say function using the code available in https:// github.com/rickwargo/twitter-news/blob/master/test/test_tweet2say.js ▸ Run tests using “gulp test” — there should now be 41 passing tests 46
  • 47. BUILD AN ALEXA SKILL STEP-BY-STEP Prepare the LatestTweets Intent Handler in index.js ▸ Add the require for tweet2say to index.js tweet2say = require('./lib/helpers/tweet2say'), ▸ Add dictionary near the top of index.js Object.assign(app.dictionary, {
 tweet: ['tweet', 'tweets', 'item', 'items', 'story', 'stories', 'news', 'news item', 
 'news items', 'news story', 'news stories', 'post', 'posts', 'update', 'updates', 
 'message', 'messages'],
 whats: ['what is', 'what are', 'what's', 'about', 'give me', 'tell me'],
 the: ['the', 'a', 'an']
 }); ▸ Add the custom slot for the intent handler to index.js app.customSlotType('TWEET_CATEGORIES', ['popular', 'latest', 'recent', 'last']);
 47
  • 48. BUILD AN ALEXA SKILL STEP-BY-STEP Create the LatestTweets Intent Handler in index.js ▸ Add the following code to index.js var TwitterParams = {
 q: '#PhillyCode OR #PhillyCC OR @PhillyDotNet',
 result_type: 'recent', // options: 'recent', 'mixed', or 'popular'
 since_id: '',
 include_entities: false
 };
 app.intent('LatestTweets', {
 slots: {
 Count: 'AMAZON.NUMBER',
 User: 'AMAZON.US_FIRST_NAME',
 TweetCategory: 'TWEET_CATEGORIES'
 },
 utterances: [
 '{whats|} {the} {tweet}',
 '{whats|} {-|Count} {tweet}',
 '{whats|} {the} {most|} {-|TweetCategory} {tweet}',
 '{whats|} {the} {most|} {-|TweetCategory} {-|Count} {tweet}',
 '{whats|} {the} {most|} {-|TweetCategory} {tweet} from {-|User}'
 ]
 }, function (request, response) { 48
  • 49. BUILD AN ALEXA SKILL STEP-BY-STEP Create the LatestTweets Intent Handler in index.js (cont’d) ▸ Add the following code to the end of the intent handler for LatestTweets in index.js }, function (request, response) {
 var max_tweets = Math.min(request.slot('Count') || 1, Constants.MAX_TWEETS);
 var user = request.slot('User') || null;
 var tweetCategory = request.slot('TweetCategory') || 'recent';
 
 TwitterParams.result_type = tweetCategory.toLowerCase() === 'popular'
 ? 'popular'
 : 'recent';
 return Twitter.get('search/tweets', TwitterParams)
 .then(function (tweets) { // Filter
 var counter = 0;
 return tweets.statuses.filter(function (tweet) {
 // select if within max tweets and user matches, if specified
 var select = (counter < max_tweets) && (!user || tweet.user.name.toLowerCase().indexOf(user.toLowerCase()) > -1);
 if (select) {
 counter += 1;
 }
 return select;
 });
 })
 .then(function (tweets) { // Say matching tweets
 var msg;
 if (tweets.length > 0) {
 msg = Text.lastTweets(tweets.length) + tweet2say(tweets);
 } else {
 msg = Text.noMatchingTweets;
 }
 response.say(msg);
 });
 }); 49
  • 50. BUILD AN ALEXA SKILL STEP-BY-STEP Add Tests for LatestTweets in test/test_intents.js ▸ Add the following tests ▸ Include code block from around line 79 starting with describe('#LatestTweets', function () { ▸ Run tests using “gulp test” — there should now be 52 passing tests ▸ Add a test against the Twitter API instead of a mock describe('against the Twitter API', function () {
 describe('#LatestTweets', function () {
 describe('response', function () {
 it('contains the latest tweets', function () {
 var result = request.intentRequest({name: 'LatestTweets'});
 return result.should.eventually.match(/<speak>The last 1 tweet was:/);
 });
 });
 });
 }); ▸ Run tests again using “gulp test” — there should now be 53 passing tests 50
  • 51. BUILD AN ALEXA SKILL STEP-BY-STEP Start Web Server for Testing Using the Web-based Interface ▸ Start the server with “npm start” npm start > alexa-app-root@1.0.0 start /Users/rick/Code/alexa-js/alexa-app-root > node server.js --start serving static content from: /Users/rick/Code/alexa-js/alexa-app-root/public_html loading server-side modules from: /Users/rick/Code/alexa-js/alexa-app-root/server loaded /Users/rick/Code/alexa-js/test/alexa-app-root/server/.gitkeep loading apps from: /Users/rick/Code/alexa-js/alexa-js-apps/ loaded app [twitter-news] at endpoint: /alexa/twitter-news enabling https listening on https port 8443 listening on http port 8003 51
  • 52. BUILD AN ALEXA SKILL STEP-BY-STEP Test Using the Web-based Interface ▸ Browse to http://localhost:8003/test/ ▸ There should only be one app loaded: twitter-news ▸ Click on Launch Request and press submit; the welcome message should appear. You can update the welcome message in lib/text.js at onLaunchPrompt. ▸ Experiment with the various intents to see if they work as expected 52
  • 53. BUILD AN ALEXA SKILL STEP-BY-STEP Finalize Alexa Skill Configuration — Intent Schema ▸ Populate Interaction Model ▸ Using the test web page, copy the Schema (click on Schema in top-right and then clock Copy to Clipboard) and paste into Intent Schema in Alexa Skill page 53
  • 54. BUILD AN ALEXA SKILL STEP-BY-STEP Finalize Alexa Skill Configuration — Custom Slot Types ▸ Add a Custom Slot Type by pressing Add Slot Type and enter TWEET_CATEGORIES for the type and the list of slot types from the test web page under Values 54
  • 55. BUILD AN ALEXA SKILL STEP-BY-STEP Finalize Alexa Skill Configuration — Sample Utterances ▸ Add to Sample Utterances the list of utterances generated from the test web page. Note how only a few lines of utterances in the code expanded to over 2,600 different utterances! 55
  • 56. BUILD AN ALEXA SKILL STEP-BY-STEP Build the Alexa Skill Interaction Model ▸ When all three areas are populated, press Save to build the interaction model ▸ You’ll see a message while it is building. It may take up to a minute to build the model. 56
  • 57. BUILD AN ALEXA SKILL STEP-BY-STEP Test Skill from Lambda - Create Test Event ▸ Select Configure test event from the Actions menu 57
  • 58. BUILD AN ALEXA SKILL STEP-BY-STEP Test Skill from Lambda - Input Test Event ▸ Do not select a Sample event template - just paste over what is there ▸ Copy the JSON from the Request tab on the web test page and paste into the code area ▸ Press Save 58
  • 59. BUILD AN ALEXA SKILL STEP-BY-STEP Test Skill from Lambda - Perform the Test ▸ Press Test ▸ The Execution result should show succeeded 59
  • 60. BUILD AN ALEXA SKILL STEP-BY-STEP Test Skill from Alexa Skill Portal - Select Test Pane ▸ Press Test in the left panel to bring up the testing pane 60
  • 61. BUILD AN ALEXA SKILL STEP-BY-STEP Test Skill from Alexa Skill Portal - Perform Test ▸ In the Service Simulator, enter what is the latest news under Enter Utterance and press Ask Twitter News ▸ A valid Lambda Response should appear 61
  • 62. BUILD AN ALEXA SKILL STEP-BY-STEP Test Skill using echosim.io ▸ Go to https://echosim.io and sign in to Echosim.io using your Amazon account ▸ Don’t worry, it’s safe as it uses OAUTH 62
  • 63. BUILD AN ALEXA SKILL STEP-BY-STEP Test Skill using echosim.io by Speaking ▸ Press the record button and say Ask Twitter News for the latest ▸ You should hear the latest tweet ▸ Try testing other utterances 63
  • 64. BUILD AN ALEXA SKILL STEP-BY-STEP Test on Your Own Device ▸ If your Echo is linked to the same account as your Amazon developer account, the skill is automatically enabled on your Echo and any other devices linked to the same account ▸ Repeat the same questions to your Amazon Echo ▸ The skill is now ready for your enjoyment and tweaking! 64
  • 65. BUILD AN ALEXA SKILL STEP-BY-STEP Contact Me ▸ https://www.rickwargo.com/ ▸ https://github.com/rickwargo ▸ https://linkedin.com/in/rickwargo ▸ contact@epicminds.com ▸ @rickwargo ▸ https://github.com/rickwargo/twitter-news ▸ https://github.com/rickwargo/alexa-app-root ▸ https://github.com/rickwargo/alexa-app-template 65