Google Chat ユーザーから情報を収集して処理する

このガイドでは、Google Chat 用アプリがカードベースのインターフェースでフォーム入力を構築して、ユーザーから情報を収集して処理する方法について説明します。

さまざまなウィジェットが表示されたダイアログ。
図 1: 連絡先情報を収集するダイアログを開くサンプル Chat 用アプリ

Chat 用アプリは、Chat 内外でアクションを実行するために、次のような方法でユーザーに情報をリクエストします。

  • 設定を行います。たとえば、ユーザーが通知設定をカスタマイズしたり、Chat 用アプリを 1 つ以上のスペースに構成して追加したりできるようにします。
  • 他の Google Workspace アプリケーションで情報を作成または更新します。たとえば、ユーザーが Google カレンダーの予定を作成できるようにします。
  • 他のアプリやウェブ サービスのリソースにアクセスして更新できるようにします。たとえば、Chat アプリを使用すると、Chat スペースから直接サポート チケットのステータスを更新できます。

前提条件

Node.js

インタラクション イベントを受信して応答する Google Chat 用アプリ。HTTP サービスを使用してインタラクティブな Chat 用アプリを作成するには、このクイックスタートを完了してください。

Python

インタラクション イベントを受信して応答する Google Chat 用アプリ。HTTP サービスを使用してインタラクティブな Chat 用アプリを作成するには、このクイックスタートを完了してください。

Java

インタラクション イベントを受信して応答する Google Chat 用アプリ。HTTP サービスを使用してインタラクティブな Chat 用アプリを作成するには、このクイックスタートを完了してください。

Apps Script

インタラクション イベントを受信して応答する Google Chat 用アプリ。Apps Script で双方向の Chat 用アプリを作成するには、このクイック スタートを完了してください。

カードを使用してフォームを作成する

情報を収集するために、Chat 用アプリはフォームとその入力を設計し、カードに組み込みます。ユーザーにカードを表示するために、Chat 用アプリは次の Chat インターフェースを使用できます。

  • 1 つ以上のカードを含むメッセージ
  • ホームページ。Chat 用アプリとのダイレクト メッセージの [ホーム] タブに表示されるカードです。
  • ダイアログ: メッセージやホームページから新しいウィンドウで開くカード。

Chat 用アプリは、次のウィジェットを使用してカードを構築できます。

  • ユーザーに情報をリクエストするフォーム入力ウィジェット。必要に応じて、フォーム入力ウィジェットに検証を追加して、ユーザーが情報を正しく入力してフォーマットできるようにすることができます。Chat 用アプリでは、次のフォーム入力ウィジェットを使用できます。

    • 自由形式または候補のテキスト用のテキスト入力textInput)。
    • 選択入力selectionInput)は、チェックボックス、ラジオボタン、プルダウン メニューなどの選択可能な UI 要素です。選択入力ウィジェットでは、静的または動的なデータソースから項目を入力することもできます。たとえば、ユーザーはメンバーになっている Chat スペースの一覧から選択できます。
    • 日付と時刻のエントリ用の日時ピッカーdateTimePicker)。
  • ユーザーがカードに入力した値を送信できるようにする button ウィジェット。ユーザーがボタンをクリックすると、Chat 用アプリは受信した情報を処理できます。

次の例では、カードがテキスト入力、日時選択ツール、選択入力を使用して連絡先情報を収集しています。

このお問い合わせフォームを使用する Chat 用アプリの例については、次のコードをご覧ください。

Node.js

node/contact-form-app/index.js
/**
 * The section of the contact card that contains the form input widgets. Used in a dialog and card message.
 * To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
 */
const CONTACT_FORM_WIDGETS = [
  {
    "textInput": {
      "name": "contactName",
      "label": "First and last name",
      "type": "SINGLE_LINE"
    }
  },
  {
    "dateTimePicker": {
      "name": "contactBirthdate",
      "label": "Birthdate",
      "type": "DATE_ONLY"
    }
  },
  {
    "selectionInput": {
      "name": "contactType",
      "label": "Contact type",
      "type": "RADIO_BUTTON",
      "items": [
        {
          "text": "Work",
          "value": "Work",
          "selected": false
        },
        {
          "text": "Personal",
          "value": "Personal",
          "selected": false
        }
      ]
    }
  }
];

