為了避免使用者在 Google Chat 中分享連結時切換環境,您可以在訊息中附加資訊卡,藉此預覽連結,藉此提供更多資訊,以及讓使用者直接在 Google Chat 中採取行動。
舉例來說,假設 Google Chat 聊天室包含公司所有客服專員,以及一個名為 Case-y 的 Chat 應用程式。服務專員經常在 Chat 聊天室中分享客戶服務案件的連結,而且同事每次進行會議時,都必須開啟案件連結,才能查看指派對象、狀態和主旨等詳細資料。同樣地,如果有人要接管案件擁有權或變更狀態,就必須開啟連結。
連結預覽功能啟用後,聊天室的常駐 Chat 應用程式 Case-y 即可在有人分享案件連結時,附加顯示指派對象、狀態和主旨的資訊卡。卡片上的按鈕可讓服務專員取得案件擁有權,並直接在即時通訊訊息串中變更狀態。
連結預覽的運作方式
有人在訊息中加入連結時,畫面上會顯示方塊,說明 Chat 應用程式可能會預覽連結。
訊息送出後,系統會將連結傳送到 Chat 應用程式,應用程式接著會產生資訊卡,並附加到使用者的訊息中。
連結旁邊的資訊卡則會顯示連結的其他相關資訊,包括按鈕等互動元素。Chat 應用程式可以根據使用者互動 (例如點選按鈕) 更新附加的資訊卡。
如果有人不想讓 Chat 應用程式預覽連結,例如在訊息中附加資訊卡,則可點選預覽方塊上的 cancel 禁止預覽。使用者隨時可以按一下「移除預覽畫面」移除附加的資訊卡。
在 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 聊天室中,如果使用者的訊息中含有符合連結預覽網址模式的連結,您的 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 應用程式可以用簡單的文字訊息回覆,或是附加卡片。
以簡訊回覆
若是簡單的回應,即時通訊應用程式可以使用簡單的文字訊息回覆連結,以預覽連結。這個範例會附加一則訊息,重複顯示符合連結預覽網址模式的連結網址。
附加卡片
如要將資訊卡附加至預覽的連結,請傳回 UPDATE_USER_MESSAGE_CARDS
類型的 ActionResponse
。這個範例附加了簡易資訊卡。
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 卡片服務。
/**
* 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.'};
}
更新卡片
如要更新附加至預覽連結的資訊卡,請傳回 UPDATE_USER_MESSAGE_CARDS
類型的 ActionResponse
。即時通訊應用程式只能更新預覽連結的資訊卡,以回應 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
。做法如下:
更新資訊卡的常見原因是使用者點選按鈕,如要查看上一節的「指派給我」按鈕,請附加卡片。以下完整範例會更新資訊卡,讓系統在使用者點選「指派給我」後將卡片指派給「您」。這個範例會檢查寄件者類型,以動態方式設定 ActionResponse
。
完整範例:Case-y 客戶服務的即時通訊應用程式
以下是 Case-y 的完整程式碼,這是一個 Chat 應用程式,可讓您預覽在客服專員協作的 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 卡片服務。
/**
* 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 應用程式的連結預覽時,請注意下列限制和注意事項:
- 每個即時通訊應用程式最多可支援 5 個網址模式的連結預覽。
- 即時通訊應用程式預覽每則訊息一個連結。如果單一訊息中顯示多個可預覽的連結,則只會顯示第一個可預覽的連結預覽。
- 即時通訊應用程式只能預覽開頭為「
https://
」的連結,因此 https://support.example.com/cases/
會預覽,但 support.example.com/cases/
不會。
- 除非訊息包含傳送至 Chat 應用程式的其他資訊 (例如斜線指令),否則只有連結網址會透過連結預覽傳送至 Chat 應用程式。
- 預覽連結附加的資訊卡僅支援
UPDATE_USER_MESSAGE_CARDS
類型的 ActionResponse
,且只能回應 Chat 應用程式互動事件。透過 Chat API 更新預覽連結中附加的資訊卡時,連結預覽不支援 UPDATE_MESSAGE
或非同步要求。詳情請參閱更新卡片。
偵錯連結預覽
實作連結預覽時,您可能需要讀取 Chat 應用程式的記錄,對 Chat 應用程式進行偵錯。如要讀取記錄檔,請前往 Google Cloud 控制台的記錄檔探索工具。