Skip to content

Latest commit

 

History

History
521 lines (419 loc) · 21.6 KB

readme.md

File metadata and controls

521 lines (419 loc) · 21.6 KB

Node Alexa Starter Kit

The purpose of this starter kit is to boost up Amazon Alexa custom skill development speed. This starter kit simplifies development of multiple skills within a single project. It generates configuration (intent schemas, utterances, slot values) for Amazon Developer Console automatically and stores them for each skill separately. No changes needed in server code. Development in local machine is done using express. Server restarts itself and new configuration is regenerated automatically when code is changed. In that way the changes can be tested immediately unless intent names, utterances or slots are changed (in which case configuration should be updated on amazon developer console). This kit is able to run custom skills in express server and also deploy to AWS lambda.

This kit uses alexa-app module, visit the page for more information about functionality and customizing server if needed.

Updates

  • v1.0.1 - endpoint for config
  • v1.0.2 - update some links in readme
  • v1.0.3 - update alexa-app and aws-sdk

Contents

  • git clone git@github.com:AlexSapoznikov/node-alexa-starter-kit.git
  • cd node-alexa-starter-kit/
  • npm install
  • npm start - builds and starts server
  • npm run start-dev - starts and restarts server on code change
  • npm run deploy - deploys to lambda
  • npm run build - builds without starting server
  • npm run create-skill [-- --name=anyname] - creates new sample skill file in skills folder
  • npm run expose - exposes your localhost to the internet
  • npm run eslint - lints the code for errors
  • npm run test - runs tests
amazonConfig                        // Configuration for amazon developer console is generated here
    [skillName]                     // Configuration is separated by skill name
        intentSchema.json               // Generated intent schema
        sampleUtterances.txt            // Generated utterances
        slots
            [slotType].txt              // Generated slot values
config                              // Project configuration
    config.json
    config.test.json
    config.dev.json
data
    sampleSkill                         // Sample skill that is used for creating new skill file
public                              // Code compiled using babel
static                              // Front-end files for displaying configuration
src
    scripts
        execNgrok.js                    // Script for exposing localhost to web
        generateAmazonConfig.js         // Script for generating configuration for Amazon Development Console
        generateNewSkill.js             // Script for generating new skill
    skills                          // All skills should be added here!
        dateExampleSkill.js             // Example skill - delete it!
        dogExampleSkill.js              // Example skill - delete it!
        questionExampleSkill.js         // Example skill - delete it!
    test
        skills                      // Example skills for testing
            dateExampleSkill.js
            dogExampleSkill.js
            questionExampleSkill.js
        helpers.js                      // Helper functions for testing
        testServer.js                   // Tests for server
        testSkills.js                   // Tests for merging skills
    utils
        mergeSkills.js                  // Merging skills
    errorMessages.js                    // Error messages for Alexa
    events.js                           // Events (launch, pre, post, sessionEnd, error)
    server.js                           // Server code
įmages                              // Screenshots
  • Development is being done in ./src folder.
  • The builded code is generated to ./public folder.
  • Configuration files are located in ./config.
  • Skills are located in ./src/skills/ folder.
  • Events are located in ./src/events.js file.
  • Server creates intents (endpoints) automatically using merged skills by ./src/utils/mergeSkills.js file.
  • Scripts for generating amazon configuration and new skill files are located in ./src/scripts folder.
  • Error messages are located in ./src/errorMessages.js file

Location for configuration files is ./config easy-config is used for project configuration.

  • ./config/config.json - public config file, do NOT use keys and secrets in this file.
  • ./config/config.dev.json - private config file, overrides ./config/config.json if NODE_ENV=development environment used, use keys and secrets here and do NOT commit that file.
  • ./config/config.test.json - config file for tests, overrides ./config/config.json if NODE_ENV=test environment used. Do not commit keys and secrets.

Configuration file looks like this:

{
  "server": {
    "host": "localhost",
    "port": 5000,
    "accessEndpoint": "alexa"               // Endpoint for accessing custom skill. May be empty.
  },
  "deploy": {
    "aws": {
      "region": "us-east-1",                // AWS region
      "accessKeyId": "",                    // AWS access key
      "secretAccessKey": "",                // AWS secret access key
      "bucketName": "my-bucket-name",       // S3 Bucket name
      "fileName": "myAlexaProject",         // Name of compressed file that will be uploaded to lambda on deploy

      "lambda": {
        "functionName": "myAlexaFunction"
      }
    }
  },
  "locations": {
    "amazonConfig": "../amazonConfig/",     // This is where Amazon Developer Console configuration will be written to
    "skillsLocation": "/skills"             // This is where all skills files are located
  }
}
  • Server contains everything needed for running express server and developing in local machine
  • Deploy contains everything needed for deploying to AWS Lambda
  • Locations contains configurable folder locations
  • Add new skill file via terminal
