インタラクティブなダイアログを開く

このページでは、Chat アプリでダイアログを開く方法について説明します。 ユーザーに対応できます

ダイアログ: ウィンドウ形式のカードベースのインターフェース Chat スペースまたはメッセージから開くことができます。ダイアログとその 開いたユーザーだけが閲覧できます。

Chat アプリはダイアログを使用して、 Chat ユーザー(複数ステップのフォームを含む)。詳細情報 フォーム入力の作成について詳しくは、ユーザーから情報を収集して処理するをご覧ください。

<ph type="x-smartling-placeholder">

前提条件

Node.js

  • インタラクティブ機能を有効にする Google Chat アプリ。新しい HTTP サービスを使用したインタラクティブな Chat アプリについては、こちらのクイックスタートを完了します。

Python

  • インタラクティブ機能を有効にする Google Chat アプリ。新しい HTTP サービスを使用したインタラクティブな Chat アプリについては、こちらのクイックスタートを完了します。

Apps Script

  • インタラクティブ機能を有効にする Google Chat アプリ。新しい 対話型の Chat アプリを使用するには、このクイックスタートを完了します。

ダイアログを開く

<ph type="x-smartling-placeholder">
</ph> さまざまなウィジェットを表示するダイアログ。
図 1: 連絡先情報を収集するダイアログ

このセクションでは、応答方法とダイアログの設定方法について説明します。手順は次のとおりです。

  1. ユーザーの操作からダイアログ リクエストをトリガーします。
  2. ダイアログに戻って開き、リクエストを処理します。
  3. ユーザーが情報を送信したら、 別のダイアログを返すこともできます。

ダイアログ リクエストをトリガーする

Chat アプリでは、ユーザーに応答するためのダイアログのみを開くことができる (スラッシュ コマンドや、カード内のメッセージからのボタンのクリックなど)です。

ダイアログでユーザーに応答するには、Chat 用アプリで 次のようなダイアログ リクエストをトリガーするインタラクションを作成します。

  • スラッシュ コマンドに応答します。スラッシュ コマンドからリクエストをトリガーするには、 コマンドを構成するときに、[ダイアログを開く] チェックボックスをオンにする必要があります。
  • 特定のボタンのクリックに message、 カードの一部として表示するか、メッセージの下部に表示できます。トリガー メッセージ内のボタンからリクエストを送信したい場合は、 ボタンの onClick アクションの interactionOPEN_DIALOG に設定します。
  • Chat 用アプリのホームページでのボタンクリックに応答する。 ホームページからダイアログを開く方法については、 Google Chat 用アプリのホームページを作成します
で確認できます。 <ph type="x-smartling-placeholder">
</ph> ダイアログをトリガーするボタン
図 2: Chat アプリが、/addContact スラッシュ コマンドを使用するようにユーザーに促すメッセージを送信します。
このメッセージには、ユーザーがクリックするとコマンドをトリガーするボタンも含まれています。

次の JSON は、Google Chat のボタンでダイアログ リクエストを 表示されます。ダイアログを開くには、 button.interaction フィールドが OPEN_DIALOG に設定されている。

{
  "buttonList": { "buttons": [{
    "text": "BUTTON_TEXT",
    "onClick": { "action": {
      "function": "FUNCTION_NAME",
      "interaction": "OPEN_DIALOG"
    }}
  }]}
}

ここで、BUTTON_TEXT はボタンに表示されるテキストです。 FUNCTION_NAME は初期状態ファイルを開くために実行される クリックします。

最初のダイアログを開く

ユーザーがダイアログ リクエストをトリガーすると、Chat 用アプリは ユーザーが操作イベントを受信します。このイベントは event Chat API。操作によってダイアログ リクエストがトリガーされると、イベントの dialogEventType フィールドが REQUEST_DIALOG に設定されている。

