為避免使用者在 Google Chat 中分享連結時切換情境,您的 Chat 應用程式可以預覽連結,方法是在訊息中附加資訊更豐富的資訊卡,讓使用者直接在 Google Chat 中採取行動。
舉例來說,假設 Google Chat 聊天室包含公司所有客服專員,以及名為 Case-y 的 Chat 應用程式。服務專員經常在 Chat 聊天室中分享客戶服務案件的連結,但每次同事都必須開啟案件連結,才能查看指派對象、狀態和主旨等詳細資料。同樣地,如果有人想接管案件或變更狀態,也需要開啟連結。
連結預覽功能可讓空間的常駐 Chat 應用程式 Case-y,在有人分享案件連結時,附上顯示指派對象、狀態和主旨的資訊卡。服務專員可以透過資訊卡上的按鈕接管案件,並直接在對話串中變更狀態。
連結預覽功能的運作方式
如果有人在訊息中加入連結,系統會顯示資訊方塊,提醒對方 Chat 應用程式可能會預覽連結。
傳送訊息後,連結會傳送到 Chat 應用程式,接著系統會產生資訊卡並附加至使用者的訊息。
除了連結外,資訊卡還會提供連結的額外資訊,包括按鈕等互動式元素。Chat 應用程式可以根據使用者互動 (例如點選按鈕) 更新隨附資訊卡。
如果使用者不想讓 Chat 應用程式在訊息中附加資訊卡來預覽連結,可以點選預覽資訊方塊上的
,禁止預覽連結。使用者隨時可以點選「移除預覽」,移除附加的資訊卡。必要條件
HTTP
可擴充 Google Chat 功能的 Google Workspace 外掛程式。如要建構一個,請完成 HTTP 快速入門導覽。
Apps Script
可擴充 Google Chat 功能的 Google Workspace 外掛程式。如要建構巨集,請完成 Apps Script 快速入門。
設定連結預覽
在 Google Cloud 控制台的 Chat 應用程式設定頁面中,將特定連結 (例如 example.com
、support.example.com
和 support.example.com/cases/
) 註冊為網址模式,Chat 應用程式就能預覽這些連結。
- 開啟 Google Cloud 控制台。
- 按一下「Google Cloud」旁邊的向下箭頭 ,然後開啟 Chat 應用程式的專案。
- 在搜尋欄位中輸入
Google Chat API
,然後點選「Google Chat API」。 - 依序點選「管理」>「設定」。
- 在「連結預覽」下方,新增或編輯網址模式。
- 如要為新的網址模式設定連結預覽,請按一下「新增網址模式」。
- 如要編輯現有網址模式的設定,請按一下向下箭頭 。
在「主機模式」欄位中,輸入網址模式的網域。Chat 應用程式會預覽這個網域的連結。
如要讓 Chat 應用程式預覽特定子網域 (例如
subdomain.example.com
) 的連結,請加入該子網域。如要讓 Chat 應用程式預覽整個網域的連結,請指定萬用字元,並以星號 (*) 做為子網域。舉例來說,
*.example.com
符合subdomain.example.com
和any.number.of.subdomains.example.com
。在「路徑前置字串」欄位中,輸入要附加至主機模式網域的路徑。
如要比對主機模式網域中的所有網址,請將「路徑前置字串」留空。
舉例來說,如果主機模式為
support.example.com
,如要比對在support.example.com/cases/
託管的案件網址,請輸入cases/
。按一下 [完成]。
按一下 [儲存]。
現在,只要有人在包含您 Chat 應用程式的 Chat 聊天室訊息中加入符合連結預覽網址模式的連結,您的應用程式就會預覽該連結。
預覽連結
為特定連結設定連結預覽功能後,Chat 應用程式就能辨識並預覽連結,方法是在連結中附加更多資訊。
在包含 Chat 應用程式的 Chat 聊天室中,如果有人傳送的訊息含有符合連結預覽網址模式的連結,Chat 應用程式就會收到含有 MessagePayload
的事件物件。在酬載中,message.matchedUrl
物件包含使用者在訊息中加入的連結:
JSON
message: {
matchedUrl: {
url: "https://support.example.com/cases/case123"
},
... // other message attributes redacted
}
只要檢查 MESSAGE
事件酬載中是否有 matchedUrl
欄位,Chat 應用程式就能在訊息中加入預覽連結的相關資訊。Chat 應用程式可以回覆基本文字訊息或附加資訊卡。
使用簡訊回覆
如要取得基本回覆,Chat 應用程式可以回覆連結的文字訊息,藉此預覽連結。這個範例會附加訊息,重複符合連結預覽網址模式的連結網址。
Node.js
/**
* Google Cloud Function that handles messages that have links whose
* URLs match URL patterns configured for link previewing.
*
*
* @param {Object} req Request sent from Google Chat space
* @param {Object} res Response to send back
*/
exports.previewLinks = function previewLinks(req, res) {
const chatEvent = req.body.chat;
// Handle MESSAGE events
if(chatEvent.messagePayload) {
return res.send(handlePreviewLink(chatEvent.messagePayload.message));
// Handle button clicks
} else if(chatEvent.buttonClickedPayload) {
return res.send(handleCardClick(chatEvent.buttonClickedPayload.message));
}
};
/**
* Respond to messages that have links whose URLs match URL patterns configured
* for link previewing.
*
* @param {Object} chatMessage The chat message object from Google Workspace Add On event.
* @return {Object} Response to send back depending on the matched URL.
*/
function handlePreviewLink(chatMessage) {
// If the Chat app does not detect a link preview URL pattern, reply
// with a text message that says so.
if (!chatMessage.matchedUrl) {
return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
text: 'No matchedUrl detected.'
}}}}};
}
// Reply with a text message for URLs of the subdomain "text"
if (chatMessage.matchedUrl.url.includes("text.example.com")) {
return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
text: 'event.chat.messagePayload.message.matchedUrl.url: ' + chatMessage.matchedUrl.url
}}}}};
}
}
Apps Script
/**
* Reply to messages that have links whose URLs match the pattern
* "text.example.com" configured for link previewing.
*
* @param {Object} event The event object from Google Workspace add-on.
*
* @return {Object} The action response.
*/
function onMessage(event) {
// Stores the Google Chat event as a variable.
const chatMessage = event.chat.messagePayload.message;
// If the Chat app doesn't detect a link preview URL pattern, reply
// with a text message that says so.
if (!chatMessage.matchedUrl) {
return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
text: 'No matchedUrl detected.'
}}}}};
}
// Reply with a text message for URLs of the subdomain "text".
if (chatMessage.matchedUrl.url.includes("text.example.com")) {
return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
text: 'event.chat.messagePayload.message.matchedUrl.url: ' + chatMessage.matchedUrl.url
}}}}};
}
}
附加可預覽連結的資訊卡
如要將資訊卡附加至預覽連結,請傳回含有 UpdateInlinePreviewAction
類型 ChatDataActionMarkup
物件的動作 DataActions
。
在以下範例中,Chat 應用程式會將預覽資訊卡新增至包含網址模式 support.example.com
的訊息。
Node.js
/**
* Google Cloud Function that handles messages that have links whose
* URLs match URL patterns configured for link previewing.
*
*
* @param {Object} req Request sent from Google Chat space
* @param {Object} res Response to send back
*/
exports.previewLinks = function previewLinks(req, res) {
const chatEvent = req.body.chat;
// Handle MESSAGE events
if(chatEvent.messagePayload) {
return res.send(handlePreviewLink(chatEvent.messagePayload.message));
// Handle button clicks
} else if(chatEvent.buttonClickedPayload) {
return res.send(handleCardClick(chatEvent.buttonClickedPayload.message));
}
};
/**
* Respond to messages that have links whose URLs match URL patterns configured
* for link previewing.
*
* @param {Object} chatMessage The chat message object from Google Workspace Add On event.
* @return {Object} Response to send back depending on the matched URL.
*/
function handlePreviewLink(chatMessage) {
// Attach a card to the message for URLs of the subdomain "support"
if (chatMessage.matchedUrl.url.includes("support.example.com")) {
// A hard-coded card is used in this example. In a real-life scenario,
// the case information would be fetched and used to build the card.
return { hostAppDataAction: { chatDataAction: { updateInlinePreviewAction: { cardsV2: [{
cardId: 'attachCard',
card: {
header: {
title: 'Example Customer Service Case',
subtitle: 'Case basics',
},
sections: [{ widgets: [
{ decoratedText: { topLabel: 'Case ID', text: 'case123'}},
{ decoratedText: { topLabel: 'Assignee', text: 'Charlie'}},
{ decoratedText: { topLabel: 'Status', text: 'Open'}},
{ decoratedText: { topLabel: 'Subject', text: 'It won\'t turn on...' }},
{ buttonList: { buttons: [{
text: 'OPEN CASE',
onClick: { openLink: {
url: 'https://support.example.com/orders/case123'
}},
}, {
text: 'RESOLVE CASE',
onClick: { openLink: {
url: 'https://support.example.com/orders/case123?resolved=y',
}},
}, {
text: 'ASSIGN TO ME',
// Use runtime environment variable set with self URL
onClick: { action: { function: process.env.BASE_URL }}
}]}}
]}]
}
}]}}}};
}
}
Apps Script
這個範例會傳回 card JSON,藉此傳送訊息卡片。 您也可以使用 Apps Script 卡片服務。
/**
* Attach a card to messages that have links whose URLs match the pattern
* "support.example.com" configured for link previewing.
*
* @param {Object} event The event object from Google Workspace add-on.
*
* @return {Object} The action response.
*/
function onMessage(event) {
// Stores the Google Chat event as a variable.
const chatMessage = event.chat.messagePayload.message;
// Attach a card to the message for URLs of the subdomain "support".
if (chatMessage.matchedUrl.url.includes("support.example.com")) {
// A hard-coded card is used in this example. In a real-life scenario,
// the case information would be fetched and used to build the card.
return { hostAppDataAction: { chatDataAction: { updateInlinePreviewAction: { cardsV2: [{
cardId: 'attachCard',
card: {
header: {
title: 'Example Customer Service Case',
subtitle: 'Case summary',
},
sections: [{ widgets: [
{ decoratedText: { topLabel: 'Case ID', text: 'case123'}},
{ decoratedText: { topLabel: 'Assignee', text: 'Charlie'}},
{ decoratedText: { topLabel: 'Status', text: 'Open'}},
{ decoratedText: { topLabel: 'Subject', text: 'It won\'t turn on...' }},
{ buttonList: { buttons: [{
text: 'OPEN CASE',
onClick: { openLink: {
url: 'https://support.example.com/orders/case123'
}},
}, {
text: 'RESOLVE CASE',
onClick: { openLink: {
url: 'https://support.example.com/orders/case123?resolved=y',
}},
}, {
text: 'ASSIGN TO ME',
// Clicking this button triggers the execution of the function
// "assign" from the Apps Script project.
onClick: { action: { function: 'assign'}}
}]}}
]}]
}
}]}}}};
}
}
更新連結預覽資訊卡
當使用者與連結預覽資訊卡互動時 (例如點選資訊卡上的按鈕),Chat 應用程式可以更新資訊卡。
如要更新資訊卡,Chat 應用程式必須傳回 DataActions
動作,並附上下列其中一個 ChatDataActionMarkup
物件:
- 如果使用者傳送訊息,請傳回
UpdateMessageAction
物件。 - 如果訊息是由 Chat 應用程式傳送,請傳回
UpdateInlinePreviewAction
物件。
如要判斷訊息傳送者,請使用事件酬載 (buttonClickedPayload
) 檢查傳送者 (message.sender.type
) 是否設為 HUMAN
(使用者) 或 BOT
(Chat 應用程式)。
以下範例說明 Chat 應用程式如何更新連結預覽畫面:每當使用者點選「指派給我」按鈕,應用程式就會更新資訊卡的「受讓人」欄位,並停用該按鈕。
Node.js
/**
* Google Cloud Function that handles messages that have links whose
* URLs match URL patterns configured for link previewing.
*
*
* @param {Object} req Request sent from Google Chat space
* @param {Object} res Response to send back
*/
exports.previewLinks = function previewLinks(req, res) {
const chatEvent = req.body.chat;
// Handle MESSAGE events
if(chatEvent.messagePayload) {
return res.send(handlePreviewLink(chatEvent.messagePayload.message));
// Handle button clicks
} else if(chatEvent.buttonClickedPayload) {
return res.send(handleCardClick(chatEvent.buttonClickedPayload.message));
}
};
/**
* Respond to clicks by assigning user and updating the card that was attached to a
* message with a previewed link.
*
* @param {Object} chatMessage The chat message object from Google Workspace Add On event.
* @return {Object} Action response depending on the original message.
*/
function handleCardClick(chatMessage) {
// Creates the updated card that displays "You" for the assignee
// and that disables the button.
//
// A hard-coded card is used in this example. In a real-life scenario,
// an actual assign action would be performed before building the card.
const message = { cardsV2: [{
cardId: 'attachCard',
card: {
header: {
title: 'Example Customer Service Case',
subtitle: 'Case basics',
},
sections: [{ widgets: [
{ decoratedText: { topLabel: 'Case ID', text: 'case123'}},
// The assignee is now "You"
{ decoratedText: { topLabel: 'Assignee', text: 'You'}},
{ decoratedText: { topLabel: 'Status', text: 'Open'}},
{ decoratedText: { topLabel: 'Subject', text: 'It won\'t turn on...' }},
{ buttonList: { buttons: [{
text: 'OPEN CASE',
onClick: { openLink: {
url: 'https://support.example.com/orders/case123'
}},
}, {
text: 'RESOLVE CASE',
onClick: { openLink: {
url: 'https://support.example.com/orders/case123?resolved=y',
}},
}, {
text: 'ASSIGN TO ME',
// The button is now disabled
disabled: true,
// Use runtime environment variable set with self URL
onClick: { action: { function: process.env.BASE_URL }}
}]}}
]}]
}
}]};
// Checks whether the message event originated from a human or a Chat app
// to return the adequate action response.
if(chatMessage.sender.type === 'HUMAN') {
return { hostAppDataAction: { chatDataAction: { updateInlinePreviewAction: message }}};
} else {
return { hostAppDataAction: { chatDataAction: { updateMessageAction: message }}};
}
}
Apps Script
這個範例會傳回 card JSON,藉此傳送訊息卡片。 您也可以使用 Apps Script 卡片服務。
/**
* Assigns and updates the card that's attached to a message with a
* previewed link of the pattern "support.example.com".
*
* @param {Object} event The event object from the Google Workspace add-on.
*
* @return {Object} Action response depending on the message author.
*/
function assign(event) {
// Creates the updated card that displays "You" for the assignee
// and that disables the button.
//
// A hard-coded card is used in this example. In a real-life scenario,
// an actual assign action would be performed before building the card.
const message = { cardsV2: [{
cardId: 'attachCard',
card: {
header: {
title: 'Example Customer Service Case',
subtitle: 'Case summary',
},
sections: [{ widgets: [
{ decoratedText: { topLabel: 'Case ID', text: 'case123'}},
// The assignee is now "You"
{ decoratedText: { topLabel: 'Assignee', text: 'You'}},
{ decoratedText: { topLabel: 'Status', text: 'Open'}},
{ decoratedText: { topLabel: 'Subject', text: 'It won\'t turn on...' }},
{ buttonList: { buttons: [{
text: 'OPEN CASE',
onClick: { openLink: {
url: 'https://support.example.com/orders/case123'
}},
}, {
text: 'RESOLVE CASE',
onClick: { openLink: {
url: 'https://support.example.com/orders/case123?resolved=y',
}},
}, {
text: 'ASSIGN TO ME',
// The button is now disabled
disabled: true,
onClick: { action: { function: 'assign'}}
}]}}
]}]
}
}]};
// Use the adequate action response type. It depends on whether the message
// the preview link card is attached to was created by a human or a Chat app.
if(event.chat.buttonClickedPayload.message.sender.type === 'HUMAN') {
return { hostAppDataAction: { chatDataAction: { updateInlinePreviewAction: message }}};
} else {
return { hostAppDataAction: { chatDataAction: { updateMessageAction: message }}};
}
}
限制和注意事項
為 Chat 應用程式設定連結預覽時,請注意下列限制和考量事項:
- 每個 Chat 應用程式最多支援 5 個網址模式的連結預覽。
- Chat 應用程式會預覽每則訊息中的一個連結。如果單一訊息中有多個可預覽的連結,系統只會預覽第一個可預覽的連結。
- 即時通訊應用程式只會預覽開頭為
https://
的連結,因此會預覽https://support.example.com/cases/
,但不會預覽support.example.com/cases/
。 - 除非訊息包含其他會傳送至 Chat 應用程式的資訊 (例如斜線指令),否則連結預覽功能只會將連結網址傳送至 Chat 應用程式。
- 如果使用者發布連結,只有在使用者與連結預覽資訊卡互動 (例如點選按鈕) 時,Chat 應用程式才能更新該資訊卡。您無法在
Message
資源上呼叫 Chat API 的update()
方法,以非同步方式更新使用者的訊息。 - 聊天室應用程式必須為聊天室中的所有使用者預覽連結,因此訊息必須省略
privateMessageViewer
欄位。
偵錯連結預覽
導入連結預覽功能時,您可能需要讀取應用程式記錄,才能對 Chat 應用程式進行偵錯。如要讀取記錄,請前往 Google Cloud 控制台的「記錄檔探索工具」。