APLデータソースとトランスフォーマー



APLデータソースとトランスフォーマー

データソースは、APLドキュメントにバインドできるソースを定義します。スキル開発者がAPLドキュメントをAlexaに送信するとき、1つ以上のデータソースを添付できます。データソースは、APLドキュメントのパラメーターに名前でバインドされます。ドキュメント内のAPLコンポーネントは、${..}形式のAPLデータバインディング式を使ってこれらのデータソースを参照できます。

データソースはRenderDocumentディレクティブの一部であるdatasourcesオブジェクト内にありますが、APLドキュメントの外にあります。このdatasourcesオブジェクトには他のオブジェクト(実際のデータソース)のみ含めることができます。データソースにアクセスするには、APLドキュメントのmainTemplateで、ルートdatasourcesオブジェクトを指すpayloadというパラメーターを宣言します。次の応答ではmyDocumentDataという1つのデータソースにバインドするAPLドキュメントを示しています。データソース名は開発者が選択できますが、APLドキュメント内のデータソースのプロパティにバインドするときは、同じ名前を使用する必要があります。

{
  "version": "1.0",
  "response": {
    "outputSpeech": {
      "type": "SSML",
      "ssml": "<speak>これは例です</speak>"
    },
    "directives": [
      {
        "type": "Alexa.Presentation.APL.RenderDocument",
        "token": "[SkillProvidedToken]",
        "document": {
          "type": "APL",
          "version": "1.0",
          "theme": "auto",
          "import": [
            {
              "name": "alexa-layouts",
              "version": "1.0.0"
            }
          ],
          "resources": [
            {
              "description": "ライトテーマ向けにストックされた色",
              "colors": {
                "colorTextPrimary": "#151920"
              }
            },
            {
              "description": "ダークテーマ向けにストックされた色",
              "when": "${viewport.theme == 'dark'}",
              "colors": {
                "colorTextPrimary": "#f0f1ef"
              }
            }
            ],
          "styles": {
            "textStyleBase": {
              "description": "基本フォントの説明:設定された色とコアフォントファミリ",
              "values": [
                {
                  "color": "@colorTextPrimary",
                  "fontFamily": "Amazon Ember Display"
                }
              ]
            }
          },
          "layouts": {},
          "mainTemplate": {
            "parameters": [
              "payload"
            ],
            "items": [
              {
                "type": "Container",
                "direction": "column",
                "width": "100vw",
                "height": "100vh",
                "items": [
                  {
                    "type": "Text",
                    "text": "${payload.myDocumentData.title}"
                  }
                ]
              }
            ]
          }
        },
        "datasources": {
          "myDocumentData": {
            "title": "これはとても単純な例です"
          }
        }
      }
    ]
  },
  "userAgent": "ask-node/2.0.7 Node/v6.10.3",
  "sessionAttributes": {}
}

オブジェクト型のデータソース

APLはobject型のデータソースもサポートしています。型付けされていないデータソースと違い、構造が規定されている型付けされたデータソースは、データソース値の変換といった追加機能を有効にするのに使用できます。以下はオブジェクトデータソースに適用できるプロパティを示しています。object型のデータソースによって、スキル開発者はトランスフォーマーを使用できるようになります。トランスフォーマーはAPLドキュメントにヒントを追加したり、SpeakItemコマンドで使用できるようにSSML式を音声に変換したりすることに使えます。トランスフォーマーを参照してください。

プロパティ 必須 説明
type オブジェクト 「オブジェクト」である必要があります。
properties オブジェクト トランスフォーマーで使用できるバインド可能なプロパティを含むオブジェクトです。
objectID 文字列 オブジェクトデータソースの任意の識別子です。
description 文字列 データソースの任意の説明です。
transformers 配列 プロパティオブジェクトの値に適用されるトランスフォーマーの配列です。