ダイアログを開くには、Chat 用アプリが レスポンスを actionResponse typeDIALOG に設定されているオブジェクト。 Message 渡されます。ダイアログの内容を指定するには、以下を含めます。 オブジェクト:

  • actionResponse typeDIALOG に設定しています。
  • dialogAction オブジェクト。body フィールドには、以下の操作を行うためのユーザー インターフェース(UI)要素が含まれます。 このカードには、1 つまたは複数の ウィジェットの sections。 ユーザーから情報を収集するには、フォーム入力ウィジェットと クリックします。フォーム入力の設計について詳しくは、このモジュールの ユーザーから情報を収集して処理する

次の JSON は、Chat 用アプリが 次のようなレスポンスが返されます。

{ "actionResponse": {
  "type": "DIALOG",
  "dialogAction": { "dialog": { "body": { "sections": [{
    "widgets": [{
      WIDGETS,
      { "buttonList": { "buttons": [{
        "text": "BUTTON_TEXT",
        "onClick": {
          "action": {"function": "FUNCTION_NAME"}
        }
      }]}}
    }]
  }]}}}
}}

ここで、BUTTON_TEXT はボタンに表示されるテキスト( Next または Submit)、WIDGETS は 1 つ以上を表します。 フォーム入力ウィジェット FUNCTION_NAME は、ユーザーがボタンをクリックしたときに実行される関数です。

ダイアログの送信を処理する

ダイアログを送信するボタンをユーザーがクリックすると Chat アプリの受信内容 CARD_CLICKED インタラクション dialogEventType イベント SUBMIT_DIALOG です。

Chat アプリは、次の方法でインタラクション イベントを処理する必要があります。 次のいずれかを行います。

省略可: 別のダイアログを返す

ユーザーが最初のダイアログを送信すると、Chat アプリは ユーザーが事前に情報を確認できるように、1 つ以上の追加のダイアログを返す フォームへの入力、複数ステップのフォームへの入力、フォーム コンテンツを動的に入力できます。

ユーザーが最初のダイアログから入力したデータを読み込むには、 次のダイアログを開くボタンにパラメータを渡すか、元の値を 最初のダイアログの CARD_CLICKED インタラクション イベント。詳しくは、 データを別のカードに移行する

この例では、Chat 用アプリで は、送信前に 2 番目のダイアログを返します。入力データを読み込むには、 Chat アプリが CARD_CLICKED インタラクション イベントを渡す 次のダイアログを開く関数のパラメータとして渡します。

Node.js

// Respond to button clicks on attached cards
if (event.type === "CARD_CLICKED") {

  // Open the first dialog.
  if (event.common.invokedFunction === "openDialog") {
    openDialog(event);
  }

  // Open the second dialog.
  if (event.common.invokedFunction === "openNextDialog") {
    openNextDialog(event);
  }
}

