收集並處理 Google Chat 使用者的資訊

本指南說明 Google Chat 應用程式如何在以卡片為基礎的介面中建立表單輸入內容,以便收集及處理使用者提供的資訊。

對話方塊內含各種不同的小工具。
圖 1Chat 範例應用程式,用於開啟收集聯絡資訊的對話方塊。

Chat 應用程式會向使用者索取資訊,以便在 Chat 中或在 Chat 之外執行動作,包括以下方式:

  • 調整設定。例如,讓使用者自訂通知設定,或將 Chat 應用程式新增至一或多個聊天室。
  • 在其他 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 介面:

  • 含有一或多張資訊卡的訊息
  • 首頁:這是在 Chat 應用程式即時訊息的「首頁」分頁中顯示的資訊卡。
  • 對話方塊:在訊息和首頁中開啟新視窗的資訊卡。

Chat 應用程式可以使用下列小工具建立資訊卡:

  • 可要求使用者提供資訊的表單輸入小工具。您可以視需要在表單輸入小工具中加入驗證,確保使用者輸入的資訊格式正確無誤。Chat 應用程式可以使用下列表單輸入小工具:

    • 文字輸入 (textInput):用於輸入自由形式或建議文字。
    • 選取輸入項 (selectionInput) 是可選取的 UI 元素,例如核取方塊、圓形按鈕和下拉式選單。選取輸入小工具也可以從靜態或動態資料來源填入項目。舉例來說,使用者可以從所屬 Chat 聊天室清單中選取自己所屬的 Chat 聊天室。
    • 日期和時間輸入項目的日期時間挑選器 (dateTimePicker)。
  • 按鈕小工具,方便使用者提交在資訊卡中輸入的值。使用者按下按鈕後,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 應用程式就會收到包含互動資訊的 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 應用程式會處理互動事件,取得使用者輸入小工具的值。下表說明如何取得特定表單輸入小工具的值。對於每個小工具,表格會顯示小工具接受的資料類型、值儲存在互動事件中的位置,以及範例值。

表單輸入小工具 輸入資料類型 互動事件的輸入值 範例值
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 應用程式可以顯示初始資訊卡,要求使用者提供預約原因,然後填入另一張資訊卡,根據預約類型提供可預約的時間。

如要從初始資訊卡轉移資料輸入內容,您可以使用 actionParameters 建構 button 小工具,其中包含小工具的 name 和使用者輸入內容,如以下範例所示:

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.
if (!contactName) {
  const errorMessage = "Don't forget to name your new contact!";
  if (event.dialogEventType === "SUBMIT_DIALOG") {
    return { actionResponse: {
      type: "DIALOG",
      dialogAction: { actionStatus: {
        statusCode: "INVALID_ARGUMENT",
        userFacingMessage: errorMessage
      }}
    }};
  } else {
    return {
      privateMessageViewer: event.user,
      text: 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.
if contact_name == "":
  error_message = "Don't forget to name your new contact!"
  if "SUBMIT_DIALOG" == event.get('dialogEventType'):
    return { 'actionResponse': {
      'type': "DIALOG",
      'dialogAction': { 'actionStatus': {
        'statusCode': "INVALID_ARGUMENT",
        'userFacingMessage': error_message
      }}
    }}
  else:
    return {
      'privateMessageViewer': event.get('user'),
      'text': 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.
if (contactName.isEmpty()) {
  String errorMessage = "Don't forget to name your new contact!";
  if (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))));
  } else {
    return new Message()
      .setPrivateMessageViewer(new User().setName(event.at("/user/name").asText()))
      .setText(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.
if (!contactName) {
  const errorMessage = "Don't forget to name your new contact!";
  if (event.dialogEventType === "SUBMIT_DIALOG") {
    return { actionResponse: {
      type: "DIALOG",
      dialogAction: { actionStatus: {
        statusCode: "INVALID_ARGUMENT",
        userFacingMessage: errorMessage
      }}
    }};
  } else {
    return {
      privateMessageViewer: event.user,
      text: errorMessage
    };
  }
}

如要處理及關閉對話方塊,您必須傳回 ActionResponse 物件,指定是否要傳送確認訊息、更新原始訊息或資訊卡,或是只關閉對話方塊。如需操作步驟,請參閱「關閉對話方塊」。

疑難排解

當 Google Chat 應用程式或資訊卡傳回錯誤時,Chat 介面會顯示「發生錯誤」的訊息。或「無法處理您的要求」。Chat UI 有時不會顯示任何錯誤訊息,但 Chat 應用程式或資訊卡卻產生非預期的結果,例如資訊卡可能不會顯示。

雖然 Chat UI 可能不會顯示錯誤訊息,但只要開啟 Chat 應用程式的錯誤記錄功能,您就能取得描述性錯誤訊息和記錄資料,協助修正錯誤。如需查看、偵錯及修正錯誤的相關說明,請參閱「排解及修正 Google Chat 錯誤」一文。