Чтобы предотвратить переключение контекста, когда пользователи делятся ссылкой в Google Chat, ваше приложение Chat может предварительно просмотреть ссылку, прикрепив к их сообщению карточку, которая дает дополнительную информацию и позволяет людям совершать действия прямо из Google Chat.
В Google Chat дополнения отображаются пользователям как приложения Google Chat. Дополнительную информацию см. в обзоре расширения Google Chat .
Например, представьте себе пространство Google Chat, включающее всех агентов по обслуживанию клиентов компании, а также приложение Chat под названием Case-y. Агенты часто делятся ссылками на обращения в службу поддержки клиентов в чате, и каждый раз, когда они это делают, их коллегам приходится открывать ссылку на обращение, чтобы просмотреть такие подробности, как правопреемник, статус и тема. Аналогично, если кто-то хочет взять на себя ответственность за обращение или изменить его статус, ему необходимо открыть ссылку.
Предварительный просмотр ссылки позволяет резидентному приложению чата пространства Case-y прикреплять карточку с указанием правопреемника, статуса и темы всякий раз, когда кто-то делится ссылкой на обращение. Кнопки на карточке позволяют агентам взять на себя ответственность за обращение и изменить статус непосредственно из потока чата.
Как работает предварительный просмотр ссылок
Когда кто-то добавляет ссылку в свое сообщение, появляется метка, сообщающая ему, что приложение чата может просмотреть ссылку.
После отправки сообщения ссылка отправляется в приложение «Чат», которое затем генерирует и прикрепляет карточку к сообщению пользователя.
Помимо ссылки, карточка предоставляет дополнительную информацию о ссылке, включая интерактивные элементы, такие как кнопки. Ваше приложение Chat может обновлять прикрепленную карточку в ответ на действия пользователя, например нажатия кнопок.
Если кто-то не хочет, чтобы приложение Chat просматривало его ссылку, прикрепив карточку к сообщению, он может запретить предварительный просмотр, нажав
на чипе предварительного просмотра. Пользователи могут удалить прикрепленную карту в любое время, нажав «Удалить предварительный просмотр» .Предварительные условия
Node.js
Надстройка Google Workspace, расширяющая Google Chat. Чтобы построить один, завершите HTTP QuickStart .
Скрипт приложений
Надстройка Google Workspace, расширяющая Google Chat. Чтобы создать его, выполните краткое руководство по Apps Script .
Настройка предварительного просмотра ссылок
Зарегистрируйте определенные ссылки, такие как example.com
, support.example.com
и support.example.com/cases/
, в качестве шаблонов URL-адресов на странице конфигурации вашего приложения Chat в консоли Google Cloud, чтобы ваше приложение Chat могло их просмотреть.
- Откройте Google Cloud Console .
- Рядом с надписью «Google Cloud» нажмите стрелку и откройте проект приложения Chat.
- В поле поиска введите
Google Chat API
и нажмите Google Chat API . - Нажмите «Управление» > «Конфигурация» .
- В разделе «Предварительный просмотр ссылок» добавьте или измените шаблон URL-адреса.
- Чтобы настроить предварительный просмотр ссылок для нового шаблона URL-адреса, нажмите «Добавить шаблон URL-адреса» .
- Чтобы изменить конфигурацию существующего шаблона URL-адреса, нажмите стрелку вниз .
В поле Шаблон хоста введите домен шаблона URL-адреса. Приложение Chat будет просматривать ссылки на этот домен.
Чтобы иметь ссылки предварительного просмотра приложения Chat для определенного субдомена, например
subdomain.example.com
, включите субдомен.Чтобы иметь ссылки на предварительный просмотр приложения Chat для всего домена, укажите в качестве поддомена подстановочный знак со звездочкой (*). Например,
*.example.com
соответствуетsubdomain.example.com
иany.number.of.subdomains.example.com
.В поле Префикс пути введите путь для добавления к домену шаблона хоста.
Чтобы сопоставить все URL-адреса в домене шаблона узла, оставьте префикс пути пустым.
Например, если шаблон хоста —
support.example.com
, чтобы сопоставить URL-адреса обращений, размещенных по адресуsupport.example.com/cases/
, введитеcases/
.Нажмите Готово .
Нажмите Сохранить .
Теперь, когда кто-то добавляет ссылку, соответствующую шаблону URL-адреса предварительного просмотра ссылки, на сообщение в пространстве чата, которое включает ваше приложение Chat, ваше приложение просматривает ссылку.
Предварительный просмотр ссылки
После того как вы настроите предварительный просмотр для конкретной ссылки, ваше приложение Chat сможет распознать и просмотреть ссылку, прикрепив к ней дополнительную информацию.
Внутри пространств Chat, включающих ваше приложение Chat, когда чье-либо сообщение содержит ссылку, соответствующую шаблону URL-адреса предварительного просмотра ссылки, ваше приложение Chat получает объект события с MessagePayload
. В полевой нагрузке объект message.matchedUrl
содержит ссылку, которую пользователь включил в сообщение:
JSON
message: {
matchedUrl: {
url: "https://support.example.com/cases/case123"
},
... // other message attributes redacted
}
Проверив наличие поля matchedUrl
в полезных данных события MESSAGE
, ваше приложение чата может добавить информацию в сообщение с предварительно просмотренной ссылкой. Ваше приложение в чате может либо ответить с основным текстовым сообщением, либо прикрепить карту.
Ответить текстовым сообщением
Для базовых ответов ваше приложение для чата может предварительно просмотреть ссылку, отвечая на текстовое сообщение на ссылку. Этот пример прикрепляет сообщение, которое повторяет URL -адрес ссылки, который соответствует шаблону URL -адреса предварительного просмотра ссылки.
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
}}}}};
}
}
Скрипт приложений
/**
* 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
}}}}};
}
}
Прикрепите карточку с предварительным просмотром ссылки
Чтобы прикрепить карту к предварительно просмотренной ссылке, верните DataActions
Action с помощью объекта ChatDataActionMarkup
Type UpdateInlinePreviewAction
.
В следующем примере приложение Chat добавляет карточку предварительного просмотра к сообщениям, содержащим шаблон URL-адреса 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 }}
}]}}
]}]
}
}]}}}};
}
}
Скрипт приложений
В этом примере отправляется карточное сообщение, возвращая card JSON . You can also use the Apps Script card service .
/**
* 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 может обновлять карточку предварительного просмотра ссылки, когда пользователи взаимодействуют с ней, например нажимают кнопку на карточке.
Чтобы обновить карточку, ваше приложение чата должно вернуть действие DataActions
с одним из следующих объектов ChatDataActionMarkup
:
- Если пользователь отправил сообщение, верните объект
UpdateMessageAction
. - Если приложение Chat отправило сообщение, верните объект
UpdateInlinePreviewAction
.
Чтобы определить, кто отправил сообщение, используйте полезные данные события ( buttonClickedPayload
), чтобы проверить, установлен ли отправитель ( message.sender.type
) HUMAN
(пользователь) или BOT
(приложение чата).
В следующем примере показано, как приложение чата обновляет предварительный просмотр ссылки каждый раз, когда пользователь нажимает кнопку «Назначить мне» , обновляя поле «Назначенный» карты и отключая кнопку.
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 }}};
}
}
Скрипт приложений
В этом примере отправляется карточное сообщение, возвращая 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 обратите внимание на следующие ограничения и рекомендации:
- Каждое приложение чата поддерживает предварительный просмотр ссылок до 5 шаблонов URL-адресов.
- Приложения чата просматривают одну ссылку на каждое сообщение. Если в одном сообщении присутствует несколько доступных для предварительного просмотра ссылок, отображается только первая доступная для предварительного просмотра ссылка.
- Приложения чата просматривают только ссылки, начинающиеся с
https://
, поэтомуhttps://support.example.com/cases/
являются предварительным просмотром, аsupport.example.com/cases/
нет. - Если сообщение не содержит другую информацию, которая отправляется в приложение Chat, например косую черту , в приложение Chat при предварительном просмотре отправляется только URL-адрес ссылки.
- Если пользователь публикует ссылку, приложение чата может обновить карточку предварительного просмотра ссылки только в том случае, если пользователи взаимодействуют с карточкой, например при нажатии кнопки. Вы не можете вызвать метод
update()
API Chat для ресурсаMessage
, чтобы асинхронно обновить сообщение пользователя. - Приложения чата должны просматривать ссылки для всех в пространстве, поэтому в сообщении должно быть опущено поле
privateMessageViewer
.
Предварительный просмотр ссылок отладки
При реализации предварительного просмотра ссылок вам может потребоваться отладка приложения Chat, прочитав журналы приложения. Чтобы прочитать журналы, посетите Logs Explorer в консоли Google Cloud.