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

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

在 Google Chat 中,使用者會看到附加元件,就像是 Google Chat 應用程式一樣。詳情請參閱「擴充 Google Chat 總覽」。

對話方塊,其中包含各種不同的小工具。
圖 1:即時通訊應用程式開啟對話方塊來收集聯絡人資訊。

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

  • 調整設定。例如,讓使用者自訂通知設定,或將 Chat 應用程式新增至一個或多個聊天室。
  • 在其他 Google Workspace 應用程式中建立或更新資訊。例如,讓使用者建立 Google 日曆活動。
  • 允許使用者存取及更新其他應用程式或網路服務中的資源。舉例來說,Chat 應用程式可協助使用者直接在 Chat 聊天室中更新支援單狀態。

必要條件

Node.js

可在 Google Chat 中使用的 Google Workspace 外掛程式。如要建構一個,請完成HTTP 快速入門

Apps Script

可在 Google Chat 中使用的 Google Workspace 外掛程式。如要建構一個應用程式,請完成 Apps Script 快速入門

使用資訊卡建立表單

如要收集資訊,Chat 應用程式會設計表單及其輸入內容,並將這些項目建構為資訊卡。如要向使用者顯示資訊卡,Chat 應用程式可以使用下列 Chat 介面:

  • 含有一或多張資訊卡的即時通訊訊息。
  • 對話方塊:在訊息和首頁中開啟新視窗的資訊卡。

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

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

    • 文字輸入 (textInput):用於輸入自由形式或建議文字。
    • 選取輸入項 (selectionInput) 是可選取的 UI 元素,例如核取方塊、圓形按鈕和下拉式選單。選取輸入小工具也可以從 Google Workspace 資料 (例如 Chat 空間) 或動態資料來源填入及建議項目。詳情請參閱下節「新增多重選取選單」。

    • 日期和時間輸入項目的日期時間挑選器 (dateTimePicker)。

  • 按鈕小工具,方便使用者提交在資訊卡中輸入的值。使用者按下按鈕後,Chat 應用程式就能處理收到的資訊

在以下範例中,資訊卡會使用文字輸入、日期時間挑選器和選項輸入功能收集聯絡資訊:

如要查看更多可用於收集資訊的互動式小工具範例,請參閱 Google Chat API 說明文件中的「設計互動式資訊卡或對話方塊」。

新增多重選取選單

如要自訂選取項目,或讓使用者從動態資料來源選取項目,Chat 應用程式可以使用多重選取選單,這是一種 SelectionInput 小工具。舉例來說,下列資訊卡會顯示多重選取選單,使用者可從聯絡人清單中動態選取:

您可以從下列資料來源為多重選取選單填入項目:

  • Google Workspace 資料,包括使用者或使用者所屬的 Chat 聊天室。選單只會填入同一個 Google Workspace 機構的項目。
  • 外部資料來源,例如關聯資料庫。舉例來說,您可以使用多重選取選單,協助使用者從客戶關係管理 (CRM) 系統的待開發客戶清單中選取項目。

從 Google Workspace 資料來源填入項目

如要使用 Google Workspace 資料來源,請在 SelectionInput 小工具中指定 platformDataSource 欄位。與其他選項輸入類型不同,您可以省略 SelectionItem 物件,因為這些選項項目會從 Google Workspace 動態取得。

下列程式碼會顯示 Google Workspace 使用者的多重選取選單。如要填入使用者,請在選取輸入內容中將 commonDataSource 設為 USER

JSON

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

以下程式碼會顯示 Chat 空間的多重選取選單。如要填入空格,選取輸入內容會指定 hostAppDataSource 欄位。多重選取選單也會將 defaultToCurrentSpace 設為 true,讓目前的聊天室成為選單中的預設選項:

JSON

