SSMLをJSX/TSXで書くための軽量ライブラリ@talkyjs/ssml

Alexa Live 2020まではssml-tsxを使っていたのですが、JSXの定義周りでask-sdk-jsx-for-aplと衝突するらしく、どうせならと簡単なものを作りました。

@talkyjs/ssml

ReactのJSXに乗っかるための型定義と、SSML to Stringする関数だけなのでかなりあっさりしています。

Install

ask-sdk-jsx-for-apl にかなり寄せたので、依存も大体一緒です。

$ npm install -S @talkyjs/ssml react react-dom

# (Optional) with ask-sdk-jsx-for-apl
$ npm install -S ask-sdk-jsx-for-apl

# (Optional) with TypeScript
$ npm install -D @types/react @types/react-dom

(Optional) tsconfig.jsonに注意

この2つの設定が漏れると事故りやすいです。

...
    "jsx": "react",
    "esModuleInterop": true,
...

AlexaのレスポンスをJSXで

@talkyjs/ssmlask-sdk-jsx-for-aplを使うと、APLもSSMLもJSX / TSXでかけるのでReact遣い的にはとても捗ります。.

ssml.jsx

import React from 'react'
import '@talkyjs/ssml'

export const LaunchRequestSpeech = () => {
    return (
        <speak>
            hello It's a great thing,
            and there is test. 
            <emphasis level="reduced">hello</emphasis>
            <w role="amazon:NN">aaaa</w>
            <amazon-domain name="music">Music</amazon-domain>
            <amazon-effect name="whispered">aaaa</amazon-effect>
            <amazon-emotion name="disappointed" intensity="high">aaaa</amazon-emotion>
        </speak>
    )
}

apl.jsx

import React from 'react';
import { APL, MainTemplate, Container, Text, AplDocument } from 'ask-sdk-jsx-for-apl';

export const LaunchAplDocumentFC = () => {
    const launchMessage = 'Welcome to my first JSX for APL skill!';
    return (
        <APL theme="dark">
            <MainTemplate>
                <Container
                    alignItems="center"
                    justifyContent="spaceAround">
                    <Text
                        text={launchMessage}
                        fontSize="50px"
                        color="rgb(251,184,41)" />
                </Container>
            </MainTemplate>
        </APL>
    );
}

LaunchRequest.jsx

import React from 'react'
import { renderSSMLToString } from "@talkyjs/ssml";
import { AplDocument } from "ask-sdk-jsx-for-apl";

import { LaunchAplDocumentFC } from "./apl";
import { LaunchRequestSpeech } from "./ssml";

export const LaunchRequestHandler = {
    canHandle(input) {
        return input.requestEnvelope.request.type === 'LaunchRequest'
    },
    async handle(input) {
        return input.responseBuilder
            .speak(
                renderSSMLToString(
                    <LaunchRequestSpeech />
                )
            )
            .addDirective(
                new AplDocument(
                    <LaunchAplDocumentFC />
                ).getDirective()
            )
            .getResponse()
    }
}

The response

{
  "directives": [
    {
      "document": {
        "mainTemplate": {
          "items": [
            {
              "alignItems": "center",
              "items": [
                {
                  "color": "rgb(251,184,41)",
                  "fontSize": "50px",
                  "text": "Welcome to my first JSX for APL skill!",
                  "type": "Text"
                }
              ],
              "justifyContent": "spaceAround",
              "type": "Container"
            }
          ],
          "parameters": []
        },
        "theme": "dark",
        "type": "APL",
        "version": "1.4"
      },
      "type": "Alexa.Presentation.APL.RenderDocument"
    }
  ],
  "outputSpeech": {
    "ssml": "<speak>hello It's a great thing, and there is test.<emphasis level="reduced">hello</emphasis><w role="amazon:NN">aaaa</w><amazon:domain name="music">Music</amazon:domain><amazon:effect name="whispered">aaaa</amazon:effect><amazon:emotion name="disappointed" intensity="high">aaaa</amazon:emotion></speak>",
    "type": "SSML"
  }
}

Comment