/**
* Opens and starts a dialog that lets users add details about a contact.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openDialog(event) {
  res.json({ "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      { "buttonList": { "buttons": [{
        "text": "Next",
        "onClick": { "action": {
          "function": "openNextDialog"
        }}
      }]}}
    ]}]}}}
  }});
};

/**
* Opens a second dialog that lets users add more contact details.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openNextDialog(event) {
  res.json({ "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      {
        "horizontalAlignment": "END",
        "buttonList": { "buttons": [{
          "text": "Submit",
          "onClick": { "action": {
            "function": "submitDialog"
          }}
        }]}
      }
    ]}]}}}
  }});
}

Python

from typing import Any, Mapping

import flask
import functions_framework

@functions_framework.http
def main(req: flask.Request) -> Mapping[str, Any]:
  """Responds to a MESSAGE event in Google Chat that includes the /createContact
     slash command by opening a dialog.

  Args:
      req (flask.Request): the event object from Chat API.

  Returns:
      Mapping[str, Any]: open a Dialog in response to a card's button click.
  """

  if req.method == 'GET':
    return 'Sorry, this function must be called from a Google Chat.'

  request = req.get_json(silent=True)

  if request.get('type') == 'CARD_CLICKED':
    if invoked_function := request.get('common', dict()).get('invokedFunction'):
      if invoked_function == 'open_dialog':
        return open_dialog(request)

      elif invoked_function == 'open_next_dialog':
        return open_dialog(request)

def open_dialog(request: Mapping[str, Any]) -> Mapping[str, Any]:
  """Opens a dialog in Google Chat.

  Args:
      request (Mapping[str, Any]): the event object from Chat API.

  Returns:
      Mapping[str, Any]: open a Dialog in response to a card's button click.
  """
  return { "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      { "buttonList": { "buttons": [{
        "text": "Next",
        "onClick": { "action": {
          "function": "open_next_dialog"
        }}
      }]}}
    ]}]}}}
  }}

def open_next_dialog(request: Mapping[str, Any]) -> Mapping[str, Any]:
  """Opens a second dialog that lets users add more contact details.

  Args:
      request (Mapping[str, Any]): the event object from Chat API.

  Returns:
      Mapping[str, Any]: open a Dialog in response to a card's button click.
  """
  return { "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      {
        "horizontalAlignment": "END",
        "buttonList": { "buttons": [{
          "text": "Submit",
          "onClick": { "action": {
            "function": "submit_dialog"
          }}
        }]}
      }
    ]}]}}}
  }}

Apps Script

この例では、メッセージにカード メッセージを送信する際に、 カード JSON。 また、 Apps Script カードサービス

/**
* Responds to a CARD_CLICKED event in Google Chat.
*
* @param {Object} event the event object from Google Chat
*/
function onCardClick(event) {

  // When a user clicks a card, the Chat app checks to see which function to run.
  if (event.common.invokedFunction === "openDialog") {
    return openDialog(event);
  }

  if (event.common.invokedFunction === "openNextDialog") {
    return openNextDialog(event);
  }
}

/**
* Opens and starts a dialog that lets users add details about a contact.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openDialog(event) {
  return { "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      { "buttonList": { "buttons": [{
        "text": "Next",
        "onClick": { "action": {
          "function": "openNextDialog"
        }}
      }]}}
    ]}]}}}
  }};
}

/**
* Opens a second dialog that lets users add more contact details.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openNextDialog(event) {
  return { "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      {
        "horizontalAlignment": "END",
        "buttonList": { "buttons": [{
          "text": "Submit",
          "onClick": { "action": {
            "function": "submitDialog"
          }}
        }]}
      }
    ]}]}}}
  }};
}

ここで、WIDGETS は 1 つ以上を表します。 フォーム入力ウィジェット

ダイアログを閉じる

ユーザーがダイアログのボタンをクリックすると Chat アプリは、ユーザーとのインタラクション イベントを 次の情報を参照してください。

以降のセクションでは、ユーザーが入力および処理するデータを検証する方法について説明します。 ダイアログを閉じます

ユーザー入力データを検証してダイアログを閉じる

ユーザーが入力したデータを処理するため、Chat 用アプリは 使用 event.common.formInputs 渡されます。入力ウィジェットから値を取得する方法について詳しくは、以下をご覧ください。 ユーザーから情報を収集して処理する

ユーザーが必須フィールドを省略したり、正しくない値を入力したりすると、 Chat アプリは、メッセージを返すことにより、エラーで応答できます。 ActionResponse 含まれている"actionStatus": "ERROR MESSAGE"

次の例では、ユーザーがウィジェットに値を入力しているかどうかを 文字列(stringInputs)を受け入れます(textInput ウィジェットなど)。指定されていない場合、 Chat アプリからエラーが返されます。存在する場合 Chat アプリがダイアログの送信を確認し、 ダイアログが閉じます。

Node.js

/**
* Checks for a form input error, the absence of
* a "name" value, and returns an error if absent.
* Otherwise, confirms successful receipt of a dialog.
*
* Confirms successful receipt of a dialog.
*
* @param {Object} event the event object from Chat API.
*
* @return {Object} open a Dialog in Google Chat.
*/
function submitDialog(event) {

  // Checks to make sure the user entered a value
  // in a dialog. If no value detected, returns
  // an error message. Any "actionStatus" value other than "OK"
  // gets returned as an error.
  if (event.common.formInputs.WIDGET_NAME.stringInputs.value[0] === "") {
    res.json({
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "ERROR_MESSAGE"
        }
      }
    });

    // Otherwise the Chat app indicates that it received
    // form data from the dialog. An "actionStatus" of "OK" is
    // interpreted as code 200, and the dialog closes.
  } else {
    res.json({
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "OK"
        }
      }
    });
  }
}