下記のコードは、ssmlToSpeechトランスフォーマーを使用するオブジェクトデータソースを示しています。スキル開発者は、Textコンポーネントと関連する音声をAlexaで再生するために、SpeakItemコマンドも発行する必要があることに注意してください。

データソースタイプ

現在、以下のデータソースタイプがサポートされています。

  • オブジェクト: 単一の固定されたJSONオブジェクト

データソースのtypeプロパティはデータソースタイプを区別するのに使われます。

オブジェクトデータソース

objectデータソースは、静的データのシンプルなJSONオブジェクトです。JSONデータは固定されており、サーバーによって変わることはありません。オブジェクトデータソースのプロパティは次のとおりです。

プロパティ 必須 説明
description 文字列 データソースの任意の説明です。
objectID 文字列 オブジェクトデータソースの任意の識別子です。
properties マップ データソースを構成するバインド可能なプロパティのコレクションです。これは埋め込みのJSONオブジェクトです。
translators 配列 トランスフォーマー
type オブジェクト 「オブジェクト」である必要があります。

以下は「recipe」という名前のオブジェクトデータソースの例です。propertiesオブジェクトは任意の複合型であることに注意してください。

{
  "datasources": {
    "recipe": {
      "type": "object",
      "properties": {
        "title": "スコティッシュショートブレッド",
        "makes": "48個分",
        "time": {
          "prep": "15分",
          "bake": "20分"
        },
        "ingredients": [
          "バター2カップ、柔らかくしておきます",
          "ブラウンシュガー1カップ",
          "中力粉4~4 1/2カップ"
        ]
      }
    }
  }
}

このオブジェクトデータソースは、APLドキュメントと共に次のように使用されます。ボタンをクリックするとドキュメントが表示されます。

トランスフォーマーを参照してください。

トランスフォーマー

トランスフォーマーは、データソースのデータを別の表現に変換します。RenderDocumentディレクティブは、現在、3つのトランスフォーマーをサポートしています。

  • ssmlToSpeech: プレーンテキストまたは音声合成マークアップ言語(SSML)を、APLコンポーネントの音声プロパティとのバインディングに適した音声に変換するトランスフォーマーです。その後、SpeakItem APLコマンドを使用して、コンポーネントに関連付けられた音声を読み上げることができます。audioタグssmlToSpeechトランスフォーマーと一緒に使うことはできません。

  • ssmlToText: SSMLをプレーンテキストに変換するトランスフォーマーです。

  • textToHint: テキストを変換するAlexaウェイクワード(Alexa、Computer、Echo、Amazon)をAlexaヒント文字列に追加するトランスフォーマーです。

トランスフォーマーはデータソース内の名前付きプロパティのデータ変換を実行して、元のデータソースのプロパティにデータを書き込みます。outputNameが指定されていない場合、トランスフォーマーは入力プロパティを上書きします。すべてのトランスフォーマーには、次の表に示す基本プロパティがあります。

プロパティ 必須 説明
transformer 文字列 トランスフォーマーのタイプです。
inputPath 文字列 オブジェクト内の、変換される部分へのパスです。
outputName 文字列 オブジェクトに追加されるプロパティの名前です。outputNameが指定されていない場合、inputPathは変換された出力で上書きされます。

inputPathはソースオブジェクトの1つのエンティティを一義的に参照するか、ワイルドカードのプロパティまたは未解決配列を使ってエンティティセットを参照することができます。inputPathと一致するプロパティが変換されます。inputPathパターンはシンボルで、一定数のノードまたはワイルドカード参照が後に続きます。

次のルールが適用されます。

  • シンボル名または配列インデックスは、プロパティブロック内の既存のオブジェクトプロパティまたは配列インデックスと一致する必要があります。一致しない場合、変換は破棄されます。

  • 出力が保存されている場所は、ワイルドカード以外の最後のノードをoutputNameで置き換えることで見つけられます。ワイルドカード以外のノードがない場合は、シンボルはoutputNameで置き換えられます。

  • 最後のワイルドカード以外のノードが数値インデックスになることはありません。最後のワイルドカード以外のノードが数値の場合は、変換は破棄されます。

