@ask-utils/speech-script: Easy markup SSML like a React JSX

speech-script is a simple library to use JSX into your Alexa Skill’s code.

We can easy to write a SSML like a React application.

Install

$ npm i -S @ask-utils/speech-script

Preparetion

To use JSX, we need to update any configuration.

For TypeScript

We have to set jsx property on tsconfig.json

$ vim tsconfig.json
{
  "compilerOptions": {
    "lib": ["es2017"],
    "jsx": "react", // ADD THE LINE 

For Webpack

We need to add resolver for build tool like a Webpack.

$ vim webpack.config.js

module.exports = {
...
  resolve: {
    // `ADD .tsx` HERE
    extensions: ['.mjs', '.json', '.ts', '.tsx'],
    symlinks: false,

Usage

We can create a JSX component for SSML.

Example1: launchRequest.tsx

The file is written just SSML. We can easy to get the request.this.props.request is same as the requestEnvelope.

/** @jsx ssml */
import {
    StandardSkillFactory
} from 'ask-sdk'
import {
    ssml,
    SpeechScriptJSX
} from '../dist/index'
import { LaunchRequest } from 'ask-sdk-model'

/**
 * SSML component like React
 **/
export class LaunchRequestScript extends SpeechScriptJSX<LaunchRequest> {
    speech() {
        const { locale } = this.props.request
        return (
            <speak>
                Hello from {locale}!
                <break time="0.5s"/>How are you?
            </speak>
        )
    }
}

Example2: launchRequest.handler.ts

We can easy to create any RequestHandler using the JSX component.

import { LaunchRequestScript } from './launchRequest.tsx'

export const LaunchRequestHandler = {
    canHandle(handlerInput) {
        return handlerInput.requestEnvelope.request.type === 'LaunchRequest'
    },
    handle(handlerInput) {
        const Speech = new LaunchRequestScript(handlerInput)
        return Speech.createResponse()
    }
}

Request handler does not care about What should we say?. Just handle the Skill’s request and correct parameter from request and any API response to pass the JSX element.

Advanced usecase

The SpeechScript class can put any additional property.

In the example, the handler pass the name property to the JSX element.

/** @jsx ssml */
import {
    StandardSkillFactory
} from 'ask-sdk'
import {
    ssml,
    SpeechScriptJSX
} from '../dist/index'
import { LaunchRequest } from 'ask-sdk-model'

/**
 * SSML component like React
 **/
class LaunchRequestScript extends SpeechScriptJSX<LaunchRequest, {name: string}> {
    speech() {
        const name = this.options ? `${this.options.name}-san` : ''
        return (
            <speak>
                Hello {name}! <break time="0.5s"/>How are you?
            </speak>
        )
    }
}

/**
 * Use the SSML component in your RequestHandler
 **/
export const handler = StandardSkillFactory.init()
.addRequestHandlers({
    canHandle(handlerInput) {
        return handlerInput.requestEnvelope.request.type === 'LaunchRequest'
    },
    handle(handlerInput) {
        const Speech = new LaunchRequestScript(handlerInput, {
            name: 'John'
        })
        return Speech.createResponse()
    }
}).lambda()

Blog post about the package