Para evitar el cambio de contexto cuando los usuarios comparten un vínculo en Google Chat, tu app de Chat puede obtener una vista previa del vínculo adjuntando una tarjeta a su mensaje que brinde más información y permita que las personas realicen acciones directamente desde Google Chat.
En Google Chat, los complementos aparecen para los usuarios como apps de Google Chat. Para obtener más información, consulta la descripción general de la extensión de Google Chat.
Por ejemplo, imagina un espacio de Google Chat que incluya a todos los agentes de atención al cliente de una empresa, además de una app de Chat llamada Case-y. Los agentes suelen compartir vínculos a casos de atención al cliente en el espacio de chat y, cada vez que lo hacen, sus colegas deben abrir el vínculo del caso para ver detalles como el asignado, el estado y el asunto. Del mismo modo, si alguien quiere apropiarse de un caso o cambiar el estado, debe abrir el vínculo.
La vista previa de vínculos permite que la app de Chat residente del espacio, Case-y, adjunte una tarjeta que muestre el asignado, el estado y el asunto cada vez que alguien comparta un vínculo del caso. Los botones de la tarjeta permiten a los agentes apropiarse del caso y cambiar el estado directamente desde el flujo de chat.
Cómo funciona la vista previa de vínculos
Cuando alguien agrega un vínculo a su mensaje, aparece un chip que le informa que una app de Chat podría obtener una vista previa del vínculo.
Después de enviar el mensaje, el vínculo se envía a la app de Chat, que luego genera y adjunta la tarjeta al mensaje del usuario.
Junto con el vínculo, la tarjeta proporciona información adicional sobre este, incluidos elementos interactivos, como botones. Tu app de Chat puede actualizar la tarjeta adjunta en respuesta a interacciones del usuario, como clics en botones.
Si alguien no quiere que la app de Chat muestre una vista previa de su vínculo adjuntando una tarjeta a su mensaje, puede hacer clic en
en el chip de vista previa para evitarla. Los usuarios pueden quitar la tarjeta adjunta en cualquier momento haciendo clic en Quitar vista previa.Requisitos previos
Node.js
Un complemento de Google Workspace que extiende Google Chat. Para compilar uno, completa la guía de inicio rápido de HTTP.
Apps Script
Un complemento de Google Workspace que extiende Google Chat. Para compilar una, completa la guía de inicio rápido de Apps Script.
Configura las vistas previas de vínculos
Registra vínculos específicos, como example.com
, support.example.com
y support.example.com/cases/
, como patrones de URL en la página de configuración de tu app de Chat en la consola de Google Cloud para que tu app de Chat pueda obtener una vista previa de ellos.
- Abre Google Cloud Console
- Junto a "Google Cloud", haz clic en la flecha hacia abajo y abre el proyecto de tu app de Chat.
- En el campo de búsqueda, escribe
Google Chat API
y haz clic en API de Google Chat. - Haz clic en Administrar > Configuración.
- En Vistas previas de vínculos, agrega o edita un patrón de URL.
- Para configurar vistas previas de vínculos para un nuevo patrón de URL, haz clic en Agregar patrón de URL.
- Para editar la configuración de un patrón de URL existente, haz clic en la flecha hacia abajo .
En el campo Patrón de host, ingresa el dominio del patrón de URL. La app de Chat obtendrá una vista previa de los vínculos a este dominio.
Para que la app de Chat obtenga una vista previa de los vínculos de un subdominio específico, como
subdomain.example.com
, inclúyelo.Para que la app de Chat obtenga una vista previa de los vínculos de todo el dominio, especifica un carácter comodín con un asterisco (*) como subdominio. Por ejemplo,
*.example.com
coincide consubdomain.example.com
yany.number.of.subdomains.example.com
.En el campo Prefijo de ruta de acceso, ingresa una ruta de acceso para agregar al dominio del patrón de host.
Para que coincidan todas las URLs del dominio del patrón de host, deja el Prefijo de ruta de acceso vacío.
Por ejemplo, si el patrón de host es
support.example.com
, para que coincidan las URLs de los casos alojados ensupport.example.com/cases/
, ingresacases/
.Haz clic en Listo.
Haz clic en Guardar.
Ahora, cada vez que alguien incluya un vínculo que coincida con un patrón de URL de vista previa de vínculo en un mensaje de un espacio de Chat que incluya tu app de Chat, esta mostrará una vista previa del vínculo.
Cómo obtener una vista previa de un vínculo
Después de configurar la vista previa de un vínculo determinado, tu app de Chat puede reconocerlo y obtener una vista previa si le adjuntas más información.
Dentro de los espacios de chat que incluyen tu app de chat, cuando el mensaje de alguien contiene un vínculo que coincide con un patrón de URL de vista previa de vínculo, tu app de chat recibe un objeto de evento con un MessagePayload
. En la carga útil, el objeto message.matchedUrl
contiene el vínculo que el usuario incluyó en el mensaje:
JSON
message: {
matchedUrl: {
url: "https://support.example.com/cases/case123"
},
... // other message attributes redacted
}
Si verificas la presencia del campo matchedUrl
en la carga útil del evento MESSAGE
, tu app de Chat puede agregar información al mensaje con el vínculo que se muestra en la vista previa. La app de Chat puede responder con un mensaje de texto básico o adjuntar una tarjeta.
Cómo responder con un mensaje de texto
En el caso de las respuestas básicas, la app de Chat puede obtener una vista previa de un vínculo respondiendo con un mensaje de texto a un vínculo. En este ejemplo, se adjunta un mensaje que repite la URL del vínculo que coincide con un patrón de URL de vista previa del vínculo.
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
}}}}};
}
}
Adjunta una tarjeta que muestre una vista previa del vínculo
Para adjuntar una tarjeta a un vínculo con vista previa, muestra la acción DataActions
con el objeto ChatDataActionMarkup
de tipo UpdateInlinePreviewAction
.
En el siguiente ejemplo, una app de Chat agrega una tarjeta de vista previa a los mensajes que contienen el patrón de 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 }}
}]}}
]}]
}
}]}}}};
}
}
Apps Script
En este ejemplo, se muestra un mensaje de tarjeta mediante la devolución de un JSON de tarjeta. También puedes usar el servicio de tarjetas de 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'}}
}]}}
]}]
}
}]}}}};
}
}
Actualiza una tarjeta de vista previa de un vínculo
Tu app de Chat puede actualizar una tarjeta de vista previa de vínculo cuando los usuarios interactúan con ella, por ejemplo, cuando hacen clic en un botón de la tarjeta.
Para actualizar la tarjeta, tu app de Chat debe mostrar la acción DataActions
con uno de los siguientes objetos ChatDataActionMarkup
:
- Si un usuario envió el mensaje, muestra un objeto
UpdateMessageAction
. - Si la app de Chat envió el mensaje, muestra un objeto
UpdateInlinePreviewAction
.
Para determinar quién envió el mensaje, usa la carga útil del evento (buttonClickedPayload
) para verificar si el remitente (message.sender.type
) está configurado como HUMAN
(usuario) o BOT
(app de Chat).
En el siguiente ejemplo, se muestra cómo una app de chat actualiza una vista previa de un vínculo cada vez que un usuario hace clic en el botón Asignarme. Para ello, actualiza el campo Destinatario de la tarjeta y lo inhabilita.
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
En este ejemplo, se muestra un mensaje de tarjeta mediante la devolución de JSON de la tarjeta. También puedes usar el servicio de tarjetas de 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 }}};
}
}
Límites y consideraciones
Cuando configures las vistas previas de vínculos para tu app de Chat, ten en cuenta estos límites y consideraciones:
- Cada app de Chat admite vistas previas de vínculos para hasta 5 patrones de URL.
- Las apps de chat muestran una vista previa de un vínculo por mensaje. Si hay varios vínculos con vista previa en un solo mensaje, solo se muestra la vista previa del primero.
- Las apps de chat solo muestran una vista previa de los vínculos que comienzan con
https://
, por lo quehttps://support.example.com/cases/
muestra una vista previa, perosupport.example.com/cases/
no. - A menos que el mensaje incluya otra información que se envíe a la app de Chat, como un comando de barra, solo la URL del vínculo se envía a la app de Chat a través de las vistas previas de vínculos.
- Si un usuario publica el vínculo, una app de Chat solo puede actualizar la tarjeta de vista previa del vínculo si los usuarios interactúan con ella, por ejemplo, haciendo clic en un botón. No puedes llamar al método
update()
de la API de Chat en el recursoMessage
para actualizar el mensaje de un usuario de forma asíncrona. - Las apps de chat deben obtener una vista previa de los vínculos para todos los usuarios del espacio, por lo que el mensaje debe omitir el campo
privateMessageViewer
.
Cómo depurar vistas previas de vínculos
A medida que implementes las vistas previas de vínculos, es posible que debas depurar tu app de Chat leyendo los registros de la app. Para leer los registros, visita el Explorador de registros en la consola de Google Cloud.