Python

python/contact-form-app/main.py
# The section of the contact card that contains the form input widgets. Used in a dialog and card message.
# To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
CONTACT_FORM_WIDGETS = [
  {
    "textInput": {
      "name": "contactName",
      "label": "First and last name",
      "type": "SINGLE_LINE"
    }
  },
  {
    "dateTimePicker": {
      "name": "contactBirthdate",
      "label": "Birthdate",
      "type": "DATE_ONLY"
    }
  },
  {
    "selectionInput": {
      "name": "contactType",
      "label": "Contact type",
      "type": "RADIO_BUTTON",
      "items": [
        {
          "text": "Work",
          "value": "Work",
          "selected": False
        },
        {
          "text": "Personal",
          "value": "Personal",
          "selected": False
        }
      ]
    }
  }
]

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
// The section of the contact card that contains the form input widgets. Used in a dialog and card message.
// To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
final static private List<GoogleAppsCardV1Widget> CONTACT_FORM_WIDGETS = List.of(
  new GoogleAppsCardV1Widget().setTextInput(new GoogleAppsCardV1TextInput()
    .setName("contactName")
    .setLabel("First and last name")
    .setType("SINGLE_LINE")),
  new GoogleAppsCardV1Widget().setDateTimePicker(new GoogleAppsCardV1DateTimePicker()
    .setName("contactBirthdate")
    .setLabel("Birthdate")
    .setType("DATE_ONLY")),
  new GoogleAppsCardV1Widget().setSelectionInput(new GoogleAppsCardV1SelectionInput()
    .setName("contactType")
    .setLabel("Contact type")
    .setType("RADIO_BUTTON")
    .setItems(List.of(
      new GoogleAppsCardV1SelectionItem()
        .setText("Work")
        .setValue("Work")
        .setSelected(false),
      new GoogleAppsCardV1SelectionItem()
        .setText("Personal")
        .setValue("Personal")
        .setSelected(false)))));

Apps Script

apps-script/contact-form-app/contactForm.gs
/**
 * The section of the contact card that contains the form input widgets. Used in a dialog and card message.
 * To add and preview widgets, use the Card Builder: https://addons.gsuite.google.com/uikit/builder
 */
const CONTACT_FORM_WIDGETS = [
  {
    "textInput": {
      "name": "contactName",
      "label": "First and last name",
      "type": "SINGLE_LINE"
    }
  },
  {
    "dateTimePicker": {
      "name": "contactBirthdate",
      "label": "Birthdate",
      "type": "DATE_ONLY"
    }
  },
  {
    "selectionInput": {
      "name": "contactType",
      "label": "Contact type",
      "type": "RADIO_BUTTON",
      "items": [
        {
          "text": "Work",
          "value": "Work",
          "selected": false
        },
        {
          "text": "Personal",
          "value": "Personal",
          "selected": false
        }
      ]
    }
  }
];

情報を収集するために使用できるインタラクティブ ウィジェットの例については、インタラクティブなカードやダイアログの設計をご覧ください。

インタラクティブ ウィジェットからデータを受け取る

