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

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

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

Chat 擴充應用程式會要求使用者提供資訊,以便在 Chat 內或外部執行動作,包括:

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

必要條件

HTTP

可擴充 Google Chat 的 Google Workspace 外掛程式。如要建構一個,請完成 HTTP 快速入門導覽

Apps Script

可擴充 Google Chat 的 Google Workspace 外掛程式。如要建構巨集,請完成 Apps Script 快速入門導覽

使用資訊卡建立表單

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

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

即時通訊應用程式可使用下列小工具建構資訊卡:

  • 要求使用者提供資訊的表單輸入小工具。視需要為表單輸入小工具新增驗證,確保使用者輸入的資訊格式正確無誤。即時通訊應用程式可以使用下列表單輸入小工具:

    • 文字輸入 (textInput) 任意形式或建議的文字。
    • 選取輸入項 (selectionInput) 是可選取的 UI 元素,例如核取方塊、圓形按鈕和下拉式選單。選取輸入小工具也可以從 Google Workspace 資料 (例如 Google 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. 傳回動作 RenderActionsmodifyCard 物件,即可傳回建議項目。

下列程式碼範例說明 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 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
  };
}

將資料轉移到其他卡片

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

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

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

Node.js

{
  "buttonList": { "buttons": [{
    "text": "Submit",
    "onClick": { "action": {
      "function": "FUNCTION_URL", // Must be an `https` endpoint.
      "parameters": [
        {
          "key": "WIDGET_NAME",
          "value": "USER_INPUT_VALUE"
        },
        // Can specify multiple parameters
      ]
    }}
  }]}
}

Apps Script

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

其中 WIDGET_NAME 是小工具的 nameUSER_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 使用者介面未顯示錯誤訊息,只要開啟 Chat 應用程式的錯誤記錄功能,系統就會提供說明性錯誤訊息和記錄資料,協助您修正錯誤。如需查看、偵錯及修正錯誤的相關協助,請參閱「排解及修正 Google Chat 錯誤」。