キャンバス プロンプト

ウェブアプリに情報をリレーするには、会話ロジックから Canvas レスポンスを送信する必要があります。Canvas レスポンスでは、次のいずれかを行うことができます。

  • ユーザーのデバイスでウェブアプリを全画面でレンダリングする
  • データを渡してウェブアプリを更新する

以下のセクションでは、各シナリオで Canvas レスポンスを返す方法について説明します。

インタラクティブ キャンバスを有効にする

Interactive Canvas を使用するには、特定の方法でアクションを構成する必要があります。Interactive Canvas を使用するアクションを作成するには、Actions Console で追加の構成が必要です(Actions SDK の場合は settings.yaml ファイルを修正します)。Actions SDK でインタラクティブ キャンバス アクションを作成して構成する詳しい手順については、プロジェクトの作成をご覧ください。

Actions Builder を使用する場合は、次の手順を行って Interactive Canvas を有効にします。

  1. [What type of Action do you want to build?] 画面で [Game] カードを選択していない場合は、上部のナビゲーションで [Deploy] をクリックします。[その他の情報] で [ゲーム &娯楽] カテゴリを選択します。 [保存] をクリックします。
  2. Actions Console の上部のナビゲーションで [Develop] をクリックします。
  3. 左側のナビゲーションで [Interactive Canvas] をクリックします。
  4. [Do you want your Action to use Interactive Canvas?] で、次のいずれかを選択します。
    • サーバー Webhook フルフィルメントを使用して Interactive Canvas を有効にします。このオプションは、特定の機能へのアクセスに Webhook を利用し、ウェブアプリにデータを渡すために頻繁に onUpdate() を使用します。有効にした場合、インテントの一致はシーンで処理されるため、別のシーンに移行したり会話を終了したりする前に Webhook を呼び出すように選択できます。
    • クライアント フルフィルメントを使用して Interactive Canvas を有効にします。このオプションを使用すると、Webhook フルフィルメント ロジックをウェブアプリに移動し、Webhook の呼び出しを、必要な会話機能(アカウントのリンクなど)のみに制限できます。有効にすると、expect() を使用してクライアント側でインテント ハンドラを登録できます。
  5. 省略可: [デフォルトのウェブアプリ URL を設定する] フィールドにウェブアプリの URL を入力します。このアクションにより、URL フィールドを含むデフォルトの Canvas レスポンスがメイン呼び出しに追加されます。
  6. [保存] をクリックします。

Actions SDK を使用する場合は、次の手順で Interactive Canvas を有効にします。

  1. アクションの説明をわかりやすくし、ユーザーがアクションを見つけやすくなるように、settings.yaml ファイルの category フィールドを GAMES_AND_TRIVIA に設定します。
  2. settings.yaml ファイルの usesInteractiveCanvas フィールドを true に設定します。

サーフェス機能を確認する

Interactive Canvas フレームワークは、ビジュアル インターフェースを備えたアシスタント デバイスでのみ動作するため、アクションはユーザーのデバイスの INTERACTIVE_CANVAS 機能を確認する必要があります。Actions Builder でプロンプトを定義するときに、candidates オブジェクトの selector フィールドにデバイス機能のリストを指定できます。プロンプト セレクタは、ユーザーのデバイスの機能に最も適したプロンプト候補を選択します。

Canvas レスポンスを返すには、アクションのロジックで次のことを行う必要があります。

  1. ユーザーのデバイスが INTERACTIVE_CANVAS 機能をサポートしていることを確認します。サポートしている場合は、ユーザーに Canvas レスポンスを送信します。
  2. Interactive Canvas 機能が使用できない場合は、ユーザーのデバイスが機能 RICH_RESPONSE をサポートしているかどうかを確認します。サポートしている場合は、代わりにリッチ レスポンスをユーザーに送信します。
  3. リッチ レスポンス機能を使用できない場合は、ユーザーにシンプルなレスポンスを送信します。

次のスニペットは、ユーザーのデバイスの機能に応じて適切なレスポンスを返します。

YAML

candidates:
  - selector:
      surface_capabilities:
        capabilities:
          - INTERACTIVE_CANVAS
    canvas:
      url: 'https://example.web.app'
  - selector:
      surface_capabilities:
        capabilities:
          - RICH_RESPONSE
    content:
      card:
        title: Card title
        text: Card Content
        image:
          url: 'https://example.com/image.png'
          alt: Alt text
        button:
          name: Link name
          open:
            url: 'https://example.com/'
  - first_simple:
      variants:
        - speech: Example simple response.
    