{
  "selectionInput": {
    "name": "spaces",
    "type": "MULTI_SELECT",
    "label": "Selected contacts",
    "multiSelectMaxSelectedItems": 3,
    "multiSelectMinQueryLength": 1,
    "platformDataSource": {
      "hostAppDataSource": {
        "chatDataSource": {
          "spaceDataSource": {
            "defaultToCurrentSpace": true
          }
        }
      }
    }
  }
}

從外部資料來源填入項目

多重選取選單也可以從第三方或外部資料來源填入項目。如要使用外部資料來源,請在 SelectionInput 小工具中指定 externalDataSource 欄位,其中包含可查詢資料來源並傳回項目的函式。

為減少對外部資料來源的要求,您可以納入建議項目,讓這些項目在使用者在選單中輸入內容前,就會顯示在多重選取選單中。舉例來說,您可以為使用者填入最近搜尋的聯絡人。如要從外部資料來源填入建議項目,請指定靜態 SelectionItem 物件。

以下程式碼顯示多重選取選單,可查詢並填入外部資料來源的項目:

JSON

{
  "selectionInput": {
    "name": "contacts",
    "type": "MULTI_SELECT",
    "label": "Selected contacts",
    "multiSelectMaxSelectedItems": 3,
    "multiSelectMinQueryLength": 1,
    "externalDataSource": { "function": "FUNCTION" },
    // Suggested items loaded by default.
    // The list is static here but it could be dynamic.
    "items": [FUNCTION]
  }
}

FUNCTION 替換為查詢外部資料庫的 HTTP 網址或 Apps Script 函式名稱。如需完整範例,說明如何傳回建議項目,請參閱「建議多重選取項目」一節。

接收互動式小工具的資料

只要使用者按下按鈕,Chat 應用程式的動作就會觸發,並提供互動資訊。在事件酬載的 commonEventObject 中,formInputs 物件包含使用者輸入的任何值。

您可以從物件 commonEventObject.formInputs.WIDGET_NAME 擷取值,其中 WIDGET_NAME 是您為小工具指定的 name 欄位。系統會將值傳回為小工具的特定資料類型。

以下顯示事件物件的一部分,其中使用者輸入了每個小工具的值:

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

如要接收資料,Chat 應用程式會處理事件物件,取得使用者輸入小工具的值。下表說明如何取得特定表單輸入小工具的值。針對每個小工具,表格會顯示小工具接受的資料類型、值儲存在事件物件中的位置,以及範例值。

表單輸入小工具 輸入資料類型 事件物件的輸入值 範例值
textInput stringInputs event.commonEventObject.formInputs.contactName.stringInputs.value[0] Kai O
selectionInput stringInputs 如要取得第一個或唯一的值,請使用 event.commonEventObject.formInputs.contactType.stringInputs.value[0] Personal
dateTimePicker 只接受日期。 dateInput event.commonEventObject.formInputs.contactBirthdate.dateInput.msSinceEpoch 1000425600000

Chat 應用程式收到資料後,可以執行下列任一操作:

  • 如果資訊卡包含多重選取選單,請根據使用者在選單中輸入的內容,填入或建議項目
  • 將資料轉移至另一個資訊卡,方便使用者查看自己的資訊或繼續填寫表單的下一節。
  • 回覆使用者,確認使用者已成功填寫表單。

建議多選項目

如果資訊卡包含多重選取選單,且該選單會從外部資料來源填入項目,Chat 應用程式就能根據使用者在選單中輸入的內容,傳回建議項目。舉例來說,如果使用者開始在選單中輸入 Atl,以便填入美國的城市,Chat 應用程式可以在使用者輸入完畢前,自動建議 Atlanta。Chat 應用程式最多可建議 100 個項目。

如要在多重選取選單中建議及動態填入項目,資訊卡上的 SelectionInput 小工具必須指定查詢外部資料來源的函式。如要傳回建議項目,函式必須執行以下操作:

  1. 處理 事件物件,Chat 應用程式會在使用者在選單中輸入內容時收到此物件。
  2. 從事件物件中取得使用者輸入的值,該值會顯示在 event.commonEventObject.parameters["autocomplete_widget_query"] 欄位中。
  3. 使用使用者輸入的值查詢資料來源,取得一或多個 SelectionItems 供使用者參考。
  4. 使用 modifyCard 物件傳回動作 RenderActions,藉此傳回建議項目。

