トランスフォーマー



トランスフォーマー

トランスフォーマーは、Alexa Presentation Language(APL)データソースのデータを別の表現に変換します。オブジェクトデータソースtransformersプロパティにトランスフォーマーオブジェクトの配列を含めることができます。

利用可能なトランスフォーマー

APLは、以下のトランスフォーマーをサポートします。

  • aplAudioToSpeechAPL for AudioドキュメントをAPLコンポーネントのspeechプロパティにバインドできるオーディオに変換します。その後、SpeakItemSpeakListのいずれかを使ってオーディオを再生するようAlexaに指示できます。
  • lineBreakProcessor – 改行すべきではない文字シーケンスの周囲に<nobr>タグを追加してテキスト入力を更新します。
  • ssmlToSpeech – 音声合成マークアップ言語(SSML)の入力値を、APLコンポーネントのspeechプロパティにバインドできる音声に変換します。その後、SpeakItemSpeakListのいずれかを使ってスピーチ音声を再生するようAlexaに指示できます。
    • audioタグssmlToSpeechトランスフォーマーと一緒に使うことはできません。
    • このトランスフォーマーに渡されるテキストは、<speak>タグで囲まれた有効なSSMLである必要があります。
  • ssmlToText – 入力したSSMLをプレーンテキストに変換します。
  • textToHint – 入力された値を、デバイスに応じた正しいウェイクワードとヒント(「アレクサ、ヒントです」と言ってみて)に変換します。デバイスに応じたウェイクワードが選択されるので、ヒントに「アレクサ」というワードをハードコーディングしないでください。
  • textToSpeech – 入力したプレーンテキストをAPLコンポーネントのspeechプロパティにバインドできる音声に変換します。その後、SpeakItem APLコマンドを使用して、コンポーネントに関連付けられた音声を読み上げることができます。このトランスフォーマーはSSMLタグのないプレーンテキストを受け取ります。

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

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

プロパティ 必須 説明
transformer 文字列 トランスフォーマーのタイプです。
inputPath 文字列 オブジェクト内の、変換するコンテンツへのパスです。データソースのpropertiesオブジェクト内のプロパティを参照する必要があります。
outputName 文字列 オブジェクトに追加されるプロパティの名前です。outputNameが指定されていない場合、inputPathは変換された出力で上書きされます。
template 文字列 RenderDocumentディレクティブのsourcesオブジェクトで指定されたAPL for Audioドキュメントを参照します。aplAudioToSpeechトランスフォーマーのみに適用されます。

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": "textToSpeech"
      }
    ]
  }
}

次の表は、inputPathoutputNameのさまざまな値によって、上記のデータソースのデータがどのように変換されるかを示しています。

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   無効:family配列にはインデックス3の値が指定されていません。
family[1].names   無効:family[1]の値にはnamesプロパティが指定されていません。
family[0] { "name": "花子", "relation": "妻" } 無効:最後のワイルドカード以外のノードが数値インデックスになることはありません。

aplAudioToSpeechトランスフォーマー

APL for AudioドキュメントをAPLコンポーネントのspeechプロパティにバインドできるオーディオに変換します。その後、SpeakItemSpeakListのいずれかを使ってオーディオを再生するようAlexaに指示できます。

aplAudioToSpeechトランスフォーマーには以下のプロパティがあります。

プロパティ 必須 説明
transformer 文字列 aplAudioToSpeechに設定します。
inputPath 文字列 APL for Audioドキュメントで置き換えられるデータを含むデータソースのオブジェクトへのパスです。
outputName 文字列 変換の結果とともにデータソースに追加されるプロパティの名前です。
template 文字列 RenderDocumentディレクティブのsourcesプロパティで指定されたAPL for Audioドキュメントを参照します。これは、オーディオに変換するドキュメントです。構文{identifierName}に従います。

このトランスフォーマーのinputPathは、データソースオブジェクト内のエンティティまたはエンティティ配列を識別します。識別された各エンティティについて、トランスフォーマーはdataと呼ばれる新しいプロパティをデータソースに追加します。その後、トランスフォーマーは変更されたデータソースを使ってAPL for Audioドキュメントを評価します。これにより、ドキュメントでデータバインディングを使用できるようになります。例については、inputPathなしの変換の例を参照してください。

outputNameは、変換の結果に使用するデータソース内のプロパティを識別します。トランスフォーマーは、urlプロパティを使い、オブジェクトとしてoutputNameをデータソースに追加します。urlプロパティには再生するオーディオが含まれます。urlプロパティを、APLドキュメント内のコンポーネントのspeechプロパティにバインドします。

templateを使用して、変換するAPL for Audioドキュメント全体を参照できます。このドキュメントを、RenderDocumentディレクティブのsourcesプロパティに指定します。sourcesプロパティは、キー/オブジェクトのマップです。sourcesのキーをtemplateの名前として使用します。

