為了避免使用者在 Google Chat 中分享連結時切換背景資訊,你可以在 Chat 訊息中附加資訊卡來預覽連結,方便使用者直接透過 Google Chat 採取行動。
舉例來說,假設有一個 Google Chat 聊天室包含公司所有的客服專員,以及名為 Case-y 的 Chat 應用程式,服務專員經常在 Chat 聊天室中分享客戶服務案件的連結,而且每當有同事時,他們都必須開啟客服案件連結,才能查看指派對象、狀態和主旨等詳細資料。同樣地,如果有人想取得客服案件的擁有權或變更狀態,就必須開啟連結。
透過連結預覽功能,聊天室的常駐 Chat 應用程式 Case-y 可以在有人分享案件連結時,附加顯示指派對象、狀態和主旨的資訊卡。資訊卡上的按鈕可讓服務專員取得案件擁有權,並直接在聊天室訊息串中變更狀態。
連結預覽功能的運作方式
當使用者在訊息中新增連結時,畫面上會顯示方塊,說明 Chat 應用程式可能會預覽連結。
訊息傳送後,連結會傳送到 Chat 應用程式,然後產生資訊卡並附加到使用者的訊息中。
資訊卡旁邊會顯示連結額外資訊,包括按鈕等互動元素。您的 Chat 應用程式可根據使用者互動 (例如點選按鈕) 來更新附加的資訊卡。
如果有人在訊息中附加資訊卡,不希望 Chat 應用程式預覽自己的連結,可以按一下預覽方塊上的 cancel,禁止系統預覽。使用者隨時可以按一下「移除預覽」移除附加的資訊卡。
必要條件
Node.js
已啟用互動功能的 Google Chat 應用程式。如要建立
請使用 HTTP 服務互動式即時通訊應用程式,請完成快速入門導覽課程。
Apps Script
已啟用互動功能的 Google Chat 應用程式。如要建立
,請完成快速入門導覽課程。
在 Google Cloud 控制台的 Chat 應用程式設定頁面,將特定連結 (例如 example.com
、support.example.com
和 support.example.com/cases/
) 註冊為網址模式,以便讓 Chat 應用程式預覽。
- 開啟 Google Cloud 控制台。
- 在「Google Cloud」旁邊按一下向下箭頭 arrow_drop_down,然後開啟 Chat 應用程式的專案。
- 在搜尋欄位中輸入
Google Chat API
,然後按一下「Google Chat API」。
- 依序按一下「Manage」(管理) >「Configuration」(設定)。
- 在「連結預覽」下方,新增或編輯網址模式。
- 如要為新網址格式設定連結預覽,請按一下「新增網址格式」。
- 如要編輯現有網址格式的設定,請按一下向下箭頭 expand_more。
在「主機模式」欄位中,輸入網址模式的網域。Chat 應用程式將預覽這個網域的連結。
如要針對特定子網域 (例如 subdomain.example.com
) 加入 Chat 應用程式預覽連結,請加入子網域。
如要將 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 應用程式
收到
MESSAGE
互動事件。JSON
互動事件的酬載包含 matchedUrl
欄位:
JSON
"message": {
. . . // other message attributes redacted
"matchedUrl": {
"url": "https://support.example.com/cases/case123"
},
. . . // other message attributes redacted
}
檢查 MESSAGE
事件中是否存在 matchedUrl
欄位
酬載,您的 Chat 應用程式可以將資訊新增至
以及含有預覽連結的訊息Chat 應用程式可以
以簡單的簡訊回覆,或附加資訊卡。
以簡訊回覆
如果回覆較單純,Chat 應用程式可以預覽連結
使用簡單的簡訊回覆
連結。這個範例所附加的訊息重複了
符合連結預覽網址模式。
附加卡片
如何在預覽連結中附加資訊卡:
傳回
ActionResponse
敬上
類型為 UPDATE_USER_MESSAGE_CARDS
。本範例會附加一張簡易資訊卡。
Node.js
/**
* Responds to messages that have links whose URLs match URL patterns
* configured for link previewing.
*
* @param {Object} req Request sent from Google Chat.
* @param {Object} res Response to send back.
*/
exports.onMessage = (req, res) => {
if (req.method === 'GET' || !req.body.message) {
return res.send(
'Hello! This function is meant to be used in a Google Chat Space.');
}
// Checks for the presence of event.message.matchedUrl and attaches a card
// if present
if (req.body.message.matchedUrl) {
return res.json({
'actionResponse': {'type': 'UPDATE_USER_MESSAGE_CARDS'},
'cardsV2': [
{
'cardId': 'attachCard',
'card': {
'header': {
'title': 'Example Customer Service Case',
'subtitle': 'Case basics',
},
'sections': [
{
'widgets': [
{'keyValue': {'topLabel': 'Case ID', 'content': 'case123'}},
{'keyValue': {'topLabel': 'Assignee', 'content': 'Charlie'}},
{'keyValue': {'topLabel': 'Status', 'content': 'Open'}},
{
'keyValue': {
'topLabel': 'Subject', 'content': 'It won"t turn on...',
}
},
],
},
{
'widgets': [
{
'buttons': [
{
'textButton': {
'text': 'OPEN CASE',
'onClick': {
'openLink': {
'url': 'https://support.example.com/orders/case123',
},
},
},
},
{
'textButton': {
'text': 'RESOLVE CASE',
'onClick': {
'openLink': {
'url': 'https://support.example.com/orders/case123?resolved=y',
},
},
},
},
{
'textButton': {
'text': 'ASSIGN TO ME',
'onClick': {
'action': {
'actionMethodName': 'assign',
},
},
},
},
],
},
],
},
],
},
},
],
});
}
// If the Chat app doesn’t detect a link preview URL pattern, it says so.
return res.json({'text': 'No matchedUrl detected.'});
};
Apps Script
此範例會透過
資訊卡 JSON。
您也可以使用
Apps Script Card 服務。
/**
* Responds to messages that have links whose URLs match URL patterns
* configured for link previewing.
*
* @param {Object} event The event object from Chat API.
* @return {Object} Response from the Chat app attached to the message with
* the previewed link.
*/
function onMessage(event) {
// Checks for the presence of event.message.matchedUrl and attaches a card
// if present
if (event.message.matchedUrl) {
return {
'actionResponse': {
'type': 'UPDATE_USER_MESSAGE_CARDS',
},
'cardsV2': [{
'cardId': 'attachCard',
'card': {
'header': {
'title': 'Example Customer Service Case',
'subtitle': 'Case basics',
},
'sections': [{
'widgets': [
{'keyValue': {'topLabel': 'Case ID', 'content': 'case123'}},
{'keyValue': {'topLabel': 'Assignee', 'content': 'Charlie'}},
{'keyValue': {'topLabel': 'Status', 'content': 'Open'}},
{
'keyValue': {
'topLabel': 'Subject', 'content': 'It won\'t turn on...',
},
},
],
},
{
'widgets': [{
'buttons': [
{
'textButton': {
'text': 'OPEN CASE',
'onClick': {
'openLink': {
'url': 'https://support.example.com/orders/case123',
},
},
},
},
{
'textButton': {
'text': 'RESOLVE CASE',
'onClick': {
'openLink': {
'url': 'https://support.example.com/orders/case123?resolved=y',
},
},
},
},
{
'textButton': {
'text': 'ASSIGN TO ME',
'onClick': {'action': {'actionMethodName': 'assign'}},
},
},
],
}],
}],
},
}],
};
}
// If the Chat app doesn’t detect a link preview URL pattern, it says so.
return {'text': 'No matchedUrl detected.'};
}
更新卡片
如要更新附加至預覽連結的資訊卡,請傳回
ActionResponse
敬上
類型為 UPDATE_USER_MESSAGE_CARDS
。即時通訊應用程式只能更新
能夠預覽連結以回應使用者的卡片
Chat 應用程式互動事件:
即時通訊應用程式無法藉由呼叫 Chat API 更新這些卡片
以非同步方式載入物件
連結預覽不支援傳回 UPDATE_MESSAGE
類型的 ActionResponse
。由於 UPDATE_MESSAGE
會更新完整訊息,而非僅更新資訊卡,因此只有在 Chat 應用程式建立原始訊息時才能使用這項功能。連結預覽功能會將資訊卡附加到使用者建立的訊息,因此 Chat 應用程式沒有更新資訊卡的權限。
為確保函式會更新 Chat 串流中使用者建立和應用程式建立的資訊卡,請根據 Chat 應用程式或使用者建立訊息,動態設定 ActionResponse
。
您可透過以下兩種方式確認訊息是否由使用者建立:在附件的 onclick
屬性中指定並檢查自訂 actionMethodName
(將訊息識別為使用者建立),或查看訊息是否由使用者建立。
如要使用 actionMethodName
正確處理預覽資訊卡上的 CARD_CLICKED
互動事件,請在附加的資訊卡的 onclick
屬性中設定自訂 actionMethodName
:
JSON
. . . // Preview card details
{
"textButton": {
"text": "ASSIGN TO ME",
"onClick": {
// actionMethodName identifies the button to help determine the
// appropriate ActionResponse.
"action": {
"actionMethodName": "assign",
}
}
}
}
. . . // Preview card details
使用 "actionMethodName": "assign"
將按鈕識別為連結預覽的一部分,您可以透過檢查相符的 actionMethodName
,以動態方式傳回正確的 ActionResponse
:
方法 2:檢查寄件者類型
確認 message.sender.type
是 HUMAN
還是 BOT
。如果是 HUMAN
,請將 ActionResponse
設為 UPDATE_USER_MESSAGE_CARDS
;否則請將 ActionResponse
設為 UPDATE_MESSAGE
。步驟如下:
更新資訊卡的常見原因在於按下按鈕。找出前一節「附加卡片」的「指派給我」按鈕。下方的完整範例會更新資訊卡,指出卡片已指派給「您」使用者按一下 [Assign to Me] (指派給我) 後。這個範例會透過檢查傳送者類型,以動態方式設定 ActionResponse
。
完整範例:Case-y 客戶服務即時通訊應用程式
以下是 Case-y 的完整程式碼:Case-y 是一個即時通訊應用程式,可預覽客服專員在 Chat 聊天室中分享的案件連結。
Node.js
/**
* Responds to messages that have links whose URLs match URL patterns
* configured for link previewing.
*
* @param {Object} req Request sent from Google Chat.
* @param {Object} res Response to send back.
*/
exports.onMessage = (req, res) => {
if (req.method === 'GET' || !req.body.message) {
return res.send(
'Hello! This function is meant to be used in a Google Chat Space.');
}
// Respond to button clicks on attached cards
if (req.body.type === 'CARD_CLICKED') {
// Checks whether the message event originated from a human or a Chat app
// and sets actionResponse.type to "UPDATE_USER_MESSAGE_CARDS if human or
// "UPDATE_MESSAGE" if Chat app.
const actionResponseType = req.body.action.actionMethodName === 'HUMAN' ?
'UPDATE_USER_MESSAGE_CARDS' :
'UPDATE_MESSAGE';
if (req.body.action.actionMethodName === 'assign') {
return res.json(createMessage(actionResponseType, 'You'));
}
}
// Checks for the presence of event.message.matchedUrl and attaches a card
// if present
if (req.body.message.matchedUrl) {
return res.json(createMessage());
}
// If the Chat app doesn’t detect a link preview URL pattern, it says so.
return res.json({'text': 'No matchedUrl detected.'});
};
/**
* Message to create a card with the correct response type and assignee.
*
* @param {string} actionResponseType
* @param {string} assignee
* @return {Object} a card with URL preview
*/
function createMessage(
actionResponseType = 'UPDATE_USER_MESSAGE_CARDS',
assignee = 'Charlie'
) {
return {
'actionResponse': {'type': actionResponseType},
'cardsV2': [
{
'cardId': 'previewLink',
'card': {
'header': {
'title': 'Example Customer Service Case',
'subtitle': 'Case basics',
},
'sections': [
{
'widgets': [
{'keyValue': {'topLabel': 'Case ID', 'content': 'case123'}},
{'keyValue': {'topLabel': 'Assignee', 'content': assignee}},
{'keyValue': {'topLabel': 'Status', 'content': 'Open'}},
{
'keyValue': {
'topLabel': 'Subject', 'content': 'It won"t turn on...',
},
},
],
},
{
'widgets': [
{
'buttons': [
{
'textButton': {
'text': 'OPEN CASE',
'onClick': {
'openLink': {
'url': 'https://support.example.com/orders/case123',
},
},
},
},
{
'textButton': {
'text': 'RESOLVE CASE',
'onClick': {
'openLink': {
'url': 'https://support.example.com/orders/case123?resolved=y',
},
},
},
},
{
'textButton': {
'text': 'ASSIGN TO ME',
'onClick': {
'action': {
'actionMethodName': 'assign',
},
},
},
},
],
},
],
},
],
}
},
],
};
}
Apps Script
此範例會透過
資訊卡 JSON。
您也可以使用
Apps Script Card 服務。
/**
* Responds to messages that have links whose URLs match URL patterns
* configured for link previews.
*
* @param {Object} event The event object from Chat API.
* @return {Object} Response from the Chat app attached to the message with
* the previewed link.
*/
function onMessage(event) {
// Checks for the presence of event.message.matchedUrl and attaches a card
// if present
if (event.message.matchedUrl) {
return {
'actionResponse': {
'type': 'UPDATE_USER_MESSAGE_CARDS',
},
'cardsV2': [{
'cardId': 'previewLink',
'card': {
'header': {
'title': 'Example Customer Service Case',
'subtitle': 'Case basics',
},
'sections': [{
'widgets': [
{'keyValue': {'topLabel': 'Case ID', 'content': 'case123'}},
{'keyValue': {'topLabel': 'Assignee', 'content': 'Charlie'}},
{'keyValue': {'topLabel': 'Status', 'content': 'Open'}},
{
'keyValue': {
'topLabel': 'Subject', 'content': 'It won\'t turn on...',
}
},
],
},
{
'widgets': [{
'buttons': [
{
'textButton': {
'text': 'OPEN CASE',
'onClick': {
'openLink': {
'url': 'https://support.example.com/orders/case123',
},
},
},
},
{
'textButton': {
'text': 'RESOLVE CASE',
'onClick': {
'openLink': {
'url': 'https://support.example.com/orders/case123?resolved=y',
},
},
},
},
{
'textButton': {
'text': 'ASSIGN TO ME',
'onClick': {'action': {'actionMethodName': 'assign'}}
},
},
],
}],
}],
},
}],
};
}
// If the Chat app doesn’t detect a link preview URL pattern, it says so.
return {'text': 'No matchedUrl detected.'};
}
/**
* Updates a card that was attached to a message with a previewed link.
*
* @param {Object} event The event object from Chat API.
* @return {Object} Response from the Chat app. Either a new card attached to
* the message with the previewed link, or an update to an existing card.
*/
function onCardClick(event) {
// Checks whether the message event originated from a human or a Chat app
// and sets actionResponse to "UPDATE_USER_MESSAGE_CARDS if human or
// "UPDATE_MESSAGE" if Chat app.
const actionResponseType = event.message.sender.type === 'HUMAN' ?
'UPDATE_USER_MESSAGE_CARDS' :
'UPDATE_MESSAGE';
// To respond to the correct button, checks the button's actionMethodName.
if (event.action.actionMethodName === 'assign') {
return assignCase(actionResponseType);
}
}
/**
* Updates a card to say that "You" are the assignee after clicking the Assign
* to Me button.
*
* @param {String} actionResponseType Which actionResponse the Chat app should
* use to update the attached card based on who created the message.
* @return {Object} Response from the Chat app. Updates the card attached to
* the message with the previewed link.
*/
function assignCase(actionResponseType) {
return {
'actionResponse': {
// Dynamically returns the correct actionResponse type.
'type': actionResponseType,
},
'cardsV2': [{
'cardId': 'assignCase',
'card': {
'header': {
'title': 'Example Customer Service Case',
'subtitle': 'Case basics',
},
'sections': [{
'widgets': [
{'keyValue': {'topLabel': 'Case ID', 'content': 'case123'}},
{'keyValue': {'topLabel': 'Assignee', 'content': 'You'}},
{'keyValue': {'topLabel': 'Status', 'content': 'Open'}},
{
'keyValue': {
'topLabel': 'Subject', 'content': 'It won\'t turn on...',
}
},
],
},
{
'widgets': [{
'buttons': [
{
'textButton': {
'text': 'OPEN CASE',
'onClick': {
'openLink': {
'url': 'https://support.example.com/orders/case123',
},
},
},
},
{
'textButton': {
'text': 'RESOLVE CASE',
'onClick': {
'openLink': {
'url': 'https://support.example.com/orders/case123?resolved=y',
},
},
},
},
{
'textButton': {
'text': 'ASSIGN TO ME',
'onClick': {'action': {'actionMethodName': 'assign'}},
},
},
],
}],
}],
},
}],
};
}
限制和注意事項
設定 Chat 應用程式的連結預覽時,請注意下列限制和注意事項:
- 每個 Chat 應用程式最多支援 5 個網址模式的連結預覽。
- Chat 擴充應用程式會預覽每則訊息中的一個連結。如果單一訊息中有多個可預覽連結,則只有第一個可預覽的連結預覽畫面。
- 即時通訊應用程式只能預覽開頭為
https://
的連結,因此有 https://support.example.com/cases/
預覽畫面,support.example.com/cases/
則不會。
- 除非訊息含有傳送至 Chat 應用程式的其他資訊 (例如斜線指令),否則只有連結網址會透過連結預覽傳送至 Chat 應用程式。
- 附加至預覽連結的資訊卡僅支援
UPDATE_USER_MESSAGE_CARDS
類型的 ActionResponse
,且僅適用於 Chat 應用程式互動事件。連結預覽功能不支援透過 Chat API 更新附加至預覽連結的卡片,因此不支援 UPDATE_MESSAGE
或非同步要求。詳情請參閱更新卡片。
- Chat 擴充應用程式必須預覽聊天室中所有成員的連結,因此
訊息必須省略
privateMessageViewer
] 欄位。
偵錯連結預覽
實作連結預覽時,您可能需要讀取應用程式的記錄檔,對 Chat 應用程式進行偵錯。如要閱讀記錄,請前往 Google Cloud 控制台的記錄檔探索工具。