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
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',
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?')
response.next([
{
type: 'intent',
intent: 'EventName',
action: 'event-create-name'
params: { createdAt: new Date() }
},
{
type: 'intent',
intent: 'AMAZON.CancelIntent',
action: 'event-cancel'
}
])
response.next({
type: 'unexpected',
action: 'event-unexpected'
})
return response
},
global: {
type: 'intent',
intent: 'EventCreate'
}
})
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
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
type next
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 throw RoutingFailed
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'
})
alexa.action('my-action', ...)
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
Testing
git clone https://github.com/estate/alexa-router && cd alexa-router
npm install && npm test