Router
Introduction
TalkyJS supports @ask-utils/router to create a new RequestHandler more easily.
import { Router } from "@ask-utils/router";
export const HelloWorldIntentRouter: Router = {
requestType: "IntentRequest",
intentName: "HelloWorldIntent",
handler: async (handlerInput) => {
return handlerInput.responseBuilder
.speak("Hello! It's a nice development. How are you?")
.reprompt("How are you?")
.getResponse()
}
}
export default HelloWorldIntentRouter
We can easy to define canHandle
method by using router.
Same Handler by ask-sdk
import { RequestHandler } from 'ask-sdk-core';
export const HelloWorldIntentHandler: RequestHandler = {
async canHandle(handlerInput) {
if (handlerInput.requestEnvelope.request.type !== 'IntentRequest') return false
return handlerInput.requestEnvelope.request.intent.name === "HelloWorldIntent"
},
async handle(handlerInput) {
return handlerInput.responseBuilder
.speak("Hello! It's a nice development. How are you?")
.reprompt("How are you?")
.getResponse()
}
}
export default HelloWorldIntentHandler
Generate by CLI
We can easy to create a new route file from TalkyJS CLI.
$ talky g router HelloWorldIntent
? What type do you handle the request? IntentRequest
? Which type do you want to write SSML? default
CREATE src/HelloWorldIntent/HelloWorldIntent.router.ts (449 bytes)
CREATE src/HelloWorldIntent/tests/HelloWorldIntent.router.spec.ts (1246 bytes)
Add Handler to TalkyJS
We can add a new Route file by using TalkyJS API as same as ask-sdk SkillBuilder.
import { SkillFactory } from '@talkyjs/core'
import HelloWorldIntentHandler from './HelloWorldIntent/HelloWorldIntent.router'
export const handler = SkillFactory.launch()
.addRequestRouters([
HelloWorldIntentHandler
])
.getSkill()
.lambda()
And also we can mix a handler and a router.
import { SkillFactory } from '@talkyjs/core'
import HelloWorldIntentHandler from './HelloWorldIntent/HelloWorldIntent.router'
import GoodByeIntentHandler from './GoodByeIntent/GoodByeIntent.handler'
export const handler = SkillFactory.launch()
.addRequestRouters([
HelloWorldIntentHandler
])
.addRequestHandlers(
GoodByeIntentHandler
)
.getSkill()
.lambda()
Situational Design
Requirement
If we want to use the Router power, we need to configure DB with DynamoDB or S3.
const config: TalkyJSSkillConfig = {
stage: 'production', // [Optional] Skill Stage
logLevel: 'error', // [Optional] Log level
database: { // [Optional] Database configuration
type: 's3', // [Optional] Database type (none / s3 / dynamodb)
tableName: 'example-bucket-name', // [Optional] Database table name
s3PathPrefix: 'path-prefix' // [Optional] [Only S3] S3 path prefix
},
skillId: 'ask.your.skill.id', // [Optional] Skill ID
errorHandler: { // [Optional] error handler configurations
usePreset: true,
}
}
Invocation Count
TalkyJS records the skill user's invocation count.
The number will increase when the skill launched.
(IfrequestEnvelope.session.new
is true, it will increase)
export const InitialLaunchRequestRouter: Router = {
requestType: "LaunchRequest",
situation: {
invocationCount: {
eq: 0
}
},
handler: async (handlerInput) => {
return handlerInput.responseBuilder
.speak("The handle will execute when invocation count is 0")
.getResponse()
}
}
export const CustomLaunchRequestRouter: Router = {
requestType: "LaunchRequest",
situation: {
invocationCount: {
gte: 5,
lte: 10
}
},
handler: async (handlerInput) => {
return handlerInput.responseBuilder
.speak("The handle will execute when 5 <= invocation count <= 10")
.getResponse()
}
}
export const Custom2LaunchRequestRouter: Router = {
requestType: "LaunchRequest",
situation: {
invocationCount: {
gt: 5,
lt: 10
}
},
handler: async (handlerInput) => {
return handlerInput.responseBuilder
.speak("The handle will execute when 5 < invocation count < 10")
.getResponse()
}
}
export const DefaultLaunchRequestRouter: Router = {
requestType: "LaunchRequest",
handler: async (handlerInput) => {
return handlerInput.responseBuilder
.speak("It is fallback of the LaunchRequest")
.getResponse()
}
}
Conversation Turn
And in the conversation session, we can handle the conversation turn.
export const InitialHelpIntentRouter: Router = {
requestType: "IntentRequest",
intentName: "AMAZON.HelpIntent",
situation: {
turnCount: {
eq: 1
}
},
handler: async (handlerInput) => {
return handlerInput.responseBuilder
.speak("The handle will execute when conversation turn is 1")
.getResponse()
}
}
export const CustomHelpIntentRouter: Router = {
requestType: "IntentRequest",
intentName: "AMAZON.HelpIntent",
situation: {
turnCount: {
gte: 5,
lte: 10
}
},
handler: async (handlerInput) => {
return handlerInput.responseBuilder
.speak("The handle will execute when 5 <= conversation turn <= 10")
.getResponse()
}
}
export const Custom2HelpIntentRouter: Router = {
requestType: "IntentRequest",
intentName: "AMAZON.HelpIntent",
situation: {
turnCount: {
gt: 5,
lt: 10
}
},
handler: async (handlerInput) => {
return handlerInput.responseBuilder
.speak("The handle will execute when 5 < conversation turn < 10")
.getResponse()
}
}
export const DefaultHelpIntentRouter: Router = {
requestType: "IntentRequest",
intentName: "AMAZON.HelpIntent",
handler: async (handlerInput) => {
return handlerInput.responseBuilder
.speak("It is fallback of the LaunchRequest")
.getResponse()
}
}
Custom condition
We can define custom function to handle the request.
In this example, the custom matcher will check the requestEnvelope.request.locale
.
export const HelpIntentForJapaneseRouter: Router = {
requestType: "IntentRequest",
intentName: "AMAZON.HelpIntent",
situation: {
custom(input) {
return /ja/.test(input.requestEnvelope.request.locale)
}
},
handler: async (handlerInput) => {
return handlerInput.responseBuilder
.speak("The route will execute only in ja locale.")
.getResponse()
}
}