この例では、RenderDocumentディレクティブのsourcesプロパティに1つのAPL for AudioドキュメントとキーcatFactAPLAudioが含まれています。このドキュメントをトランスフォーマーとともに使用するには、templatecatFactAPLAudioを設定します。

{
  "sources": {
    "catFactAPLAudio": {
      "type": "APLA",
      "version": "0.91",
      "mainTemplate": {
        "items": [
          {
            "type": "Speech",
            "contentType": "ssml",
            "content": "<speak>すべての猫が<emphasis level='strong'>マタタビ</emphasis>を好むとは限りません。</speak>"
          }
        ]
      }
    }
  }
}

inputPathなしの変換の例

inputPathプロパティは必須ではありません。以下は、inputPathのないドキュメントの例です。

この例には、RenderDocumentディレクティブのdocumentsourcesdatasourcesのプロパティが含まれています。

{
  "document": {
    "type": "APL",
    "version": "1.6",
    "theme": "dark",
    "mainTemplate": {
      "parameters": [
        "payload"
      ],
      "items": {
        "type": "Text",
        "text": "${payload.catFactData.properties.catFact}",
        "speech": "${payload.catFactData.properties.catFactAudio.url}"
      }
    }
  },
  "sources": {
    "catFactAPLAudio": {
      "type": "APLA",
      "version": "0.91",
      "mainTemplate": {
        "items": [
          {
            "type": "Speech",
            "contentType": "ssml",
            "content": "<speak>すべての猫が<emphasis level='strong'>マタタビ</emphasis>を好むとは限りません。</speak>"
          }
        ]
      }
    }
  },
  "datasources": {
    "catFactData": {
      "type": "object",
      "properties": {
        "backgroundImage": "https://.../catfacts.png",
        "title": "猫の秘密 #9",
        "logoUrl": "https://.../logo.png",
        "image": "https://.../catfact9.png"
      },
      "transformers": [
        {
          "template": "catFactAPLAudio",
          "outputName": "catFactAudio",
          "transformer": "aplAudioToSpeech"
        }
      ]
    }
  }
}

トランスフォーマーは、データソースのpropertiesオブジェクトに新しいオブジェクトcatFactAudioを追加します。この新しいオブジェクトには、再生するオーディオのURLを含むurlプロパティが含まれています。この例では、Textプロパティのspeechコンポーネントがデータバインディング式${payload.catFactData.properties.catFactAudio.url}を使用してそのオーディオを参照しています。

inputPathを使用した変換の例

以下の例は、変換中にinputPathプロパティを使用してAPL for Audioドキュメントのデータを置き換えるデータソースのデータを指定しています。この例には、RenderDocumentディレクティブのdocumentsourcesdatasourcesのプロパティが含まれています。

APLドキュメントはshoppingItems.properties.itemListのオブジェクト配列をSequencedataプロパティにバインドして、配列内のすべての項目のリストを表示します。APLAドキュメントは、名前を言い、バックグラウンドサウンドを再生するテンプレートを定義します。また、このテンプレートはデータバインディングも使用し、nameとバックグラウンドサウンドのオーディオファイルを参照します。

トランスフォーマーはinputPathitemList.*を設定し、properties.itemList配列の項目を参照します。

{
  "document": {
    "type": "APL",
    "version": "1.6",
    "theme": "dark",
    "mainTemplate": {
      "parameters": [
        "payload"
      ],
      "item": {
        "type": "Sequence",
        "width": "100%",
        "height": "100%",
        "data": "${payload.shoppingItems.properties.itemList}",
        "items": [
          {
            "type": "Container",
            "direction": "row",
            "items": [
              {
                "type": "Text",
                "text": "${data.name}",
                "color": "white"
              },
              {
                "type": "Image",
                "source": "${data.image}",
                "align": "top",
                "scale": "best-fit"
              }
            ]
          }
        ]
      }
    }
  },
  "sources": {
    "TextWithBackgroundAudio": {
      "type": "APLA",
      "version": "0.91",
      "mainTemplate": {
        "parameters": [
          "payload"
        ],
        "item": {
          "type": "Mixer",
          "items": [
            {
              "type": "Speech",
              "content": "${payload.data.name}"
            },
            {
              "type": "Audio",
              "source": "${payload.shoppingItems.properties.backgroundRoomAudio[payload.data.category]}"
            }
          ]
        }
      }
    }
  },
  "datasources": {
    "shoppingItems": {
      "type": "object",
      "properties": {
        "itemList": [
          {
            "name": "野球",
            "image": "https://imgur.com/gallery/Szbir",
            "category": "アウトドア"
          },
          {
            "name": "フリスビー",
            "image": "https://imgur.com/t/frisbee/6yWhK5k",
            "category": "アウトドア"
          },
          {
            "name": "コーヒーポット",
            "image": "https://imgur.com/gallery/IJwSUPE",
            "category": "キッチン"
          }
        ],
        "backgroundRoomAudio": {
          "バスルーム": "https://bathroom_sounds.mp3",
          "キッチン": "https://kitchen_sounds.mp3",
          "アウトドア": "https://outdoor_sounds.mp3"
        }
      },
      "transformers": [
        {
          "inputPath": "itemList.*",
          "outputName": "speech",
          "transformer": "aplAudioToSpeech",
          "template": "TextWithBackgroundAudio"
        }
      ]
    }
  }
}