ユーザーがボタンをクリックすると、Chat 用アプリはボタンの場所に応じてインタラクション イベントを受け取ります。

  • ボタンがメッセージまたはダイアログにある場合、Chat 用アプリは、インタラクションに関する情報を含む CARD_CLICKED インタラクション イベントを受け取ります。CARD_CLICKED インタラクション イベントのペイロードには、ユーザーが入力した値を含む common.formInputs オブジェクトが含まれます。

    オブジェクト common.formInputs.WIDGET_NAME から値を取得できます。ここで、WIDGET_NAME はウィジェットに指定した name フィールドです。値は、ウィジェットの特定のデータ型(Inputs オブジェクトとして表される)として返されます。

    次の例は、ユーザーが各ウィジェットに値を入力した CARD_CLICKED インタラクション イベントの一部を示しています。

    HTTP

    {
      "type": "CARD_CLICKED",
      "common": { "formInputs": {
        "contactName": { "stringInputs": {
          "value": ["Kai 0"]
        }},
        "contactBirthdate": { "dateInput": {
          "msSinceEpoch": 1000425600000
        }},
        "contactType": { "stringInputs": {
          "value": ["Personal"]
        }}
      }}
    }
    

    Apps Script

    {
      "type": "CARD_CLICKED",
      "common": { "formInputs": {
        "contactName": { "": { "stringInputs": {
          "value": ["Kai 0"]
        }}},
        "contactBirthdate": { "": { "dateInput": {
          "msSinceEpoch": 1000425600000
        }}},
          "contactType": { "": { "stringInputs": {
          "value": ["Personal"]
        }}}
      }}
    }
    
  • ボタンがホームページにある場合、Chat 用アプリは SUBMIT_FORM インタラクション イベントを受け取ります。インタラクション イベントのペイロードには、ユーザーが入力した値を含む commonEventObject.formInputs オブジェクトが含まれます。

    オブジェクト commonEventObject.formInputs.WIDGET_NAME から値を取得できます。ここで、WIDGET_NAME はウィジェットに指定した name フィールドです。値は、ウィジェットの特定のデータ型(Inputs オブジェクトとして表される)として返されます。

    次の例は、ユーザーが各ウィジェットに値を入力した SUBMIT_FORM インタラクション イベントの一部を示しています。

    HTTP

    {
      "type": "SUBMIT_FORM",
      "commonEventObject": { "formInputs": {
        "contactName": { "stringInputs": {
          "value": ["Kai 0"]
        }},
        "contactBirthdate": { "dateInput": {
          "msSinceEpoch": 1000425600000
        }},
        "contactType": { "stringInputs": {
          "value": ["Personal"]
        }}
      }}
    }
    

    Apps Script

    {
      "type": "SUBMIT_FORM",
      "commonEventObject": { "formInputs": {
        "contactName": { "": { "stringInputs": {
          "value": ["Kai 0"]
        }}},
        "contactBirthdate": { "": { "dateInput": {
          "msSinceEpoch": 1000425600000
        }}},
          "contactType": { "": { "stringInputs": {
          "value": ["Personal"]
        }}}
      }}
    }
    

データを受信するには、Chat 用アプリでインタラクション イベントを処理して、ユーザーがウィジェットに入力した値を取得します。次の表は、特定のフォーム入力ウィジェットの値を取得する方法を示しています。各ウィジェットについて、ウィジェットが受け入れるデータ型、値が保存されるインタラクション イベント、値の例が表に示されます。

フォーム入力ウィジェット 入力データのタイプ インタラクション イベントからの入力値 値の例
textInput stringInputs event.common.formInputs.contactName.stringInputs.value[0] Kai O
selectionInput stringInputs 最初または唯一の値を取得するには、event.common.formInputs.contactType.stringInputs.value[0] Personal
日付のみを受け付ける dateTimePicker dateInput event.common.formInputs.contactBirthdate.dateInput.msSinceEpoch 1000425600000

別のカードにデータを転送する

ユーザーがカードから情報を送信した後、次のいずれかを行うために追加のカードを返す必要がある場合があります。

  • 長いフォームを複数のセクションに分割して、ユーザーが入力しやすくします。
  • ユーザーが最初のカードの情報をプレビューして確認できるようにします。これにより、ユーザーは回答を送信する前に確認できます。
  • フォームの残りの部分を動的に入力します。たとえば、ユーザーに予定の作成を促すために、Chat 用アプリは、予定の理由を尋ねる最初のカードを表示し、予定の種類に基づいて利用可能な時間を表示する別のカードに入力します。

最初のカードから入力されたデータを転送するには、次の例に示すように、ウィジェットの name とユーザーが入力した値を含む actionParameters を使用して button ウィジェットをビルドします。

Node.js

node/contact-form-app/index.js
buttonList: { buttons: [{
  text: "Submit",
  onClick: { action: {
    function: "submitForm",
    parameters: [{
      key: "contactName", value: name }, {
      key: "contactBirthdate", value: birthdate }, {
      key: "contactType", value: type
    }]
  }}
}]}

Python

