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



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

(これはAPLの最新バージョンではありませんAPLの最新バージョンの資料を参照するには、その他のバージョンオプションをクリックしてください)

データソースとは、APLドキュメントにバインドできるデータのソースを定義するJSON構造のことです。APLドキュメントをAlexaに送信するときに、1つ以上のデータソースを含めることができます。データソースとは、APLドキュメントのパラメーターに名前でバインドされます。ドキュメント内のAPLコンポーネントでは、${..}スタイルのAPLデータバインディングの式を使用して、該当するデータソースを参照できます。

スキル応答のdatasourcesオブジェクト

データソースをAlexaに渡すときに使用するdatasourcesオブジェクトは、RenderDocumentディレクティブの一部ですが、APLドキュメント自体には含まれていません。このdatasourcesオブジェクトには他のオブジェクト(実際のデータソース)のみを含めることができます。

この例では、RenderDocumentディレクティブを使用したスキル応答を示しています。ドキュメントと「myDocumentData」という名前のデータソースがAlexaに渡されます。ドキュメントの内容は、簡潔に示すために省略しています。

{
  "version": "1.0",
  "response": {
    "outputSpeech": {
      "type": "SSML",
      "ssml": "<speak>これは例です</speak>"
    },
    "sessionAttributes": {},
    "directives": [
      {
        "type": "Alexa.Presentation.APL.RenderDocument",
        "token": "[SkillProvidedToken]",
        "document": {},
        "datasources": {
          "myDocumentData": {
            "title": "これはとても単純な例です"
          }
        }
      }
    ]
  }
}

ドキュメントのデータソースにアクセスする

データソースにアクセスするには、APLドキュメントのmainTemplateで、payloadというパラメーターを宣言します。このパラメーターは、応答の中でdatasourcesオブジェクトのルートに割り当てられます。したがって、ドキュメント内から、構文${payload.dataSourceName.propertyName}を使用して、ドキュメント内のプロパティをデータソース内のプロパティにバインドできます。

次の応答ではmyDocumentDataという1つのデータソースにバインドするAPLドキュメントを示しています。この場合、Textコンポーネントのtextプロパティは、myDocumentDataデータソースのtitleプロパティにバインドされています。スキルがこの応答をAlexaに送信すると、デバイスでは「これはとても単純な例です」というテキストが表示されます。

{
  "version": "1.0",
  "sessionAttributes": {},
  "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": [],
          "styles": {},
          "layouts": {},
          "mainTemplate": {
            "parameters": [
              "payload"
            ],
            "items": [
              {
                "type": "Container",
                "width": "100vw",
                "height": "100vh",
                "items": [
                  {
                    "type": "Text",
                    "text": "${payload.myDocumentData.title}"
                  }
                ]
              }
            ]
          }
        },
        "datasources": {
          "myDocumentData": {
            "title": "これはとても単純な例です"
          }
        }
      }
    ]
  }
}

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

上記の単純なデータソースは、一連のプロパティを定義する、型付けされていないデータソースの例です。APLでは、定義された構造に従った型付けされたデータソースもサポートしています。これにより、トランスフォーマーを使用してデータを操作するなど、追加機能を利用できるようになります。

型付けされたデータソースには、以下のプロパティがあります。

[SpeakItemコマンド]を使用して音声を読み上げるための式です。トランスフォーマーを参照してください。

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

この例は、ssmlToSpeechトランスフォーマーを使用したオブジェクトデータソースを示しています。トランスフォーマーはpropertiesオブジェクト内のデータを参照します。トランスフォーマーの使用方法について詳しくは、後述のトランスフォーマーをご覧ください。

{
  "myDocumentData": {
    "type": "object",
    "properties": {
      "title": "これはとても単純な例です"
    },
    "transformers": [
      {
        "inputPath": "title",
        "outputName": "titleSpeech",
        "transformer": "ssmlToSpeech"
      }
    ]
  }
}

トランスフォーマー

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

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

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

  • textToHint: Alexaヒント文字列に、ウェイクワード(アレクサ、コンピューター、エコー、アマゾンなど)をテキストに変換して追加するトランスフォーマーです。

トランスフォーマーのプロパティと変換規則

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

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

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

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

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

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

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

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

{
  "myDocumentData": {
    "type": "object",
    "properties": {
      "name": "山田太郎",
      "address": {
        "street": "中央通り301番地",
        "city": "目黒区"
      },
      "family": [
        {
          "name": "花子",
          "relation": "妻"
        },
        {
          "name": "桜子",
          "relation": "娘"
        }
      ],
      "contacts": [
        "鈴木一郎",
        "鈴木梅子"
      ]
    },
    "transformers": [
      {
        "inputPath": [],
        "outputName": [],
        "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}"
  }
}

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

{
  "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"
                }
            ]
        }
    }
 }