Para evitar a troca de contexto quando os usuários compartilham um link no Google Chat, seu app Chat pode visualizar o link anexando um card à mensagem com mais informações e permitindo que as pessoas realizem ações diretamente no Google Chat.
Por exemplo, imagine um espaço do Google Chat que inclua todos os agentes de atendimento ao cliente de uma empresa e um app do Chat chamado Case-y. Os agentes costumam compartilhar links para casos de atendimento ao cliente no espaço do Chat, e cada vez que fazem isso, os colegas precisam abrir o link do caso para ver detalhes como responsável, status e assunto. Da mesma forma, se alguém quiser assumir um caso ou mudar o status, é necessário abrir o link.
Com a visualização de links, o app de chat residente do espaço, o Case-y, anexa um card mostrando o atribuidor, o status e o assunto sempre que alguém compartilha um link de caso. Os botões no card permitem que os agentes assumam o caso e mudem o status diretamente do fluxo de chat.
Como funciona a visualização de links
Quando alguém adiciona um link à mensagem, um ícone aparece para informar que um app de chat pode mostrar uma prévia do link.

Depois de enviar a mensagem, o link é enviado ao app Chat, que gera e anexa o card à mensagem do usuário.

Além do link, o card fornece mais informações sobre ele, incluindo elementos interativos, como botões. O app Chat pode atualizar o card anexado em resposta a interações do usuário, como cliques em botões.
Se alguém não quiser que o app Chat mostre uma prévia do link anexando um card à mensagem, é possível impedir isso clicando em no ícone de prévia. Os usuários podem remover o card anexado a qualquer momento clicando em Remover visualização.
Pré-requisitos
HTTP
Um complemento do Google Workspace que estende o Google Chat. Para criar um, conclua o início rápido de HTTP.
Apps Script
Um complemento do Google Workspace que estende o Google Chat. Para criar um, conclua o guia de início rápido do Apps Script.
Configurar prévias de links
Registre links específicos, como example.com, support.example.com e support.example.com/cases/, como padrões de URL na página de configuração do app do Chat no console do Google Cloud para que o app possa visualizá-los.

- Abra o Console do Google Cloud.
- Ao lado de "Google Cloud", clique na seta para baixo e abra o projeto do app Chat.
- No campo de pesquisa, digite
Google Chat APIe clique em API Google Chat. - Clique em Gerenciar > Configuração.
- Em "Visualizações de link", adicione ou edite um padrão de URL.
- Para configurar prévias de link para um novo padrão de URL, clique em Adicionar padrão de URL.
- Para editar a configuração de um padrão de URL, clique na seta para baixo .
No campo Padrão de host, insira o domínio do padrão de URL. O app Chat vai mostrar prévias dos links para esse domínio.
Para que o app Chat mostre uma prévia de links de um subdomínio específico, como
subdomain.example.com, inclua o subdomínio.Para que o app Chat mostre uma prévia dos links de todo o domínio, especifique um caractere curinga com um asterisco (*) como subdomínio. Por exemplo,
*.example.comcorresponde asubdomain.example.comeany.number.of.subdomains.example.com.No campo Prefixo do caminho, insira um caminho a ser anexado ao domínio do padrão de host.
Para corresponder a todos os URLs no domínio do padrão de host, deixe Prefixo do caminho vazio.
Por exemplo, se o padrão de host for
support.example.com, para corresponder aos URLs de casos hospedados emsupport.example.com/cases/, insiracases/.Clique em Concluído.
Clique em Salvar.
Agora, sempre que alguém incluir um link que corresponda a um padrão de URL de prévia de link em uma mensagem em um espaço do Chat que inclua seu app Chat, o app vai mostrar uma prévia do link.
Visualizar um link
Depois de configurar a visualização de links, seu app Chat pode reconhecer e visualizar o link anexando mais informações a ele.
Em espaços do Chat que incluem seu app Chat, quando a mensagem de alguém contém um link que corresponde a um padrão de URL de prévia de link, seu app Chat recebe um objeto de evento com um MessagePayload. No payload, o objeto message.matchedUrl contém o link que o usuário incluiu na mensagem:
JSON
message: { matchedUrl: { url: "https://support.example.com/cases/case123" }, ... // other message attributes redacted } Ao verificar a presença do campo matchedUrl no payload do evento MESSAGE, seu app de chat pode adicionar informações à mensagem com o link visualizado. Seu app do Chat pode responder com uma mensagem de texto básica ou anexar um card.
Responder com uma mensagem de texto
Para respostas básicas, o app do Chat pode mostrar uma prévia de um link respondendo com uma mensagem de texto a um link. Este exemplo anexa uma mensagem que repete o URL do link que corresponde a um padrão de URL de visualização de link.
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 }}}}}; } } Anexar um card que mostra uma prévia do link
Para anexar um card a um link visualizado, retorne a ação DataActions com o objeto ChatDataActionMarkup do tipo UpdateInlinePreviewAction.
No exemplo a seguir, um app do Chat adiciona um card de visualização às mensagens que contêm o padrão 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
Este exemplo envia uma mensagem de card retornando um JSON de card. Você também pode usar o serviço de card do 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'}} }]}} ]}] } }]}}}}; } } Atualizar um card de visualização de link
O app Chat pode atualizar um card de visualização de link quando os usuários interagem com ele, como clicar em um botão no card.
Para atualizar o card, seu app Chat precisa retornar a ação DataActions com um dos seguintes objetos ChatDataActionMarkup:
- Se um usuário enviou a mensagem, retorne um objeto
UpdateMessageAction. - Se o app Chat enviou a mensagem, retorne um objeto
UpdateInlinePreviewAction.
Para determinar quem enviou a mensagem, use o payload do evento (buttonClickedPayload) para verificar se o remetente (message.sender.type) está definido como HUMAN (usuário) ou BOT (app de chat).
O exemplo a seguir mostra como um app de chat atualiza uma prévia de link sempre que um usuário clica no botão Atribuir a mim atualizando o campo Atribuído a do card e desativando o botão.

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
Este exemplo envia uma mensagem de card retornando um JSON de card. Você também pode usar o serviço de card do 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 }}}; } } Limitações e considerações
Ao configurar as prévias de links para seu app do Chat, observe estes limites e considerações:
- Cada app do Chat aceita visualizações de link para até cinco padrões de URL.
- Os apps de chat mostram a prévia de um link por mensagem. Se uma mensagem tiver vários links que podem ser visualizados, apenas o primeiro será mostrado.
- Os apps de chat só mostram prévias de links que começam com
https://. Portanto,https://support.example.com/cases/mostra uma prévia, massupport.example.com/cases/não. - A menos que a mensagem inclua outras informações enviadas ao app Chat, como um comando de barra, apenas o URL do link é enviado ao app Chat pelas prévias de link.
- Se um usuário postar o link, um app do Chat só poderá atualizar o card de visualização do link se os usuários interagirem com ele, por exemplo, clicando em um botão. Não é possível chamar o método
update()da API Chat no recursoMessagepara atualizar a mensagem de um usuário de forma assíncrona. - Os apps de chat precisam mostrar prévias dos links para todos no espaço. Por isso, a mensagem precisa omitir o campo
privateMessageViewer.
Depurar prévias de links
Ao implementar visualizações de link, talvez seja necessário depurar seu app de chat lendo os registros dele. Para ler os registros, acesse o Explorador de registros no console do Google Cloud.