python/contact-form-app/main.py
'buttonList': { 'buttons': [{
  'text': "Submit",
  'onClick': { 'action': {
    'function': "submitForm",
    'parameters': [{
      'key': "contactName", 'value': name }, {
      'key': "contactBirthdate", 'value': birthdate }, {
      'key': "contactType", 'value': type
    }]
  }}
}]}

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
new GoogleAppsCardV1Widget().setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(new GoogleAppsCardV1Button()
  .setText("Submit")
  .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
    .setFunction("submitForm")
    .setParameters(List.of(
      new GoogleAppsCardV1ActionParameter().setKey("contactName").setValue(name),
      new GoogleAppsCardV1ActionParameter().setKey("contactBirthdate").setValue(birthdate),
      new GoogleAppsCardV1ActionParameter().setKey("contactType").setValue(type))))))))));

Apps Script

apps-script/contact-form-app/main.gs
buttonList: { buttons: [{
  text: "Submit",
  onClick: { action: {
    function: "submitForm",
    parameters: [{
      key: "contactName", value: name }, {
      key: "contactBirthdate", value: birthdate }, {
      key: "contactType", value: type
    }]
  }}
}]}

ユーザーがボタンをクリックすると、Chat 用アプリは CARD_CLICKED インタラクション イベントを受信します。このイベントからデータを受信できます。

フォームの送信に対応する

カード メッセージまたはダイアログからデータを受信すると、Chat 用アプリは受信を確認するか、エラーを返して応答します。

次の例では、Chat 用アプリがテキスト メッセージを送信して、ダイアログまたはカード メッセージから送信されたフォームを正常に受信したことを確認しています。

Node.js

node/contact-form-app/index.js
const contactName = event.common.parameters["contactName"];
// Checks to make sure the user entered a contact name.
// If no name value detected, returns an error message.
const errorMessage = "Don't forget to name your new contact!";
if (!contactName && event.dialogEventType === "SUBMIT_DIALOG") {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { actionStatus: {
      statusCode: "INVALID_ARGUMENT",
      userFacingMessage: errorMessage
    }}
  }};
}

Python

python/contact-form-app/main.py
contact_name = event.get('common').get('parameters')["contactName"]
# Checks to make sure the user entered a contact name.
# If no name value detected, returns an error message.
error_message = "Don't forget to name your new contact!"
if contact_name == "" and "SUBMIT_DIALOG" == event.get('dialogEventType'):
  return { 'actionResponse': {
    'type': "DIALOG",
    'dialogAction': { 'actionStatus': {
      'statusCode': "INVALID_ARGUMENT",
      'userFacingMessage': error_message
    }}
  }}

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
String contactName = event.at("/common/parameters/contactName").asText();
// Checks to make sure the user entered a contact name.
// If no name value detected, returns an error message.
String errorMessage = "Don't forget to name your new contact!";
if (contactName.isEmpty() && event.at("/dialogEventType") != null && "SUBMIT_DIALOG".equals(event.at("/dialogEventType").asText())) {
  return new Message().setActionResponse(new ActionResponse()
    .setType("DIALOG")
    .setDialogAction(new DialogAction().setActionStatus(new ActionStatus()
      .setStatusCode("INVALID_ARGUMENT")
      .setUserFacingMessage(errorMessage))));
}

Apps Script

apps-script/contact-form-app/main.gs
const contactName = event.common.parameters["contactName"];
// Checks to make sure the user entered a contact name.
// If no name value detected, returns an error message.
const errorMessage = "Don't forget to name your new contact!";
if (!contactName && event.dialogEventType === "SUBMIT_DIALOG") {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { actionStatus: {
      statusCode: "INVALID_ARGUMENT",
      userFacingMessage: errorMessage
    }}
  }};
}

ダイアログを処理して閉じるには、確認メッセージを送信するか、元のメッセージまたはカードを更新するか、ダイアログを閉じるだけかを指定する ActionResponse オブジェクトを返します。手順については、ダイアログを閉じるをご覧ください。

トラブルシューティング

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

Chat UI にエラー メッセージが表示されない場合でも、Chat 用アプリのエラー ロギングが有効になっている場合は、エラーの修正に役立つ説明的なエラー メッセージとログデータを利用できます。エラーの表示、デバッグ、修正については、Google Chat のエラーのトラブルシューティングと修正をご覧ください。