JSON

{
  "candidates": [
    {
      "selector": {
        "surface_capabilities": {
          "capabilities": [
            "INTERACTIVE_CANVAS"
          ]
        }
      },
      "canvas": {
        "url": "https://example.web.app"
      }
    },
    {
      "selector": {
        "surface_capabilities": {
          "capabilities": [
            "RICH_RESPONSE"
          ]
        }
      },
      "content": {
        "card": {
          "title": "Card title",
          "text": "Card Content",
          "image": {
            "url": "https://example.com/image.png",
            "alt": "Alt text"
          },
          "button": {
            "name": "Link name",
            "open": {
              "url": "https://example.com/"
            }
          }
        }
      }
    },
    {
      "first_simple": {
        "variants": [
          {
            "speech": "Example simple response."
          }
        ]
      }
    }
  ]
}

    

Node.js

const supportsRichResponse = conv.device.capabilities.includes("RICH_RESPONSE");
const supportsInteractiveCanvas = conv.device.capabilities.includes("INTERACTIVE_CANVAS");
if (supportsInteractiveCanvas) {
  // Respond with a Canvas response
  conv.add(new Canvas({
    url: 'https://example.web.app',
  }));
} else if (supportsRichResponse) {
  // Respond with a rich response
  conv.add(new Card({
    title: 'Card title',
    image: new Image({
      url: 'https://example.com/image.png',
      alt: 'Alt text',
    }),
    button: new Link({
      name: 'Link name',
      open: {
        url: 'https://example.com/',
      },
    }),
  }));
} else {
  // Respond with a simple response
  conv.add('Example simple response.');
}
  

ウェブアプリをレンダリングする

Interactive Canvas を使用するアクションには、レスポンスとしてユーザーに送信する、カスタマイズされたビジュアルを表示するウェブアプリが含まれています。ウェブアプリがレンダリングされると、ユーザーは会話が終了するまで、音声、テキスト、タップでウェブアプリを操作し続けます。

最初の Canvas レスポンスには、ウェブアプリの URL を含める必要があります。このタイプの Canvas レスポンスは、ユーザーのデバイス上でそのアドレスにウェブアプリをレンダリングするよう Google アシスタントに指示します。通常、ユーザーがアクションを呼び出した直後に、最初の Canvas レスポンスを送信します。ウェブアプリが読み込まれると、Interactive Canvas ライブラリが読み込まれ、ウェブアプリが Interactive Canvas API を使用してコールバック ハンドラを登録します。

次のスクリーンショットに示すように、Actions Builder でウェブアプリの URL を指定できます。

ウェブアプリの URL を指定した後に、Canvas レスポンスを含むプロンプトを作成すると、Actions Builder によって Canvas レスポンスの URL フィールドに自動入力が行われます。コンソールでウェブアプリの URL を設定する方法について詳しくは、インタラクティブ キャンバスを有効にするのセクションをご覧ください。

次のスニペットは、Actions Builder と Webhook の両方でウェブアプリをレンダリングする Canvas レスポンスを作成する方法を示しています。

YAML

candidates:
  - first_simple:
       variants:
         - speech: >-
             Welcome! Do you want me to change color or pause spinning? You can
             also tell me to ask you later.
     canvas:
       url: 'https://your-web-app.com'
    

JSON

{
  "candidates": [
    {
      "first_simple": {
        "variants": [
          {
            "speech": "Welcome! Do you want me to change color or pause spinning? You can also tell me to ask you later."
          }
        ]
      },
      "canvas": {
        "url": "https://your-web-app.com"
      }
    }
  ]
}
    

Node.js

app.handle('welcome', (conv) => {
  conv.add('Welcome! Do you want me to change color or pause spinning? ' +
    'You can also tell me to ask you later.');
  conv.add(new Canvas({
    url: `https://your-web-app.com`,
  }));
});
    

JSON

{
  "session": {
    "id": "session_id",
    "params": {}
  },
  "prompt": {
    "override": false,
    "firstSimple": {
      "speech": "Welcome! Do you want me to change color or pause spinning? You can also tell me to ask you later.",
      "text": "Welcome! Do you want me to change color or pause spinning? You can also tell me to ask you later."
    },
    "canvas": {
      "data": [],
      "suppressMic": false,
      "url": "https://your-web-app.com"
    }
  }
}
    

データを渡してウェブアプリを更新する