以下程式碼範例說明 Chat 應用程式如何在資訊卡的多重選取選單中,動態建議項目。當使用者在選單中輸入內容時,小工具的 externalDataSource 欄位中提供的函式或端點會查詢外部資料來源,並建議使用者可選取的項目。

Node.js

/**
 * Google Cloud Function that responds to events sent from a
 * Google Chat space.
 *
 * @param {Object} req Request sent from Google Chat space
 * @param {Object} res Response to send back
 */
exports.selectionInput = function selectionInput(req, res) {
  if (req.method === 'GET' || !req.body.chat) {
    return res.send('Hello! This function is meant to be used ' +
        'in a Google Chat Space.');
  }
  // Stores the Google Chat event
  const chatEvent = req.body.chat;

  // Handle user interaction with multiselect.
  if(chatEvent.widgetUpdatedPayload) {
    return res.send(queryContacts(req.body));
  }
  // Replies with a card that contains the multiselect menu.
  return res.send({ hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    cardsV2: [{
      cardId: "contactSelector",
      card: { sections:[{ widgets: [{
        selectionInput: {
          name: "contacts",
          type: "MULTI_SELECT",
          label: "Selected contacts",
          multiSelectMaxSelectedItems: 3,
          multiSelectMinQueryLength: 1,
          externalDataSource: { function: "FUNCTION_URL" },
          // Suggested items loaded by default.
          // The list is static here but it could be dynamic.
          items: [getSuggestedContact("3")]
        }
      }]}]}
    }]
  }}}}});
};

/**
* Get contact suggestions based on text typed by users.
*
* @param {Object} event the event object that contains the user's query
* @return {Object} suggestions
*/
function queryContacts(event) {
  const query = event.commonEventObject.parameters["autocomplete_widget_query"];
  return { action: { modifyOperations: [{ updateWidget: { selectionInputWidgetSuggestions: { suggestions: [
    // The list is static here but it could be dynamic.
    getSuggestedContact("1"), getSuggestedContact("2"), getSuggestedContact("3"), getSuggestedContact("4"), getSuggestedContact("5")
  // Only return items based on the query from the user.
  ].filter(e => !query || e.text.includes(query)) }}}]}};
}

/**
 * Generate a suggested contact given an ID.
 *
 * @param {String} id The ID of the contact to return.
 * @return {Object} The contact formatted as a selection item in the menu.
 */
function getSuggestedContact(id) {
  return {
    value: id,
    startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    text: "Contact " + id
  };
}

FUNCTION_URL 替換為查詢外部資料來源的 HTTP 端點。

Apps Script

/**
* Responds to a Message trigger in Google Chat.
*
* @param {Object} event the event object from Google Chat
* @return {Object} Response from the Chat app.
*/
function onMessage(event) {
  // Replies with a card that contains the multiselect menu.
  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    cardsV2: [{
      cardId: "contactSelector",
      card: { sections:[{ widgets: [{
        selectionInput: {
          name: "contacts",
          type: "MULTI_SELECT",
          label: "Selected contacts",
          multiSelectMaxSelectedItems: 3,
          multiSelectMinQueryLength: 1,
          externalDataSource: { function: "queryContacts" },
          // Suggested items loaded by default.
          // The list is static here but it could be dynamic.
          items: [getSuggestedContact"3")]
        }
      }]}]}
    }]
  }}}}};
}

