本指南說明 Google Chat 應用程式如何在以卡片為基礎的介面中建立表單輸入內容,以便收集及處理使用者提供的資訊。
在 Google Chat 中,外掛程式會向使用者顯示為 Google Chat 應用程式。詳情請參閱「擴充 Google Chat 總覽」。


Chat 應用程式會向使用者索取資訊,以便在 Chat 內或外執行動作,包括以下方式:
- 調整設定。例如,讓使用者自訂通知設定,或將 Chat 應用程式新增至一個或多個聊天室。
- 在其他 Google Workspace 應用程式中建立或更新資訊。例如,讓使用者建立 Google 日曆活動。
- 允許使用者存取及更新其他應用程式或網路服務中的資源。舉例來說,Chat 應用程式可協助使用者直接在 Chat 聊天室中更新支援單狀態。
必要條件
可在 Google Chat 中使用的 Google Workspace 外掛程式。如要建構一個,請完成HTTP 快速入門。
可在 Google Chat 中使用的 Google Workspace 外掛程式。如要建構一個應用程式,請完成 Apps Script 快速入門。
使用資訊卡建立表單
如要收集資訊,Chat 應用程式會設計表單及其輸入內容,並將這些項目建構為資訊卡。如要向使用者顯示資訊卡,Chat 應用程式可以使用下列 Chat 介面:
- 含有一或多張資訊卡的即時通訊訊息。
- 對話方塊:在訊息和首頁中開啟新視窗的資訊卡。
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
:
{
"selectionInput": {
"name": "contacts",
"type": "MULTI_SELECT",
"label": "Selected contacts",
"multiSelectMaxSelectedItems": 5,
"multiSelectMinQueryLength": 1,
"platformDataSource": {
"commonDataSource": "USER"
}
}
}
以下程式碼會顯示 Chat 空間的多重選取選單。如要填入空格,選取輸入內容會指定 hostAppDataSource
欄位。多重選取選單也會將 defaultToCurrentSpace
設為 true
,讓目前的聊天室成為選單中的預設選項:
{
"selectionInput": {
"name": "spaces",
"type": "MULTI_SELECT",
"label": "Selected contacts",
"multiSelectMaxSelectedItems": 3,
"multiSelectMinQueryLength": 1,
"platformDataSource": {
"hostAppDataSource": {
"chatDataSource": {
"spaceDataSource": {
"defaultToCurrentSpace": true
}
}
}
}
}
}
從外部資料來源填入項目
多重選取選單也可以從第三方或外部資料來源填入項目。如要使用外部資料來源,請在 SelectionInput
小工具中指定 externalDataSource
欄位,其中包含可查詢資料來源並傳回項目的函式。
為減少對外部資料來源的要求,您可以加入建議項目,讓這些項目在使用者在選單中輸入內容前,就會顯示在多重選取選單中。舉例來說,您可以為使用者填入最近搜尋的聯絡人。如要從外部資料來源填入建議項目,請指定靜態 SelectionItem
物件。
以下程式碼顯示多重選取選單,可查詢並填入外部資料來源的項目:
{
"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
小工具必須指定查詢外部資料來源的函式。如要傳回建議項目,函式必須執行以下操作:
- 處理事件物件,這是 Chat 應用程式在使用者在選單中輸入內容時收到的事件。
- 從事件物件中取得使用者輸入的值,該值會顯示在
event.commonEventObject.parameters["autocomplete_widget_query"]
欄位中。 - 使用使用者輸入的值查詢資料來源,取得一或多個
SelectionItems
供使用者參考。 - 使用
modifyCard
物件傳回動作RenderActions
,藉此傳回建議項目。
以下程式碼範例說明 Chat 應用程式如何在資訊卡的多重選取選單中,動態建議項目。當使用者在選單中輸入內容時,小工具的 externalDataSource
欄位中提供的函式或端點會查詢外部資料來源,並建議使用者可選取的項目。
/**
* 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 端點。
/**
* 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
和使用者輸入值的 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 應用程式會傳送文字訊息,確認已成功收到來自資訊卡訊息的表單。
/**
* 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."
}}}}};
}
/**
* 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 錯誤」一文。