最初の Canvas レスポンスを送信した後、追加の Canvas レスポンスを使用して data を更新し、ウェブアプリのカスタム ロジックでウェブアプリに変更を加えます。ウェブアプリにデータを渡す Canvas レスポンスを送信すると、次の処理が行われます。

  1. シーン内でインテントが一致するとイベントがトリガーされ、JSON ペイロードを含む data フィールドを含む Canvas レスポンスがレスポンスとして返されます。
  2. data フィールドは onUpdate コールバックに渡され、ウェブアプリの更新に使用されます。
  3. 会話型アクションは、新しい Canvas レスポンスを送信し、新しい更新の送信や新しい状態の読み込みを行うための data フィールドに情報を提供できます。

ウェブアプリにデータを渡す方法は 2 つあります。

  • Actions Builder を使用するActions Builder は、ウェブアプリの更新に必要なメタデータを Canvas レスポンスの data フィールドに自動入力します。
  • Webhook を使用する場合。Webhook を使用する場合は、Canvas レスポンスでウェブアプリを更新するようにカスタム データ ペイロードを構成できます。

以降のセクションでは、Actions Builder と Webhook を介してデータを渡す方法について説明します。

Actions Builder を使用してデータを渡す

Actions Builder では、ウェブアプリに送信されるメタデータを管理するために Webhook を定義する必要はありません。代わりに、Actions Builder の UI でインテント ハンドラを構成するときに、Canvas レスポンスを含めることができます。data フィールドには、インテント名、ユーザー入力から取得したパラメータ、現在のシーンなど、ウェブアプリの更新に必要なメタデータが自動的に入力されます。

たとえば、次の Guess インテント ハンドラは、Canvas レスポンスを含める必要があることを示しています。

YAML

candidates:
  - canvas:
      send_state_data_to_canvas_app: true
    

JSON

{
  "candidates": [
    {
      "canvas": {
        "send_state_data_to_canvas_app": true
      }
    }
  ]
}
    

必要に応じて、次のスニペットをインテント ハンドラに追加して、TTS メッセージを送信できます。

...
  - first_simple:
      variants:
        - speech: Optional message.

Actions Builder は、以下のスニペットに示すように、メタデータを使用して Canvas レスポンスを自動的に拡張し、ウェブアプリを更新します。この例では、ユーザーは単語推測ゲームで文字「a」を推測しました。

YAML

candidates:
  - canvas:
      data:
        - google:
            intent:
              params:
                letter:
                  resolved: a
                  original: a
              name: guess
            scene: Game
      sendStateDataToCanvasApp: true
    

JSON

{
  "candidates": [
    {
      "canvas": {
        "data": [
          {
            "google": {
              "intent": {
                "params": {
                  "letter": {
                    "resolved": "a",
                    "original": "a"
                  }
                },
                "name": "guess"
              },
              "scene": "Game"
            }
          }
        ],
        "sendStateDataToCanvasApp": true
      }
    }
  ]
}
    

このレスポンスにより、ユーザーの回答でウェブアプリが更新され、適切なシーンに遷移します。

Webhook を使用してデータを渡す

ウェブアプリの更新に必要な状態情報を使用して、Webhook の Canvas レスポンスの data フィールドを手動で構成できます。ウェブアプリの更新に必要な一般的なメタデータだけでなく、カスタム data ペイロードを Canvas レスポンスに含める必要がある場合は、この方法をおすすめします。

次のスニペットは、Webhook の Canvas レスポンスでデータを渡す方法を示しています。

Node.js

app.handle('start_spin', (conv) => {
  conv.add(`Ok, I'm spinning. What else?`);
  conv.add(new Canvas({
    data: {
      command: 'SPIN',
      spin: true,
    },
  }));
});
    

JSON

{
  "session": {
    "id": "session_id",
    "params": {}
  },
  "prompt": {
    "override": false,
    "firstSimple": {
      "speech": "Ok, I'm spinning. What else?",
      "text": "Ok, I'm spinning. What else?"
    },
    "canvas": {
      "data": {
        "command": "SPIN",
        "spin": true
      },
      "suppressMic": false,
      "url": ""
    }
  }
}
    

ガイドラインと制限事項

アクションを作成する際は、Canvas レスポンスに関する次のガイドラインと制限事項に注意してください。

  • フルフィルメント内の各 Webhook ハンドラには Canvas を含める必要があります。Webhook レスポンスに Canvas が含まれていない場合、ウェブアプリは終了します。
  • ウェブアプリの URL は、ユーザーに送信する最初の Canvas レスポンスにのみ含める必要があります。
  • Canvas レスポンス URL が有効で、プロトコルが https である必要があります。
  • Canvas レスポンスのサイズは 50 KB 以下にする必要があります。