npm run create-skill -- --name=myNewSkill
  • Edit the skill file (./src/skills/myNewSkill.js).
  • Start the server
    npm run start
    // or
    npm run start-dev   // restarts server on code change

Alexa is now ready for testing.

  • To invoke custom skill, say: Alexa, ask [invocationName] [question using utterances]
  • For more information about invoking custom skills, visit Amazon Developer commands page

Skill file looks like this:

export default {
  skillName: 'dog',
  intents: [
    {
      intentName: 'dogNumber',
      slots: {
        number: 'AMAZON.NUMBER'
      },
      utterances: [
        'say the number {-|number}',
        'find {-|number}'
      ],
      response: (request, response) => {
        const number = request.slot('number');
        response.say(`The number you asked to say is ${number}`);
      }
    }
  ]
};
  • skillName - name of skill that is displayed to customers in the Alexa app. Must be between 2-50 characters.
  • intents - array on intents
  • intentName - name of intent
  • slots - variables for getting what user says. Can be declared in two ways:
    // if no need to provide values
    slots: {
        slotName1: "myCustomSlotType",
        slotName2: "AMAZON.[built-in-intent]",
    }

    // if values needed:

    slots: {
        slotName1: {
          type: 'myCustomSlotType',
          values: [
            'value1',
            'value2',
            'etc'
          ]
        },
        slotName2: "AMAZON.[built-in-intent]"
    }
  • utterances - these are what people say to interact with skill. Examples:
    // Use like this to get value from slot
    I want to go to {-|slotName}

    // Use like this to provide different options
    I want to go to {school|shop|work}
        // add another vertical bar ( | ) after "work" if empty option allowed
  • response - response from alexa

Handlers for launch, intent, and session
Documentation about handler objects is copied from alexa-app npm module, because current starter kit uses it's functionality.

// return the type of request received (LaunchRequest, IntentRequest, SessionEndedRequest)
String request.type()

// return the value passed in for a given slot name
String request.slot("slotName")

// check if you can use session (read or write)
Boolean request.hasSession()

// return the session object
Session request.getSession()

// return the request context
request.context

// the raw request JSON object
request.data
// tell Alexa to say something; multiple calls to say() will be appended to each other
// all text output is treated as SSML
response.say(String phrase)

// empty the response text
response.clear()

// tell Alexa to re-prompt the user for a response, if it didn't hear anything valid
response.reprompt(String phrase)

// return a card to the user's Alexa app
// for Object definition @see https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/alexa-skills-kit-interface-reference#card-object
// skill supports card(String title, String content) for backwards compat of type "Simple"
response.card(Object card)

// return a card instructing the user how to link their account to the skill
// this internally sets the card response
response.linkAccount()

// play audio stream (send AudioPlayer.Play directive) @see https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/custom-audioplayer-interface-reference#play-directive
// skill supports stream(String url, String token, String expectedPreviousToken, Integer offsetInMilliseconds)
response.audioPlayerPlayStream(String playBehavior, Object stream)

// stop playing audio stream (send AudioPlayer.Stop directive)
response.audioPlayerStop()

// clear audio player queue (send AudioPlayer.ClearQueue directive)
// clearBehavior is "CLEAR_ALL" by default
response.audioPlayerClearQueue([ String clearBehavior ])

// tell Alexa whether the user's session is over; sessions end by default
// you can optionally pass a reprompt message
response.shouldEndSession(boolean end [, String reprompt] )

// send the response to the Alexa device (success)
// this is not required for synchronous handlers
// you must call this from asynchronous handlers
response.send()

// trigger a response failure
// the internal promise containing the response will be rejected, and should be handled by the calling environment
// instead of the Alexa response being returned, the failure message will be passed
response.fail(String message)

// calls to response can be chained together
response.say("OK").send()
// check if you can use session (read or write)
Boolean request.hasSession()

// get the session object
var session = request.getSession()

