Amazon Alexaask-sdk

ask-sdk / ssml-tsx と Serverless Frameworkを使ってReactライクに発話を定義する

ask-sdkを使うことで、Alexaの会話内容をスクリプタブルに定義できます。 簡単なユースケースであればこれで事足りるのですが、SSMLを駆使した表現を目指すとなるとstringでSSMLを書かないといけない部分など […]

広告ここから
広告ここまで

ask-sdkを使うことで、Alexaの会話内容をスクリプタブルに定義できます。

input.responseBuilder.speak([
    'Hello world!',
    'This is a example sppech content from the skill',
    'The cardinal number is  <say-as interpret-as="cardinal">12345</say-as>''
  ].join(' ')).getResponse()

-> "<speak>Hello world! This is a example sppech content from the skill The cardinal number is  <say-as interpret-as="cardinal">12345</say-as></speak>"

簡単なユースケースであればこれで事足りるのですが、SSMLを駆使した表現を目指すとなるとstringでSSMLを書かないといけない部分などが断端辛くなってきます。

ssml-tsxを使ってReactライクに記述する

ReactなどのJSXを書いたことがある人であれば、ssml-tsx を使うのが良さげです。

$ yarn add ssml-tsx
$ vim tsconfig.json
{
  "compilerOptions": {
    "lib": ["es2017"],
    "jsx": "react", // この行を追記する

もしServerless FrameworkでLambdaを管理してる場合は webpack.config.jsも触りましょう。

...
module.exports = {
...
  resolve: {
    // `.tsx` を追加する
    extensions: ['.mjs', '.json', '.ts', '.tsx'],
    symlinks: false,

するとSSMLをTSXで定義できるようになります。

$ vim example.tsx
/** @jsx ssml */
import ssml, { renderToString } from "ssml-tsx";

export const speak = renderToString(
    <speak>
        Hello world! This is a example sppech content from the skill .
        The cardinal number is <say-as interpret-as="cardinal">12345</say-as>
    </speak>
);

$ vim index.ts
import {speak } from './example'
input.responseBuilder.speak(speak).getResponse()

-> <speak>Hello world! This is a example sppech content from the skill . The cardinal number is <say-as interpret-as="cardinal">12345</say-as></speak>"

Advanced usage

JSX / TSXなので、Reactのようにプロパティを渡すこともできます。カスタムコンポーネントを使う場合はFCをインポートして型をつけてやりましょう。

// example.tsx
/** @jsx ssml */
import ssml, { renderToString, FC } from "ssml-tsx";

type GreetingComponent = FC<{name?: string}>

const WelcomeMessage: GreetingComponent = ({name}) => {
    if (!name) return <p>Hello!</p>
    return <p>Hello {name} san!</p>
}

const GreetingMessage: GreetingComponent= ({name}) => (
    <speak>
        <WelcomeMessage name={name} />
        This is a example component to use ssml-tsx.
    </speak>
)

export const getGreetingPrompt = (name?: string) => renderToString(
    <GreetingMessage name={name} />
)

// index.ts
import { getGreetingPrompt } from './example'
input.responseBuilder.speak(getGreetingPrompt('John')).getResponse()

-> "<speak><p>Hello John san!</p>This is a example component to use ssml-tsx.</speak>"

こうなると条件分岐のある発話も結構楽にかけます。

既知の問題 (in Apr. 9)

今のところ amazon:domain / amazon:effect / amazon:emotion のタグはうまく動かない様子です。原因の検討はついたのでレポートとPR作成までやってありますので、遠からず解決するとは思います。

Apr. 10: the issue has been resolved

amazon:XXXタグについて、version 1.0.9にて解決されました。

https://github.com/jubilee-works/ssml-tsx/releases/tag/v1.0.9

<XXX:YYY>のようにコロンで区切るマークアップがJSXではできないため、<amazon-domain><amazon-effect>のようにハイフンで区切って実装する形となっています。

まとめ

結構こういう周辺ライブラリ入れると実装楽になるので、「おれの思う最強のAlexaスキル開発環境話」が増えてくるとうれしいなと思います。

ブックマークや限定記事(予定)など

WP Kyotoサポーター募集中

WordPressやフロントエンドアプリのホスティング、Algolia・AWSなどのサービス利用料を支援する「WP Kyotoサポーター」を募集しています。
月額または年額の有料プランを契約すると、ブックマーク機能などのサポーター限定機能がご利用いただけます。

14日間のトライアルも用意しておりますので、「このサイトよく見るな」という方はぜひご検討ください。

広告ここから
広告ここまで

Related Category posts