トランスフォーマーはproperties.itemList配列の各項目について以下を実施します。

  • speechという新しいプロパティを追加します。「speech」という名前は、トランスフォーマーで定義されたoutputNameから取得しています。
  • APLAドキュメントをオーディオに変換します。dataを参照するデータバインディング式をitemList項目のデータで置き換えます。たとえば、トランスフォーマーが最初の項目を処理する際、${payload.data.name}が"野球"に、payload.shoppingItems.properties.backgroundRoomAudio[payload.data.category]がオーディオファイル"https://outdoor_sounds.mp3"に置き換わります。
  • 変換されたオーディオをspeechオブジェクトのurlプロパティに保存します。

以下は、変換されたデータソースの例です。

{
  "shoppingItems": {
    "type": "object",
    "properties": {
      "itemList": [
        {
          "name": "野球",
          "image": "https://imgur.com/gallery/Szbir",
          "category": "アウトドア",
          "speech": {
            "url": "https://www.amazonalexa.com/examples/mp3/baseballaudio.mp3"
          }
        },
        {
          "name": "フリスビー",
          "image": "https://imgur.com/t/frisbee/6yWhK5k",
          "category": "アウトドア",
          "speech": {
            "url": "https://www.amazonalexa.com/examples/mp3/frisbeeaudio.mp3"
          }
        },
        {
          "name": "コーヒーポット",
          "image": "https://imgur.com/gallery/IJwSUPE",
          "category": "キッチン",
          "speech": {
            "url": "https://www.amazonalexa.com/examples/mp3/coffeepotaudio.mp3"
          }
        }
      ],
      "backgroundRoomAudio": {
        "バスルーム": "https: //bathroom_sounds.mp3",
        "キッチン": "https: //kitchen_sounds.mp3",
        "アウトドア": "https://outdoor_sounds.mp3"
      }
    }
  }
}

変換されたAPLAドキュメントのレンダリング

変換されたドキュメントをレンダリングするには、SpeakItemSpeakListのいずれかのコマンドを使用します。このコマンドは、ボタンを押すなど、APLドキュメント内で直接起動できます。Alexa.Presentation.APL.ExecuteCommandsディレクティブを使用して、SpeakItemコマンドをスキルから直接デバイスに送信することもできます。

以下は、ExecuteCommandsディレクティブの例です。

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

ExecuteCommandsディレクティブで渡しているトークンは必須です。このトークンは、APLドキュメントの表示に使用するRenderDocumentディレクティブでスキルによって渡されるトークンと一致する必要があります。

lineBreakProcessorトランスフォーマー

改行すべきではない文字シーケンスの周囲に<nobr>タグを追加してテキスト入力を更新します。このトランスフォーマーは日本のロケールで使用できます。

トランスフォーマーには以下の表のプロパティがあります。

プロパティ 必須 説明

transformer

文字列

lineBreakProcessorを設定します。

inputPath

文字列

変換するテキスト入力を含むデータソースのプロパティへのパスです。propertiesオブジェクト内のプロパティである必要があります。

outputName

文字列

変換の結果とともにpropertiesオブジェクトに追加されるプロパティの名前です。指定しない場合、トランスフォーマーは結果をinputPathプロパティに書き込みます。

locale

文字列

inputPathで指定されたテキストのロケールです。改行すべきではない文字シーケンスを決定します。ja-JPなどの日本語ロケールである必要があります。

以下は、日本語テキストを使ったデータソースでlineBreakProcessorトランスフォーマーを使用する方法の例です。

{
  "catFactData": {
    "type": "object",
    "properties": {
      "myText": "EU、日本から渡航解禁へ 7月1日"
    },
    "transformers": [
      {
        "inputPath": "myText",
        "outputName": "transformedText",
        "transformer": "lineBreakProcessor",
        "locale": "ja-JP"
      }
    ]
  }
}

変換後、変換されたデータソースは次のようになります。

{
  "catFactData": {
    "type": "object",
    "properties": {
      "myText": "EU、日本から渡航解禁へ 7月1日",
      "transformedText": "<nobr>EU、</nobr><nobr>日本</nobr><nobr>から</nobr><nobr>渡航</nobr><nobr>解禁</nobr><nobr>へ</nobr><nobr>7月1日</nobr>"
    }
  }
}