これらの例は、参照のしくみを示しています。次のサンプルデータを考えてみましょう。

{
    "datasources": {
        "myDocumentData": {
            "type": "object",
            "properties": {
                "name": "山田太郎",
                "address": {
                    "street": "中央通り301番地",
                    "city": "目黒区"
                },
                "family": [
                    { "name": "花子", "relation": "妻" },
                    { "name": "桜子", "relation": "娘" }
                ],
                "contacts": [ "鈴木一郎", "鈴木梅子" ]
            },
            "transformers": [
            {
                "inputPath": [See Table Below],
                "outputName": [See Table Below],
                "transformer": "ssmlToSpeech"
            }
            ]
        }
    }
}
inputPath 変換される項目 結果の保存場所
name "山田太郎" outputName
address.street "中央通り301番地" address.outputName
contacts.* ["鈴木一郎", "鈴木梅子"] outputName[0], outputName[1]
family[0].name "花子" family[0].outputName
family[*].name "花子", "桜子" family[0].outputName, family[1].outputName
address.* "中央通り301番地", "目黒区" outputName.street, outputName.city

以下は機能しません。

  • family[3].name - 機能しません - ルール1を参照してください。

  • family[1].names - 機能しません - ルール1を参照してください。

  • family[0] { "name": "花子", "relation": "妻" } 機能しません - ルール3を参照してください。

ssmlToSpeechトランスフォーマー

SSMLから音声に変換するトランスフォーマーは、SSML文字列を音声に適したエンティティに変換します。SSMLから音声に変換するトランスフォーマーには、次の表に示すプロパティがあります。

プロパティ 必須 説明
transformer ssmlToSpeech トランスフォーマーの名前です。
inputPath 文字列 オブジェクト内から変換される部分へのパスです。
outputName 文字列 オブジェクトに追加されるプロパティの名前です。

SSMLから音声に変換するトランスフォーマーからの出力は、コンポーネントのspeechプロパティに関連付けられている必要があります。下記のコードは、猫の秘密にバインドされたTextコンポーネントに音声を関連付けた「猫の秘密」スキルを示しています。

{
    "type": "Container",
    "item": {
        "type": "Text",
        "id": "catFactText",
        "text": "${payload.catFactData.properties.catFact}",
        "speech": "${payload.catFactData.properties.catFactSpeech}"
    }
 }

次に、下記のコードは、スキルリクエストの一部として送信する必要がある、対応するオブジェクトデータソースとトランスフォーマーを示しています。

{
    "datasources": {
            "catFactData": {
                "type": "object",
                "properties": {
                    "backgroundImage": "https://.../catfacts.png",
                    "title": "猫の秘密 #9",
                    "logoUrl": "https://.../logo.png",
                    "image": "https://.../catfact9.png",
                    "catFactSsml": "<speak>すべての猫が<emphasis level='strong'>マタタビ</emphasis>を好むとは限りません。</speak>"
                },
                "transformers": [
                    {
                      "inputPath": "catFactSsml",
                      "outputName": "catFactSpeech",
                      "transformer": "ssmlToSpeech"
                    },
                    {
                      "inputPath": "catFactSsml",
                      "outputName": "catFact",
                      "transformer": "ssmlToText"
                    }
                ]
            }
    }
 }

最後に、猫の秘密を読み上げるには、Alexa.Presentation.APL.ExecuteCommandsディレクティブをSpeakItemコマンドで使用する必要があります。下記のコードは、猫の秘密を読み上げるために使用できるAlexa.Presentation.APL.ExecuteCommandsディレクティブを示します。ExecuteCommandsディレクティブで渡しているトークンは必須です。このトークンは、APLドキュメントの表示に使用するRenderDocumentディレクティブでスキルによって渡されるトークンと一致する必要があります。