/**
* Get contact suggestions based on text typed by users.
*
* @param {Object} event the interactive event.
* @return {Object} suggestions
*/
function queryContacts(event) {
  const query = event.commonEventObject.parameters["autocomplete_widget_query"];
  return { action: { modifyOperations: [{ updateWidget: { selectionInputWidgetSuggestions: { suggestions: [
    // The list is static here but it could be dynamic.
    getSuggestedContact("1"), getSuggestedContact("2"), getSuggestedContact("3"), getSuggestedContact("4"), getSuggestedContact("5")
  // Only return items based on the query from the user.
  ].filter(e => !query || e.text.includes(query)) }}}]}};
}

/**
* Generate a suggested contact given an ID.
*
* @param {String} id The ID of the contact to return.
* @return {Object} The contact formatted as a selection item in the menu.
*/
function getSuggestedContact(id) {
  return {
    value: id,
    startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    text: "Contact " + id
  };
}

將資料轉移到其他卡片

使用者提交資訊卡後,您可能需要傳回其他資訊卡,才能執行下列任一操作:

  • 建立不同的部分,協助使用者填寫較長的表單。
  • 讓使用者預覽並確認初始資訊卡中的資訊,方便他們在提交前檢查答案。
  • 動態填入表單的其餘部分。舉例來說,如要提示使用者建立預約,Chat 應用程式可以顯示初始資訊卡,要求使用者提供預約原因,然後填入另一張資訊卡,根據預約類型提供可預約的時間。

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

{
  "buttonList": { "buttons": [{
    "text": "Submit",
    "onClick": { "action": {
      "function": "submitForm",
      "parameters": [
        {
          "key": "WIDGET_NAME",
          "value": "USER_INPUT_VALUE"
        },
        // Can specify multiple parameters
      ]
    }}
  }]}
}

其中 WIDGET_NAME 是小工具的 name,而 USER_INPUT_VALUE 是使用者輸入的內容。舉例來說,如果是收集使用者姓名的文字輸入內容,小工具名稱為 contactName,範例值則為 Kai O

使用者按下按鈕時,Chat 應用程式會收到事件物件,您可以透過該物件接收資料

回覆表單提交

接收資訊卡訊息或對話方塊的資料後,Chat 應用程式會回應,確認已收到資料或傳回錯誤。

在以下範例中,Chat 應用程式會傳送文字訊息,確認已成功收到來自資訊卡訊息的表單。

Node.js

/**
 * Google Cloud Function that handles all Google Workspace Add On events for
 * the contact manager app.
 *
 * @param {Object} req Request sent from Google Chat space
 * @param {Object} res Response to send back
 */
exports.contactManager = function contactManager(req, res) {
  const chatEvent = req.body.chat;
  const chatMessage = chatEvent.messagePayload.message;

  // Handle message payloads in the event object
  if(chatEvent.messagePayload) {
    return res.send(handleMessage(chatMessage, chatEvent.user));
  // Handle button clicks on the card
  } else if(chatEvent.buttonClickedPayload) {
    switch(req.body.commonEventObject.parameters.actionName) {
        case "openDialog":
            return res.send(openDialog());
        case "openNextCard":
            return res.send(openNextCard(req.body));
        case "submitForm":
            return res.send(submitForm(req.body));
    }
  }
};

/**
 * Submits information from a dialog or card message.
 *
 * @param {Object} event the interactive event with form inputs.
 * @return {Object} a message response that posts a private message.
 */
function submitForm(event) {
  const chatUser = event.chat.user;
  const contactName = event.commonEventObject.parameters["contactName"];

  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    privateMessageViewer: chatUser,
    text: "✅ " + contactName + " has been added to your contacts."
  }}}}};
}

Apps Script

/**
 * Sends private text message that confirms submission.
 *
 * @param {Object} event the interactive event with form inputs.
 * @return {Object} a message response that posts a private message.
 */
function submitForm(event) {
  const chatUser = event.chat.user;
  const contactName = event.commonEventObject.parameters["contactName"];

  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    privateMessageViewer: chatUser,
    text: "✅ " + contactName + " has been added to your contacts."
  }}}}};
}

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

疑難排解

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

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