インタラクティブなカードまたはダイアログを設計する

このページでは、ユーザーがボタンのクリックや情報の送信など、Google Chat アプリを操作できるように、ウィジェットと UI 要素をカードやダイアログ メッセージに追加する方法について説明します。


カードビルダーを使用して、Chat 用アプリ用の JSON カード メッセージを設計し、プレビューします。

カードビルダーを開きます

前提条件

  • Google Chat へのアクセス権を持つ Google Workspace アカウント
  • 公開された Chat アプリ。Chat アプリを作成するには、このquickstartに沿って操作してください。
  • ボタンを追加する

    ButtonList ウィジェットには一連のボタンが表示されます。ボタンには、テキスト、アイコン、またはテキストとアイコンの両方を表示できます。各 Button は、ユーザーがボタンをクリックしたときに発生する OnClick アクションをサポートしています。次に例を示します。

    • OpenLink でハイパーリンクを開き、ユーザーに追加情報を提供します。
    • API の呼び出しなどのカスタム関数を実行する action を実行します。

    ユーザー補助機能については、ボタンで代替テキストがサポートされています。

    カスタム関数を実行するボタンを追加する

    以下は、2 つのボタンを持つ ButtonList ウィジェットで構成されるカードです。1 つのボタンを選択すると、Google Chat デベロッパー向けドキュメントが新しいタブで開きます。もう 1 つのボタンは、goToView() というカスタム関数を実行し、viewType="BIRD EYE VIEW" パラメータを渡します。

    カスタム色のボタンと無効なボタンを追加する

    "disabled": "true" を設定すると、ユーザーがボタンをクリックできないようにすることができます。

    以下は、2 つのボタンを持つ ButtonList ウィジェットで構成されるカードの例です。1 つのボタンは、Color フィールドを使用してボタンの背景色をカスタマイズします。他のボタンは Disabled フィールドで無効になります。これにより、ユーザーはボタンをクリックして機能を実行できなくなります。

    アイコン付きのボタンを追加する

    以下は、2 つのアイコン Button ウィジェットを持つ ButtonList ウィジェットで構成されるカードの例です。1 つのボタンは、knownIcon フィールドを使用して Google Chat の組み込みメールアイコンを表示します。もう 1 つのボタンは、iconUrl フィールドを使用してカスタム アイコン ウィジェットを表示します。

    アイコンとテキスト付きのボタンを追加する

    以下では、ユーザーにメールを送信するよう促す ButtonList ウィジェットで構成されるカードを表示します。最初のボタンにはメールアイコン、2 番目のボタンにはテキストが表示されます。ユーザーはアイコンまたはテキストボタンをクリックして、sendEmail 関数を実行できます。

    選択可能な UI 要素を追加する

    SelectionInput ウィジェットには、チェックボックス、ラジオボタン、スイッチ、プルダウン メニューなど、選択可能なアイテムのセットが用意されています。このウィジェットを使用すると、定義済みで標準化されたデータをユーザーから収集できます。ユーザーから未定義のデータを収集するには、代わりに TextInput ウィジェットを使用します。

    SelectionInput ウィジェットは、ユーザーが均一なデータを入力するのに役立つ候補と、変更時のアクション(ユーザーによるアイテムの選択や選択解除など、選択入力フィールドに変更が発生したときに実行される Actions)をサポートしています。

    Chat アプリは、選択されたアイテムの値を受け取って処理できます。フォーム入力の操作について詳しくは、フォームデータを受信するをご覧ください。

    このセクションでは、SelectionInput ウィジェットを使用するカードの例を示します。この例では、さまざまな種類のセクション入力を使用します。

    チェックボックスを追加する

    次のコードは、チェックボックスを使用する SelectionInput ウィジェットで、連絡先が仕事、個人、またはその両方のいずれであるかを指定するダイアログを表示します。

    ラジオボタンを追加する

    以下の例では、ラジオボタンを使用する SelectionInput ウィジェットを使用して、連絡先が仕事用か個人用かを指定するようユーザーに求めるダイアログが表示されています。

    スイッチを追加する

    次のダイアログが表示され、ユーザーはスイッチを使用する SelectionInput ウィジェットを使用して、連絡先が仕事用か個人用か、またはその両方かを指定するよう求めることができます。

    以下に示すのは、プルダウン メニューを使用する SelectionInput ウィジェットで、連絡先が仕事用か個人用かを指定するようユーザーに求めるダイアログです。

    複数選択メニューを追加する

    次のようにすると、複数選択メニューから連絡先を選択するようユーザーに求めるダイアログが表示されます。

    複数選択メニューにデータソースを使用する

    次のセクションでは、複数選択メニューを使用して、Google Workspace アプリケーションや外部データソースなどの動的ソースからデータを取得する方法について説明します。

    Google Workspace のデータソース

    Google Workspace では、次のデータソースから複数選択メニューの項目を入力できます。

    • Google Workspace ユーザー: 同じ Google Workspace 組織内のユーザーにのみ入力できます。
    • Chat スペース: 複数選択メニューの項目を入力すると、Google Workspace 組織内で自分が属しているスペースのみを表示および選択できます。

    Google Workspace データソースを使用するには、platformDataSource フィールドを指定します。他の選択入力タイプとは異なり、SectionItem オブジェクトは省略します。これらの選択項目は Google Workspace から動的に取得されるためです。

    次のコードは、Google Workspace ユーザーの複数選択メニューを示しています。ユーザーを入力するには、選択入力で commonDataSourceUSER に設定します。

    JSON

    {
      "selectionInput": {
        "name": "contacts",
        "type": "MULTI_SELECT",
        "label": "Selected contacts",
        "multiSelectMaxSelectedItems": 5,
        "multiSelectMinQueryLength": 1,
        "platformDataSource": {
          "commonDataSource": "USER"
        }
      }
    }
    

    次のコードは、Chat スペースの複数選択メニューを示しています。スペースを入力するには、選択入力で hostAppDataSource フィールドを指定します。また、複数選択メニューでは defaultToCurrentSpacetrue に設定されるため、現在のスペースがメニューのデフォルト選択になります。

    JSON

    {
      "selectionInput": {
        "name": "spaces",
        "type": "MULTI_SELECT",
        "label": "Selected contacts",
        "multiSelectMaxSelectedItems": 3,
        "multiSelectMinQueryLength": 1,
        "platformDataSource": {
          "hostAppDataSource": {
            "chatDataSource": {
              "spaceDataSource": {
                "defaultToCurrentSpace": true
              }
            }
          }
        }
      }
    }
    
    Google Workspace の外部にあるデータソース

    複数選択メニューには、サードパーティまたは外部のデータソースからアイテムを入力することもできます。たとえば、複数選択メニューを使用すると、顧客管理(CRM)システムの見込み顧客のリストからユーザーが選択できるようになります。

    外部データソースを使用するには、externalDataSource フィールドを使用して、データソースからアイテムを返す関数を指定します。

    外部データソースへのリクエストを減らすには、ユーザーがメニューを入力する前に複数選択メニューに表示される候補アイテムを含めることができます。たとえば、そのユーザーの最近検索した連絡先を入力できます。外部データソースから候補アイテムを入力するには、SelectionItem オブジェクトを指定します。

    次のコードは、ユーザーの外部の連絡先セットからのアイテムの複数選択メニューを示しています。デフォルトでは、メニューには 1 つの連絡先が表示され、getContacts 関数を実行して外部データソースから項目を取得して、データを入力します。

    JSON

    {
      "selectionInput": {
        "name": "contacts",
        "type": "MULTI_SELECT",
        "label": "Selected contacts",
        "multiSelectMaxSelectedItems": 5,
        "multiSelectMinQueryLength": 2,
        "externalDataSource": {
          "function": "getContacts"
        },
        "items": [
          {
            "text": "Contact 3",
            "value": "contact-3",
            "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
            "bottomText": "Contact three description",
            "selected": false
          }
        ]
      }
    }
    

    外部データソースの場合、ユーザーが複数選択メニューで入力を開始する項目を予測入力することもできます。たとえば、ユーザーが米国の都市を入力するメニューに対して Atl の入力を開始すると、ユーザーが入力を終える前に、Chat アプリは Atlanta を自動提案できます。最大 100 個のアイテムを予測入力できます。

    予測入力項目を作成するには、外部データソースに対してクエリを実行し、ユーザーが複数選択メニューに入力するたびに項目を返す関数を作成します。この関数は、次のことを行う必要があります。

    • ユーザーによるメニュー操作を表すイベント オブジェクトを渡します。
    • インタラクション イベントの invokedFunction 値が externalDataSource フィールドの関数と一致することを確認します。
    • 関数が一致すると、外部データソースから候補アイテムを返します。ユーザーの入力内容に基づいてアイテムを提案するには、autocomplete_widget_query キーの値を取得します。この値は、ユーザーがメニューに入力した内容を表します。

    次のコードでは、外部データリソースのアイテムが予測入力されます。上記の例を使用すると、Chat アプリは、getContacts 関数がトリガーされたタイミングに基づいてアイテムを提案します。

    Apps Script

    apps-script/selection-input/on-widget-update.gs
    /**
     * Widget update event handler.
     *
     * @param {Object} event The event object from Chat API.
     * @return {Object} Response from the Chat app.
     */
    function onWidgetUpdate(event) {
      const actionName = event.common["invokedFunction"];
      if (actionName !== "getContacts") {
        return {};
      }
    
      return {
        actionResponse: {
          type: "UPDATE_WIDGET",
          updatedWidget: {
            suggestions: {
              items: [
                {
                  value: "contact-1",
                  startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                  text: "Contact 1",
                  bottomText: "Contact one description",
                  selected: false
                },
                {
                  value: "contact-2",
                  startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                  text: "Contact 2",
                  bottomText: "Contact two description",
                  selected: false
                },
                {
                  value: "contact-3",
                  startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                  text: "Contact 3",
                  bottomText: "Contact three description",
                  selected: false
                },
                {
                  value: "contact-4",
                  startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                  text: "Contact 4",
                  bottomText: "Contact four description",
                  selected: false
                },
                {
                  value: "contact-5",
                  startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                  text: "Contact 5",
                  bottomText: "Contact five description",
                  selected: false
                },
              ]
            }
          }
        }
      };
    }
    

    Node.js

    node/selection-input/on-widget-update.js
    /**
     * Widget update event handler.
     *
     * @param {Object} event The event object from Chat API.
     * @return {Object} Response from the Chat app.
     */
    function onWidgetUpdate(event) {
      const actionName = event.common["invokedFunction"];
      if (actionName !== "getContacts") {
        return {};
      }
    
      return {
        actionResponse: {
          type: "UPDATE_WIDGET",
          updatedWidget: {
            suggestions: {
              items: [
                {
                  value: "contact-1",
                  startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                  text: "Contact 1",
                  bottomText: "Contact one description",
                  selected: false
                },
                {
                  value: "contact-2",
                  startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                  text: "Contact 2",
                  bottomText: "Contact two description",
                  selected: false
                },
                {
                  value: "contact-3",
                  startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                  text: "Contact 3",
                  bottomText: "Contact three description",
                  selected: false
                },
                {
                  value: "contact-4",
                  startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                  text: "Contact 4",
                  bottomText: "Contact four description",
                  selected: false
                },
                {
                  value: "contact-5",
                  startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                  text: "Contact 5",
                  bottomText: "Contact five description",
                  selected: false
                },
              ]
            }
          }
        }
      };
    }
    

    ユーザーがテキストを入力できるフィールドを追加します

    TextInput ウィジェットには、ユーザーがテキストを入力できるフィールドがあります。このウィジェットは、ユーザーが均一なデータを入力するのに役立つ提案と、テキスト入力フィールドで変更(テキストの追加や削除など)が発生したときに実行される Actions である変更時のアクションをサポートしています。

    抽象的なデータや未知のデータをユーザーから収集する必要がある場合は、この TextInput ウィジェットを使用します。ユーザーから定義済みのデータを収集するには、代わりに SelectionInput ウィジェットを使用します。

    ユーザーが入力したテキストを処理するには、フォームデータを受信するをご覧ください。

    以下は、TextInput ウィジェットで構成されるカードです。

    ユーザーが日時を選択できるようにする

    DateTimePicker ウィジェットを使用すると、ユーザーは日付、時刻、またはその両方を入力できます。または、選択ツールを使用して日付と時刻を選択することもできます。ユーザーが無効な日時を入力すると、選択ツールにエラーが表示され、情報を正しく入力するよう求められます。

    ユーザーが入力した日付と時刻の値を処理するには、フォームデータを受信するをご覧ください。

    次のコードは、3 種類の DateTimePicker ウィジェットで構成されるカードを表示します。

    カードに入力されたデータを検証する

    このページでは、カードの action とウィジェットに入力されたデータを検証する方法について説明します。たとえば、テキスト入力フィールドにユーザーが入力したテキストや、特定の文字数が含まれていることを検証できます。

    アクションに必要なウィジェットを設定する

    カードの action の一部として、アクションに必要なウィジェットの名前を requiredWidgets リストに追加します。

    ここにリストされているいずれかのウィジェットに、このアクションが呼び出されたときに値がない場合、フォーム アクションの送信はキャンセルされます。

    アクションに "all_widgets_are_required": "true" が設定されている場合、カード内のすべてのウィジェットがこのアクションで必要になります。

    複数選択での all_widgets_are_required アクションの設定

    JSON

    {
      "sections": [
        {
          "header": "Select contacts",
          "widgets": [
            {
              "selectionInput": {
                "type": "MULTI_SELECT",
                "label": "Selected contacts",
                "name": "contacts",
                "multiSelectMaxSelectedItems": 3,
                "multiSelectMinQueryLength": 1,
                "onChangeAction": {
                  "all_widgets_are_required": true
                },
                "items": [
                  {
                    "value": "contact-1",
                    "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                    "text": "Contact 1",
                    "bottomText": "Contact one description",
                    "selected": false
                  },
                  {
                    "value": "contact-2",
                    "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                    "text": "Contact 2",
                    "bottomText": "Contact two description",
                    "selected": false
                  },
                  {
                    "value": "contact-3",
                    "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                    "text": "Contact 3",
                    "bottomText": "Contact three description",
                    "selected": false
                  },
                  {
                    "value": "contact-4",
                    "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                    "text": "Contact 4",
                    "bottomText": "Contact four description",
                    "selected": false
                  },
                  {
                    "value": "contact-5",
                    "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                    "text": "Contact 5",
                    "bottomText": "Contact five description",
                    "selected": false
                  }
                ]
              }
            }
          ]
        }
      ]
    }
    

    dateTimePicker で all_widgets_are_required アクションを設定する

    JSON

    {
      "sections": [
        {
          "widgets": [
            {
              "textParagraph": {
                "text": "A datetime picker widget with both date and time:"
              }
            },
            {
              "divider": {}
            },
            {
              "dateTimePicker": {
                "name": "date_time_picker_date_and_time",
                "label": "meeting",
                "type": "DATE_AND_TIME"
              }
            },
            {
              "textParagraph": {
                "text": "A datetime picker widget with just date:"
              }
            },
            {
              "divider": {}
            },
            {
              "dateTimePicker": {
                "name": "date_time_picker_date_only",
                "label": "Choose a date",
                "type": "DATE_ONLY",
                "onChangeAction":{
                  "all_widgets_are_required": true
                }
              }
            },
            {
              "textParagraph": {
                "text": "A datetime picker widget with just time:"
              }
            },
            {
              "divider": {}
            },
            {
              "dateTimePicker": {
                "name": "date_time_picker_time_only",
                "label": "Select a time",
                "type": "TIME_ONLY"
              }
            }
          ]
        }
      ]
    }
    

    プルダウン メニューで all_widgets_are_required アクションを設定する

    JSON

    {
      "sections": [
        {
          "header": "Section Header",
          "collapsible": true,
          "uncollapsibleWidgetsCount": 1,
          "widgets": [
            {
              "selectionInput": {
                "name": "location",
                "label": "Select Color",
                "type": "DROPDOWN",
                "onChangeAction": {
                  "all_widgets_are_required": true
                },
                "items": [
                  {
                    "text": "Red",
                    "value": "red",
                    "selected": false
                  },
                  {
                    "text": "Green",
                    "value": "green",
                    "selected": false
                  },
                  {
                    "text": "White",
                    "value": "white",
                    "selected": false
                  },
                  {
                    "text": "Blue",
                    "value": "blue",
                    "selected": false
                  },
                  {
                    "text": "Black",
                    "value": "black",
                    "selected": false
                  }
                ]
              }
            }
          ]
        }
      ]
    }
    

    テキスト入力ウィジェットの検証を設定する

    textInput ウィジェットの検証フィールドでは、このテキスト入力ウィジェットの文字数制限と入力タイプを指定できます。

    テキスト入力ウィジェットの文字数制限を設定する

    JSON

    {
      "sections": [
        {
          "header": "Tell us about yourself",
          "collapsible": true,
          "uncollapsibleWidgetsCount": 2,
          "widgets": [
            {
              "textInput": {
                "name": "favoriteColor",
                "label": "Favorite color",
                "type": "SINGLE_LINE",
                "validation": {"character_limit":15},
                "onChangeAction":{
                  "all_widgets_are_required": true
                }
              }
            }
          ]
        }
      ]
    }
    

    テキスト入力ウィジェットの入力タイプを設定する

    JSON

    {
      "sections": [
        {
          "header": "Validate text inputs by input types",
          "collapsible": true,
          "uncollapsibleWidgetsCount": 2,
          "widgets": [
            {
              "textInput": {
                "name": "mailing_address",
                "label": "Please enter a valid email address",
                "type": "SINGLE_LINE",
                "validation": {
                  "input_type": "EMAIL"
                },
                "onChangeAction": {
                  "all_widgets_are_required": true
                }
              }
            },
            {
              "textInput": {
                "name": "validate_integer",
                "label": "Please enter a number",
                  "type": "SINGLE_LINE",
                "validation": {
                  "input_type": "INTEGER"
                }
              }
            },
            {
              "textInput": {
                "name": "validate_float",
                "label": "Please enter a number with a decimal",
                "type": "SINGLE_LINE",
                "validation": {
                  "input_type": "FLOAT"
                }
              }
            }
          ]
        }
      ]
    }
    

    トラブルシューティング

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

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