alexa-router
v2.0.0
Published
Easily build custom skills for Alexa
Downloads
4
Readme
alexa-router
Why
alexa-router
makes it easy for you to build custom Alexa
skills with complex request/response flows.
Install
$ npm install -S alexa-router
Usage
alexa-router
is available via an instance of the Router
. Make sure you begin by initializing the
Router
.
let Alexa = require('alexa-router')
let alexa = new Alexa.Router({
appId: 'my-app-id'
})
Once you initialize the router, you can either configure actions
or dispatch
a HTTP request to be
routed to the actions you have configured.
Router
API
new Alexa.Router(config)
config
Required
Type: Object
config.appId
Required
Type: String[]
Your application ID or an array with many
config.routeIntentOnly
Optional
Type: Boolean
Default: true
Try to route IntentRequest
only
config.verifySignature
Optional
Type: Boolean
Default: true
Verifies the incoming request against a valid Amazon signature to prevent request forgery. Amazon requires verification as part of the skill submission process
config.verifyTimestamp
Optional
Type: Boolean
Default: true
Verifies if the incoming request have a valid timestamp to prevent replay attacks
config.verifyAppId
Optional
Type: Boolean
Default: true
Verifies if the incoming request have a valid application ID to prevent replay attacks from other applications
Examples
let alexa = new Alexa.Router({
appId: 'my-id',
verifySignature: false
})
alexa.action
Routes are defined via the action
method
API
alexa.action(name, config)
name
Required
Type: String
The action name. You can reference this action by its name when defining complex action flows.
config
Required
Type: Object
config.handler(request[, params])
Required
Type: Function
The handler receives a decorated HTTP request and optionally receives params if they were configured to be passed by a previous action.
request
Type: Object
The decorated [Alexa Request Body](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/alexa-skills-kit-interface-reference#Request Format) with additional methods.
request.next()
Returns: Array
An array of Next Action Objects set by the previous response in the session
request.response()
Returns: Object
A decorated Alexa Response Object
// Instantiate a new Response object
let response = request.response()
response.session(key, value)
Param: key String
Param: value String|Object
Sets, patches, or retrieves the session's attributes
response.speech(text)
Param: text String
Convenience method to set speech with raw text or SSML
response.reprompt(text)
Param: text String
Convenience method to set reprompt with raw text or SSML
response.card(card)
Param: card Object
a valid [Alexa Card Object](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/alexa-skills-kit-interface-reference#Response Format)
Convenience method to set the response card
response.endSession(shouldEndSession)
Param: shouldEndSession Boolean
A convenience to set the response shouldEndSession
property
response.clearSession()
Clears the current session
response.next(config)
Param: config Object|Array
If you pass an object it will be merged with any previous Next Action Objects that were passed
The Next Action Object
type
Required
Type: String
One of 'intent', 'launch', 'sessionEnded', or 'unexpected'
action
Required
Type: String
The name of the action that should be called if this route is activated
intent
Required if type === 'intent'
Type: String
The custom or built-in intent that this action should be associated with. e.g. 'AMAZON.YesIntent'
params
Optional
Type: Any
Any data you'd like to pass to follow request if this route is activated
params
Type: Object
Params set by a previous action
config.global
Optional
Type: Object
Actions with the global key are accessible at any point in the routing flow (like a catch-all). These actions can be used to kick-off a new flow, interrupt an existing flow, etc. An action to help the user know what commands are available or cancel the request are two examples for where you might use a global action.
config.global.type
Required
Type: String
One of 'intent', 'launch', 'sessionEnded', or 'unexpected'
config.global.intent
Required if type === 'intent'
Type: String
The custom or built-in intent that this action should be associated with. e.g. 'AMAZON.YesIntent'
Examples
A simple action that can be activated by an incoming intent
alexa.action('global-hello', {
handler: request => {...},
global: {
type: 'intent', // Could also be launch, sessionEnded or unexpected
intent: 'AMAZON.YesIntent'
}
})
You can also chain requests by responding with a list of possible actions that could be next in the interaction flow
alexa.action('event-create', {
handler: request => {
let response = request.response()
response.speech('What\'s the name of your event?')
// You can define the next actions by passing an array of actions that can come next
response.next([
{
type: 'intent',
intent: 'EventName', // Custom intent
action: 'event-create-name'
params: { createdAt: new Date() } // Params will be passed to the `event-create-name` handler
},
{
type: 'intent',
intent: 'AMAZON.CancelIntent', // Built-in intent
action: 'event-cancel'
}
])
// You can also pass an individual object and it will be merged with the previous ones
response.next({
type: 'unexpected',
action: 'event-unexpected'
})
return response
},
global: {
type: 'intent',
intent: 'EventCreate' // Custom intent
}
})
// This action does not have the global attribute so it can only be accessed if passed
// as a `next` action
alexa.action('event-create-name', {
handler: (request, params) => {...}
})
alexa.dispatch
The dispatch method takes a HTTP request and routes it to the appropriate action
API
alexa.dispatch(requestBody, headers)
requestBody
Required Type: 'Object'
The HTTP request body
Headers
Required Type: 'Object'
The headers present in the original incoming request
Understanding the routing mechanism
- Check if the incoming request was configured with
next
actions - If
next
actions are present, try to resolve the next action - If no action was resolved, check for an
unexpected
typenext
option - If no next actions are present in the request's session, try to match a global action
- If no global action was found try to find an
unexpected
global action - If no
unexpected
global action then throwRoutingFailed
HTTP handling
alexa-router
is HTTP server agnostic. This means that you can use it with
any Node.js library that can parse and reply JSON. An example using Express:
let express = require('express')
let bodyParser = require('body-parser')
let Alexa = require('alexa-router')
let app = express()
let alexa = new Alexa.Router({
appId: 'my-app-id'
})
// Do all your routing configs
alexa.action('my-action', ...)
// Configure a route for passing JSON to alexa-router
app.post('/alexa/incoming', bodyParser.json(), (req, res) => {
alexa.dispatch(req.body, req.headers)
.then(result => res.json(result))
.catch(err => {
res.send('Somthing bad happened...').status(500)
})
})
To-do
- [ ] Add plugin support
- [ ] Add more testing cases
- [ ] Build plugins for Express, Hapi, Restify (...)
Testing
git clone https://github.com/estate/alexa-router && cd alexa-router
npm install && npm test