ssmlToSpeechトランスフォーマー

ssmlToSpeechトランスフォーマーは、SSML文字列を音声に適したエンティティに変換します。このトランスフォーマーに渡されるテキストは、<speak>タグで囲まれた有効なSSMLである必要があります。プレーンテキストの場合は、代わりにtextToSpeechトランスフォーマーを使用してください。

ドキュメントにおいて、ssmlToSpeechトランスフォーマーの出力値をコンポーネントのspeechプロパティにバインドします。下記のコードは、猫の秘密にバインドされたTextコンポーネントに音声を関連付けた「猫の秘密」スキルを示しています。

textプロパティはcatFactData.properties.catFactを指し、speechコンポーネントはcatFactData.properties.catFactSpeechを指します。

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

次の例は、対応するcatFactDataデータソースを示しています。propertiesオブジェクトには、コンポーネントで使用する実際のテキストを含むcatFactSsmlプロパティがあります。このプロパティは、ssmlToSpeechおよびssmlToTextトランスフォーマーの両方の入力値として使用されます。

  • ssmlToSpeechトランスフォーマーは、catFactSsmlの値を音声に変換し、その出力値をcatFactSpeechという新しいプロパティに格納します。catFactSpeechプロパティは、前述のTextコンポーネントのspeechプロパティにバインドされています。
  • ssmlToTextトランスフォーマーは、catFactSsmlの値をプレーンテキストに変換し、出力値をcatFactという新しいプロパティに配置します。catFactプロパティは、前述のTextコンポーネントのtextプロパティにバインドされています。
{
  "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"
      }
    ]
  }
}

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

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

ssmlToSpeechトランスフォーマーで処理されたすべてのテキストは、Alexaアプリの音声履歴ページに表示されます。アプリのこのセクションには、Alexaのユーザーへの応答が表示されます。ssmlToSpeechテキストは、音声応答の一部とみなされます。テキストは、SpeakItemを使って処理したテキストを読み上げたことがなくてもアプリに表示されます。

ssmlToTextトランスフォーマー

SSMLからテキストに変換するトランスフォーマーは、SSMLマークアップを削除することで、すべてのSSMLテキスト文字列を人が読みやすいテキストに変換します。

textToHintトランスフォーマー

textToHintトランスフォーマーは入力された値を、デバイスに応じた正しいウェイクワードとヒント(「アレクサ、ヒントです」と言ってみて)に変換します。デバイスに応じたウェイクワードが選択されるので、ヒントに「アレクサ」という語をハードコーディングしないでください。通常、このトランスフォーマーはAlexaFooterレスポンシブ対応コンポーネントと共に使用します。

ヒントの表示例については、textToHintトランスフォーマーを使用するを参照してください。

textToSpeechトランスフォーマー

textToSpeechトランスフォーマーは、プレーンテキストを音声に適したエンティティに変換します。このトランスフォーマーに渡されるテキストは、プレーンテキストでなければなりません。SSMLテキストの場合は、代わりにssmlToSpeechトランスフォーマーを使用してください。

このトランスフォーマーは、ssmlToSpeechトランスフォーマーと同じように機能します。textToSpeechトランスフォーマーの出力値をコンポーネントのspeechプロパティにバインドして、SpeakItemコマンドを使用してテキストを読み上げます。

このデータソースの例では、前述のcatFactDataデータソースを示していますが、catFactTextプロパティにはプレーンテキストを使用しています。この場合、catFactTextプロパティは既にプレーンテキストであるため、ssmlToTextトランスフォーマーは不要です。

{
  "catFactData": {
    "type": "object",
    "properties": {
      "backgroundImage": "https://.../catfacts.png",
      "title": "猫の秘密 #9",
      "logoUrl": "https://.../logo.png",
      "image": "https://.../catfact9.png",
      "catFactText": "すべての猫がマタタビを好むとは限りません。"
    },
    "transformers": [
      {
        "inputPath": "catFactText",
        "outputName": "catFactSpeech",
        "transformer": "textToSpeech"
      }
    ]
  }
}

Textコンポーネントでは、このデータソースを次のように参照できます。

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

textプロパティは、変換されていないプレーンテキストのcatFactTextプロパティにバインドします。speechプロパティはトランスフォーマーの出力値にバインドします。

textToSpeechトランスフォーマーで処理されたすべてのテキストは、Alexaアプリの音声履歴ページに表示されます。アプリのこのセクションには、Alexaのユーザーへの応答が表示されます。textToSpeechテキストは、音声応答の一部とみなされます。テキストは、SpeakItemを使って処理したテキストを読み上げたことがなくてもアプリに表示されます。