We recently released version two of the Alexa Skills Kit Software Development Kit (SDK) for Node.js, which included improvements to request handling, response building, and attribute management. For request handling specifically, we changed our approach to include all the attributes in a request, not just the name of an intent. The new syntax might be different, but the core logic remains while increasing flexibility. This post provides an overview of the request handling enhancements that will allow you to quickly build a rich voice experience.
Every interaction between the Alexa voice service and your skill is really just a few JSON objects traveling back and forth. Our SDKs (for Node.js and Java) make it easier for you to build and minimize the amount of "boilerplate" code necessary. With the new version of the SDK, you define and register a list of handlers for each of your intents. Each handler has two parts—a `canHandle` function that defines what events the handler responds to, and a `Handle` function that contains the logic for how the handler responds.
In the previous version, the SDK would route requests based on only two properties, the `Request Type` and the `Intent Name`, and it would then match the request against the name of your handler function. While this approach is straightforward, it has limitations; handling requests based on any other property was difficult, and checking multiple properties required nested logic. For example, routing a request based on the value of one of your slots, required you to hand-code logic into multiple intent handlers, to cover all scenarios. This became evident when you built skills that leveraged states, as it meant you had to have a separate set of handlers for each of the states.
In the new SDK, request routing is all based on the condition/s set inside the `canHandle` function. This function is required in every intent handler, and it must return 'true' for each event that the handler can process. This lets you write a single handler for multiple intents, or handlers that check for other values, like Session Attributes. Here's a sample `canHandle` function from our fact skill sample template:
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'LaunchRequest'
||
(request.type === 'IntentRequest' && request.intent.name === 'GetNewFactIntent');
},
You'll notice that in this case, we are checking the type of request (request.type) as well as the name of the intent (request.intent.name). We could use the same structure to check a locale or the value of a slot. We can also use the `Attributes Manager` to check `Session Attributes` and route to a handler based on that.
The second required function for each intent handler is, `handle`. The contents of this function are less regimented, as it is up to you to define what logic to run. But in general, you will be using the `ResponseBuilder` to build your response and return it so the SDK sends the correct JSON object back. Take a look at the `handle` function for the 'GetNewFactIntent':
handle(handlerInput) {
const factArr = data;
const factIndex = Math.floor(Math.random() * factArr.length);
const randomFact = factArr[factIndex];
const speechOutput = GET_FACT_MESSAGE + randomFact;
return handlerInput.responseBuilder
.speak(speechOutput)
.withSimpleCard(SKILL_NAME, randomFact)
.getResponse();
}
In this case, we built a response that includes a string to be spoken, and a simple card that will be delivered to the customer’s Amazon Alexa app. Also, note that we are closing the session here, which is the default behavior of the responseBuilder. You can keep the session open by adding a `.reprompt()` or `.withShouldEndSession(false)` to your responseBuilder. So, like –
return handlerInput.responseBuilder
.speak(speechOutput)
.withSimpleCard(SKILL_NAME, randomFact)
.reprompt(‘Would you like another fact?’)
.getResponse();
Another addition to the SDK is that you must register all your request handlers. This step is important but easy to forget, since it was not required with the old SDK. If you write a handler but skip registering it, you will most likely get a `RequestHandlerChain` error when testing, since the SDK won't know where to route the request. The order in which you register handlers is important because the SDK will waterfall through all the registered handlers looking for one that will return `true` for each request. This means that if more than one handler would return `true` for an event, the one you register first will be the one that gets called. Consider registering your handlers from the most specific to the most general. You can see how we did that in the fact skill sample below:
skillBuilder.addRequestHandlers(
GetNewFactHandler,
HelpHandler,
ExitHandler,
SessionEndedRequestHandler
)
We can’t wait to see what you build using this new SDK. If you have questions, find me on Twitter @memodoring. For any issues with the SDK, please consider submitting a pull request through the GitHub repo.
When you create delightful skills with compelling content, customers win. You can make money through Alexa skills using in-skill purchasing or Amazon Pay for Alexa Skills. You can also make money for eligible skills that drive some of the highest customer engagement with Alexa Developer Rewards. Learn more about how you can make money with Alexa skills, and download our guide to learn which product best meets your needs.