{
    "type" : "Alexa.Presentation.APL.ExecuteCommands",
    "token": "[SkillProvidedToken]",
    "commands": [{
        "type": "SpeakItem",
        "componentId" : "catFactText",
        "highlightMode": "line",
        "align": "center"
    }]
 }

ssmlToTextトランスフォーマー

SSMLからテキストに変換するトランスフォーマーは、SSMLマークアップを削除することで、すべてのSSMLテキスト文字列を人が読みやすいテキストに変換します。このプロパティは、トランスフォーマー値をssmlToTextに設定する必要がある点を除いて、ssmlToSpeechトランスフォーマーと同じです。

textToHintトランスフォーマー

スキル開発者は、デバイスのウェイクワードを推測したり、「Alexa」をデフォルトにしたりしなくても、textToHintトランスフォーマーを使用して、APLドキュメントに表示されるヒント文字列に正しいウェイクワードを自動で追加できます。textToHintトランスフォーマーは、AlexaFooterレイアウトにバインドされたオブジェクトタイプのデータソースのプロパティに適用されます。次の表は、textToHintトランスフォーマーに適用可能なプロパティを示しています。

プロパティ 必須 説明
transformer textToHint テキストをヒントに変換するトランスフォーマーを呼び出すには、このプロパティをtextToHintに設定する必要があります。
inputPath 文字列 変換が必要なデータソースの値のパスです。
outputName 文字列 変換された出力を格納するデータソースのプロパティ名です。この出力プロパティは、入力プロパティと常に兄弟関係にあります。このため、outputNameを指定しないと、inputPath内の値がトランスフォーマーの出力値で置き換えられます。

ヒントを表示するには、alexa-layoutsパッケージをAPLドキュメントに読み込み、このパッケージの一部であるAlexaFooterをAPLドキュメントで使用します。以下のコードサンプルでは、AlexaFooterレイアウトを使用してヒントを表示するAPLドキュメントを示しています。AlexaFooterのfooterHintプロパティが、catFactDataデータソースのプロパティにどのようにバインドされているかに注意してください。

{
    "type": "APL",
    "version": "1.0",
    "import": [{
        "name": "alexa-layouts",
        "version": "1.0.0"
    }],
    "mainTemplate": {
        "parameters": [
            "payload"
        ],
        "items": [
            {
                "type": "Container",
                "items": [
                    {
                        "type": "AlexaHeader",
                        "title": "${payload.catFactData.properties.title}",
                        "attributionImage": "${payload.catFactData.properties.logoUrl}"
                    }
                ]
            },
            {
                "type": "ScrollView",
                "item": {
                    "type": "Text",
                    "id": "catFactText",
                    "text": "${payload.catFactData.properties.catFact}"
                }
            },
        {
            "type": "AlexaFooter",
            "footerHint": "${payload.catFactData.properties.hintString}"
        }
      ]    
    }
 }

以下のコードは、スキル開発者がデータソースをAlexaFooterのfooterHintにバインドする方法を示しています。例としてcatFactDataを取り上げると、catFactDataのデータソースには、データソースのhintStringプロパティに適用されるtextToHintトランスフォーマーが含まれています。トランスフォーマーを使用するには、変換するプロパティをオブジェクトデータソース内のpropertiesオブジェクトに配置する必要があります。このトランスフォーマーによって、hintStringがエンドユーザーに表示される「アレクサ、…と言ってみましょう」形式のヒントに変換されます。

{
    "datasources": {
        "catFactData": {
            "type": "object",
            "properties": {
                "title": "猫の秘密 #9",
                "logoUrl": "https://.../logo.png",
                "catFact": "すべての猫がマタタビを好むとは限りません。",
                "hintString": "ペルシャ猫の秘密を教えて"
            },
            "transformers": [
                {
                  "inputPath": "hintString",
                  "transformer": "textToHint"
                }
            ]
        }
    }
 }