トランスフォーマー
トランスフォーマーは、Alexa Presentation Language(APL)データソースのデータを別の表現に変換します。オブジェクトデータソースのtransformersプロパティにトランスフォーマーオブジェクトの配列を含めることができます。
利用可能なトランスフォーマー
APLは、以下のトランスフォーマーをサポートします。
aplAudioToSpeech- APL for Audioドキュメントを変換して、APLコンポーネントのspeechプロパティにバインドできるオーディオを生成します。その後、SpeakItemまたはSpeakListを使用してAlexaにオーディオの再生を指示できます。lineBreakProcessor- テキスト入力を更新して、改行するべきでない文字シーケンスの周囲に<nobr>タグを追加します。ssmlToSpeech- 音声合成マークアップ言語(SSML)の入力を変換して、APLコンポーネントのspeechプロパティにバインドできる音声を生成します。その後、SpeakItemコマンドまたはSpeakListコマンドを使用してAlexaに音声の再生を指示できます。- audioタグを
ssmlToSpeechトランスフォーマーと一緒に使用することはできません。 - このトランスフォーマーに渡すテキストは、
<speak>タグで囲まれた有効なSSMLである必要があります。
- audioタグを
ssmlToText- 入力のSSMLをプレーンテキストに変換します。textToHint- ユーザーがデバイスに設定した正しいウェイクワードを使用して、入力をヒントに変換します(「『アレクサ、ヒント』と言ってみてください」など)。デバイスのウェイクワードはユーザーが選択できるため、ヒントに「アレクサ」というワードをハードコードしないでください。textToSpeech- 入力のプレーンテキストを変換して、APLコンポーネントのspeechプロパティにバインドできる音声を生成します。その後、SpeakItemAPLコマンドを使用して、コンポーネントに関連付けられた音声を読み上げることができます。このトランスフォーマーは、SSMLタグのないプレーンテキストを受け取ります。
トランスフォーマーのプロパティと変換規則
トランスフォーマーは、データソース内の名前付きプロパティからデータを取得し、変換を実行して、元のデータソースのプロパティにデータを書き込みます。outputNameが指定されていない場合、トランスフォーマーはinputプロパティを上書きします。トランスフォーマーには、次の表に示す基本プロパティがあります。
| プロパティ | 型 | 必須 | 説明 |
|---|---|---|---|
transformer |
文字列 | ◯ | トランスフォーマーのタイプです。 |
inputPath |
文字列 | ◯ | 変換するコンテンツの、オブジェクト内でのパスを指定します。データソースのpropertiesオブジェクト内のプロパティを参照する必要があります。 |
outputName |
文字列 | × | オブジェクトに追加されるプロパティの名前です。outputNameが指定されていない場合は、inputPathが、変換された出力で上書きされます。 |
template |
文字列 | × | RenderDocumentディレクティブのsourcesオブジェクトで提供されるAPL for Audioドキュメントを参照します。aplAudioToSpeechトランスフォーマーにのみ適用されます。 |
inputPathは、データソースオブジェクト内の単一のエンティティを指すか、ワイルドカードでプロパティまたは未解決配列を表すことで一連のエンティティを参照します。inputPathに一致する各プロパティが変換されます。inputPathパターンでは、シンボルの後に、ノードのインデックス番号やワイルドカード参照を続けます。
次のルールが適用されます。
-
シンボル名または配列インデックスは、propertiesブロック内の既存のオブジェクトプロパティまたは配列インデックスに一致する必要があります。一致しない場合、変換は破棄されます。
-
出力の保存場所は、ワイルドカード以外の最後のノードをoutputNameに置き換えたものになります。ワイルドカード以外のノードがない場合、シンボルがoutputNameで置き換えられます。
-
ワイルドカード以外の最後のノードを数値インデックスにすることはできません。ワイルドカード以外の最後のノードが数値の場合、変換は破棄されます。
以下の例では、参照がどのように解決されるかを示します。次のサンプルデータがあるとします。
{
"myDocumentData": {
"type": "object",
"properties": {
"name": "山田太郎",
"address": {
"street": "中央通り301番地",
"city": "目黒区"
},
"family": [
{
"name": "花子",
"relation": "妻"
},
{
"name": "桜子",
"relation": "娘"
}
],
"contacts": [
"鈴木一郎",
"鈴木梅子"
]
},
"transformers": [
{
"inputPath": ["下表の例を参照"],
"outputName": ["下表の例を参照"],
"transformer": "textToSpeech"
}
]
}
}
次の表は、inputPathとoutputNameにさまざまな値を指定した場合に、上記のデータソースのデータがどのように変換されるかを示しています。
| 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プロパティにバインドできるオーディオを生成します。その後、SpeakItemまたはSpeakListを使用してAlexaにオーディオの再生を指示できます。
aplAudioToSpeechトランスフォーマーには、次のプロパティがあります。
| プロパティ | 型 | 必須 | 説明 |
|---|---|---|---|
transformer |
文字列 | ◯ | aplAudioToSpeechに設定します。 |
inputPath |
文字列 | × | APL for Audioドキュメントに代入するデータを含む、データソース内のオブジェクトのパスを指定します。 |
outputName |
文字列 | ◯ | 変換の結果と共にデータソースに追加されるプロパティの名前です。 |
template |
文字列 | ◯ | RenderDocumentディレクティブのsourcesプロパティで提供されるAPL for Audioドキュメントを参照します。これが、オーディオに変換されるドキュメントです。{identifierName}という構文に従います。 |
このトランスフォーマーのinputPathは、データソースオブジェクト内のエンティティまたはエンティティ配列を識別します。識別された各エンティティについて、トランスフォーマーは「data」という新しいプロパティをデータソースに追加します。次に、トランスフォーマーは変更されたデータソースを使用してAPL for Audioドキュメントを評価します。これにより、ドキュメントでデータバインディングを使用できるようになります。例については、inputPathのない変換の例を参照してください。
outputNameは、変換の結果を格納するために使用するデータソース内のプロパティを識別します。トランスフォーマーは、outputNameをオブジェクトとしてデータソースに追加して、urlプロパティを含めます。urlプロパティには再生するオーディオが含まれます。このurlプロパティを、APLドキュメント内のコンポーネントのspeechプロパティにバインドします。
templateには、変換するAPL for Audioドキュメント全体への参照を指定します。このドキュメントは、RenderDocumentディレクティブのsourcesプロパティで提供します。sourcesプロパティはキー/オブジェクトのマップです。sourcesのキーをtemplateの名前として使用します。
次の例では、RenderDocumentディレクティブのsourcesプロパティに、キーがcatFactAPLAudioのAPL for Audioドキュメントが1つ含まれています。このドキュメントをトランスフォーマーで使用するには、templateにcatFactAPLAudioを設定します。
{
"sources": {
"catFactAPLAudio": {
"type": "APLA",
"version": "0.91",
"mainTemplate": {
"items": [
{
"type": "Speech",
"contentType": "SSML",
"content": "<speak>すべての猫が<emphasis level='strong'>マタタビ</emphasis>を好むとは限りません。</speak>"
}
]
}
}
}
}
inputPathのない変換の例
inputPathプロパティは必須ではありません。以下は、inputPathのないドキュメントの例です。
この例は、RenderDocumentディレクティブのdocument、sources、datasourcesの各プロパティを示しています。
{
"document": {
"type": "APL",
"version": "2024.3",
"theme": "dark",
"mainTemplate": {
"parameters": [
"payload"
],
"items": {
"type": "Text",
"id": "catFactText",
"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",
"catFact": "すべての猫がマタタビを好むとは限りません。"
},
"transformers": [
{
"template": "catFactAPLAudio",
"outputName": "catFactAudio",
"transformer": "aplAudioToSpeech"
}
]
}
}
}
変換により、データソースのpropertiesオブジェクトにcatFactAudioという新しいオブジェクトが追加されます。この新しいオブジェクトにはurlプロパティがあり、再生するオーディオのURLが含まれています。この例では、Textプロパティのspeechコンポーネントでデータバインディング式${payload.catFactData.properties.catFactAudio.url}を使用して、そのオーディオを参照しています。
inputPathのある変換の例
以下の例では、変換中にinputPathプロパティを使用して、データソースのデータをAPL for Audioドキュメントに代入します。この例は、RenderDocumentディレクティブのdocument、sources、datasourcesの各プロパティを示しています。
APLドキュメントは、shoppingItems.properties.itemListのオブジェクト配列をSequenceのdataプロパティにバインドして、配列内のすべての項目のリストを表示します。APLAドキュメントは、名前の読み上げとバックグラウンドサウンドの再生を行うテンプレートを定義します。このテンプレートでは、nameとバックグラウンドサウンドのオーディオファイルを参照するためにデータバインディングも使用します。
トランスフォーマーは、inputPathをitemList.*に設定して、properties.itemList配列の項目を参照します。
{
"document": {
"type": "APL",
"version": "2024.3",
"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"
}
],
"speech": "${data.speech.url}"
}
]
}
}
},
"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": "Outdoor"
},
{
"name": "フリスビー",
"image": "https://imgur.com/t/frisbee/6yWhK5k",
"category": "Outdoor"
},
{
"name": "コーヒーポット",
"image": "https://imgur.com/gallery/IJwSUPE",
"category": "Kitchen"
}
],
"backgroundRoomAudio": {
"Bathroom": "https://bathroom_sounds.mp3",
"Kitchen": "https://kitchen_sounds.mp3",
"Outdoor": "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": "Outdoor",
"speech": {
"url": "https://www.amazonalexa.com/examples/mp3/baseballaudio.mp3"
}
},
{
"name": "フリスビー",
"image": "https://imgur.com/t/frisbee/6yWhK5k",
"category": "Outdoor",
"speech": {
"url": "https://www.amazonalexa.com/examples/mp3/frisbeeaudio.mp3"
}
},
{
"name": "コーヒーポット",
"image": "https://imgur.com/gallery/IJwSUPE",
"category": "Kitchen",
"speech": {
"url": "https://www.amazonalexa.com/examples/mp3/coffeepotaudio.mp3"
}
}
],
"backgroundRoomAudio": {
"Bathroom": "https://bathroom_sounds.mp3",
"Kitchen": "https://kitchen_sounds.mp3",
"Outdoor": "https://outdoor_sounds.mp3"
}
}
}
}
変換されたAPLAドキュメントのレンダリング
変換されたドキュメントをレンダリングするには、SpeakItemコマンドまたはSpeakListコマンドを使用します。このコマンドは、APLドキュメントでボタンの押下などに応じて直接トリガーできます。Alexa.Presentation.APL.ExecuteCommandsディレクティブを使用して、SpeakItemコマンドをスキルから直接デバイスに送信することもできます。
以下は、ExecuteCommandsディレクティブの例を示しています。
{
"type": "Alexa.Presentation.APL.ExecuteCommands",
"token": "[SkillProvidedToken]",
"commands": [
{
"type": "SpeakItem",
"componentId": "catFactText",
"highlightMode": "line",
"align": "center"
}
]
}
ExecuteCommandsディレクティブで渡しているtokenは必須です。これは、APLドキュメントのレンダリングに使用するRenderDocumentディレクティブでスキルから渡すトークンと一致する必要があります。
lineBreakProcessorトランスフォーマー
テキスト入力を更新して、改行するべきでない文字シーケンスの周囲に<nobr>タグを追加します。このトランスフォーマーは日本語のロケールで使用できます。
このトランスフォーマーには、次の表に示すプロパティがあります。
| プロパティ | 型 | 必須 | 説明 |
|---|---|---|---|
|
|
文字列 |
◯ |
|
|
|
文字列 |
◯ |
変換するテキスト入力を含む、データソース内のプロパティのパスを指定します。 |
|
|
文字列 |
× |
変換の結果と共に |
|
|
文字列 |
◯ |
|
次の例は、日本語テキストを含むデータソースで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で読み上げたことがなくても、アプリにはテキストが表示されます。
関連トピック
最終更新日: 2025 年 11 月 26 日