// set a session variable
// by defailt, Alexa only persists session variables to the next request
// the alexa-app module makes session variables persist across multiple requests
// Note that you *must* use `.set` or `.clear` to update
// session properties. Updating properties of `attributeValue`
// that are objects will not persist until `.set` is called
session.set(String attributeName, String attributeValue)

// return the value of a session variable
String session.get(String attributeName)

// session details, as passed by Amazon in the request
session.details = { ... }

Usually there is no need for making changes to the server code.
Server code is located in ./src/server.js file.

  • Merges skill files and initializes intents.
  • Exports Alexa app and handler for AWS Lambda.
  • Events like launch, pre, post, sessionEnded, error are moved to ./src/events.js.
  • To disable persisting every request session attribute into response: in server file, set app.persistentSession to false

For more functionality and options visit alexa-app npm module.

When starting server, Amazon configuration is written to amazonConfig folder.
Configuration is separated into different folders that are named after skill names
Configuration can be found also on localhost:port/config url.
The structure is following:

amazonConfig
    [skillName1]
        intentSchema.json
        sampleUtterances.txt
        slots
            [slotType1].txt
            [slotType2].txt
            etc...
    [skillName2]
    etc...

All you need to do in Amazon Developer Console is to

  • Add skill name
  • Add invocation name
  • copy intent schema from amazonConfig folder
  • copy sample utterances from amazonConfig folder
  • copy slot values from amazonConfig folder
  1. Go to https://developer.amazon.com and sign in
  2. Choose Alexa Tab

1_alexaTab.png

  1. Choose Alexa Skills Kit

2_chooseSkillKit.png

  1. Add new skill

3_addNewSkill.png

  1. Add skill name and invocation name. (Check Audio Player if you will use audio files)

4_addSkillName.png

  1. Add interaction model - intent schema, sample utterances and slot values (if exist). Copy-paste them from localhost:port/config url or amazonConfig folder (details).

5_addSchema.png

  1. Add url - for setting up express server or testing with this starter kit use https. For development use ngrok to expose your localhost to the web and copy ngrok url to Amazon Developer Console.

6_addUrl.png

  1. Amazon also allows to test skill in test section.

7_test.png

Your skill should now be up and running.
Changes should work as soon as server restarts itself (automatically, if npm run start-dev used).
If intent name, utterances or slot values changed in code, configuration on Amazon Developer Console must be updated.

  • Create new S3 Bucket in AWS Amazon Console
  • Create new Lambda function in AWS Amazon Console
  • Modify configuration file
    • Add credentials
    • Add bucket name for the bucket that was created in the first step
    • Add fileName for compressed file that will be deployed to Lambda
    • Add name for Lambda function
  • Deploy using npm run deploy command in terminal
  1. Go to AWS Amazon Console and sign in

  2. Go to S3 Service

  3. Create bucket

    • Click on create bucket button 1_createBucketButton.png
    • Fill needed fields and click create. 2_fillBucketField.png
  4. Go to Lambda Service

    • Choose same region that was used when creating bucket 3_chooseRegion.png
    • Click on Get started now button if you are doing it first time 4_getStartedNowButton.png
    • Click on Create a lambda function button 5_createLambdaFunctionButton.png
    • Setup new lambda function
      • In Select blueprint window Select runtime to latest Node version and click on Blank Function 6_runtimeBlanckFunc.png
      • Click on empty box and choose Alexa Skills Kit, then click Next button 7_trigger.png
      • In Function Configuration window fill name and for existing role choose lambda_basic_execution, other changes are optional. Make sure index.handler is set in Handler field. Then click next 8_functionConf.png
      • In Review window click Create function button 9_review.png
      • Copy ARN top right, you will need that in Amazon Developer Console settings 10_copyArn.png
  5. Get your AWS credentials

    • Go to IAM Service, then go to users tab and click on your user name 11_usersTab.png
    • Go to security credentials tab and click on Create access key button 12_credentialsTab.png
    • Copy your Access key ID and Secret access key 13_copyCredentials.png
  6. Edit configuration file in ./config/

    • Add your credentials (Access key ID and Secret access key)
    • Add your bucket name my-alexa-bucket-name
    • Add your lambda function name myLambdaFunction
    • You may also want to change name for compressed file
  7. Run npm run deploy command in terminal to deploy.

  8. Configuration in Amazon Developer Console

Copyright (c) 2017 Aleksandr Sapožnikov, NodeSWAT

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Node Alexa Starter Kit is maintained by nodeSWAT – an agile development team of NodeJS enthusiasts and professionals. More info at www.nodeswat.com