Python

def receive_dialog(event: Mapping[str, Any]) -> Mapping[str, Any]:
  """Checks for a form input error, the absence of a "name" value, and returns
     an error if absent. Otherwise, confirms successful receipt of a dialog.

  Args:
      event (Mapping[str, Any]): the event object from Chat API.

  Returns:
      Mapping[str, Any]: the response.
  """

  if common := event.get('common'):
    if form_inputs := common.get('formInputs'):
      if contact_name := form_inputs.get('WIDGET_NAME'):
        if string_inputs := contact_name.get('stringInputs'):
          if name := string_inputs.get('value')[0]:
            return {
              'actionResponse': {
                'type': 'DIALOG',
                'dialogAction': {
                  'actionStatus': 'OK'
                }
              }
            }
          else:
            return {
              'actionResponse': {
                'type': 'DIALOG',
                'dialogAction': {
                  'actionStatus': 'ERROR_MESSAGE'
                }
              }
            }

Apps Script

この例では、メッセージにカード メッセージを送信する際に、 カード JSON。 また、 Apps Script カードサービス

/**
* Checks for a form input error, the absence of
* a "name" value, and returns an error if absent.
* Otherwise, confirms successful receipt of a dialog.
*
* Confirms successful receipt of a dialog.
*
* @param {Object} event the event object from Chat API.
*
* @return {object} open a Dialog in Google Chat.
*/
function submitDialog(event) {

  // Checks to make sure the user entered a value
  // in a dialog. If no value detected, returns
  // an error message. Any "actionStatus" value other than "OK"
  // gets returned as an error.
  if (event.common.formInputs.WIDGET_NAME[""].stringInputs.value[0] === "") {
    return {
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "ERROR_MESSAGE"
        }
      }
    };

    // Otherwise the Chat app indicates that it received
    // form data from the dialog. An "actionStatus" of "OK" is
    // interpreted as code 200, and the dialog closes.
  } else {
    return {
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "OK"
        }
      }
    };
  }
}

この例で、WIDGET_NAME は、リクエストの name フィールドを表します。 (contactName など)であり、ERROR_MESSAGE は、 エラー メッセージの内容(Don't forget to name your contact など)。 ウィジェットからの入力データの処理について詳しくは、以下をご覧ください。 インタラクティブなウィジェットからデータを受け取る

省略可: 確認メッセージを送信する

ダイアログを閉じると、新しいメッセージを送信したり、 必要があります

新しいメッセージを送信するには、 ActionResponse typeNEW_MESSAGE に設定されたオブジェクト。たとえば、ダイアログを閉じるには 次のテキスト メッセージを送信します。

  {
    "actionResponse": {
      "type": "NEW_MESSAGE",
    },
    "text": "Your information has been submitted."
  }

メッセージを更新するには、次を含む actionResponse オブジェクトを返します。 メッセージを更新し、type を次のいずれかに設定します。

トラブルシューティング

Google Chat アプリまたは card がエラーを返した場合、 Chat のインターフェースに「エラーが発生しました」というメッセージが表示されている。 または「リクエストを処理できません」が表示されます。場合によっては、Chat の UI が エラー メッセージは表示されませんが、Chat 用アプリまたは 予期しない結果が生じた場合たとえば、カード メッセージに 表示されます。

Chat UI にエラー メッセージが表示されない場合がありますが、 エラーの修正に役立つ、わかりやすいエラー メッセージとログデータ Chat 用アプリのエラーロギングが有効になっている場合。表示のヘルプについては、 エラーの修正について詳しくは、このモジュールの Google Chat のエラーのトラブルシューティングと修正