Visualizzare l'anteprima dei link nei messaggi di Google Chat

Per impedire il cambio di contesto quando gli utenti condividono un link in Google Chat, l'app Chat può anteprime il link allegando al messaggio una scheda che fornisce maggiori informazioni e consente alle persone di intervenire direttamente da Google Chat.

In Google Chat, i componenti aggiuntivi vengono visualizzati dagli utenti come app Google Chat. Per saperne di più, consulta la panoramica di Estensione di Google Chat.

Ad esempio, immagina uno spazio di Google Chat che includa tutti gli agenti dell'assistenza clienti di un'azienda, oltre a un'app di Chat denominata Case-y. Gli agenti condividono spesso i link alle richieste di assistenza clienti nello spazio di Chat e ogni volta che lo fanno i colleghi devono aprire il link della richiesta per visualizzare dettagli come assegnatario, stato e oggetto. Allo stesso modo, se un utente vuole acquisire la proprietà di una richiesta o modificarne lo stato, deve aprire il link.

L'anteprima dei link consente all'app di chat residente dello spazio, Case-y, di allegare una scheda che mostra l'assegnatario, lo stato e l'oggetto ogni volta che qualcuno condivide un link alla richiesta. I pulsanti sulla scheda consentono agli agenti di acquisire la proprietà della richiesta e di modificarne lo stato direttamente dallo stream di chat.

Quando un utente aggiunge un link al proprio messaggio, viene visualizzato un chip che lo informa che un'app di chat potrebbe visualizzare l'anteprima del link.

Chip che indica che un'app di chat potrebbe visualizzare l'anteprima di un link

Dopo l'invio del messaggio, il link viene inviato all'app Chat, che genera e allega la scheda al messaggio dell'utente.

App Chat che mostra l'anteprima di un link allegando una scheda al messaggio

Oltre al link, la scheda fornisce ulteriori informazioni sul link, inclusi elementi interattivi come i pulsanti. L'app Chat può aggiornare la scheda allegata in risposta alle interazioni dell'utente, ad esempio i clic sui pulsanti.

Se un utente non vuole che l'app Chat mostri l'anteprima del suo link allegando una scheda al messaggio, può impedire la visualizzazione facendo clic su sul chip di anteprima. Gli utenti possono rimuovere la scheda allegata in qualsiasi momento facendo clic su Rimuovi anteprima.

Prerequisiti

Node.js

Un componente aggiuntivo di Google Workspace che espande Google Chat. Per crearne uno, compila la guida rapida HTTP.

Apps Script

Un componente aggiuntivo di Google Workspace che espande Google Chat. Per crearne uno, compila la guida rapida di Apps Script.

Registra link specifici, come example.com, support.example.com e support.example.com/cases/, come pattern URL nella pagina di configurazione della tua app Chat nella console Google Cloud in modo che la tua app Chat possa visualizzarne l'anteprima.

Menu di configurazione delle anteprime link

  1. Apri la console Google Cloud.
  2. Accanto a "Google Cloud", fai clic sulla Freccia giù e apri il progetto dell'app Chat.
  3. Nel campo di ricerca, digita Google Chat API e fai clic su API Google Chat.
  4. Fai clic su Gestisci > Configurazione.
  5. In Anteprime link, aggiungi o modifica un pattern URL.
    1. Per configurare le anteprime dei link per un nuovo pattern URL, fai clic su Aggiungi pattern URL.
    2. Per modificare la configurazione di un pattern URL esistente, fai clic sulla Freccia giù .
  6. Nel campo Pattern host, inserisci il dominio del pattern URL. L'app Chat mostrerà l'anteprima dei link a questo dominio.

    Per fare in modo che l'app Chat mostri l'anteprima dei link per un sottodominio specifico, come subdomain.example.com, includilo.

    Per fare in modo che l'app Chat mostri l'anteprima dei link per l'intero dominio, specifica un carattere jolly con un asterisco (*) come sottodominio. Ad esempio, *.example.com corrisponde a subdomain.example.com e any.number.of.subdomains.example.com.

  7. Nel campo Prefisso del percorso, inserisci un percorso da aggiungere al dominio del pattern host.

    Per trovare tutte le corrispondenze per tutti gli URL nel dominio del pattern host, lascia vuoto il campo Prefisso del percorso.

    Ad esempio, se il pattern host è support.example.com, per trovare una corrispondenza per gli URL delle richieste ospitate su support.example.com/cases/, inserisci cases/.

  8. Fai clic su Fine.

  9. Fai clic su Salva.

Ora, ogni volta che qualcuno include un link che corrisponde a un pattern di URL di anteprima del link in un messaggio di uno spazio di Chat che include la tua app Chat, l'app mostra l'anteprima del link.

Dopo aver configurato l'anteprima dei link per un determinato link, l'app Chat può riconoscerlo e visualizzarne l'anteprima associandovi ulteriori informazioni.

Negli spazi di Chat che includono la tua app Chat, quando il messaggio di un utente contiene un link che corrisponde a un pattern URL di anteprima del link, l'app Chat riceve un oggetto evento con un valore MessagePayload. Nel payload, l'oggetto message.matchedUrl contiene il link incluso dall'utente nel messaggio:

JSON

message: {
  matchedUrl: {
    url: "https://support.example.com/cases/case123"
  },
  ... // other message attributes redacted
}

Controllando la presenza del campo matchedUrl nel payload dell'evento MESSAGE, l'app Chat può aggiungere informazioni al messaggio con il link visualizzato in anteprima. L'app Chat può rispondere con un messaggio di testo di base o allegare una scheda.

Rispondere con un messaggio

Per le risposte di base, l'app Chat può visualizzare l'anteprima di un link rispondendo con un messaggio di testo a un link. Questo esempio allega un messaggio che ripete l'URL del link corrispondente a un pattern di URL di anteprima del 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
    }}}}};
  }
}

Per allegare una scheda a un link visualizzato in anteprima, restituire l'azione DataActions con l'oggetto ChatDataActionMarkup di tipo UpdateInlinePreviewAction.

Nell'esempio seguente, un'app di Chat aggiunge una scheda di anteprima ai messaggi che contengono il pattern di URL support.example.com.

App Chat che mostra l'anteprima di un link allegando una scheda al messaggio

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

Questo esempio invia un messaggio della scheda restituendo JSON della scheda. Puoi anche utilizzare il servizio di schede di 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'}}
        }]}}
        ]}]
      }
    }]}}}};
  }
}

L'app Chat può aggiornare una scheda di anteprima del link quando gli utenti interagiscono con essa, ad esempio facendo clic su un pulsante nella scheda.

Per aggiornare la scheda, l'app Chat deve restituire l'azione DataActions con uno dei seguenti oggetti ChatDataActionMarkup:

Per determinare chi ha inviato il messaggio, utilizza il payload dell'evento (buttonClickedPayload) per verificare se il mittente (message.sender.type) è impostato su HUMAN (utente) o BOT (app di chat).

L'esempio seguente mostra come un'app di chat aggiorna un'anteprima del link ogni volta che un utente fa clic sul pulsante Assegna a me aggiornando il campo Assegnatario della scheda e disattivando il pulsante.

App Chat che mostra l'anteprima di un link con una versione aggiornata di una scheda allegata a un messaggio

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

Questo esempio invia un messaggio della scheda restituendo JSON della scheda. Puoi anche utilizzare il servizio di schede di 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 }}};
  }
}

Limiti e considerazioni

Quando configuri le anteprime dei link per la tua app Chat, tieni conto di questi limiti e considerazioni:

  • Ogni app Chat supporta le anteprime dei link per un massimo di 5 pattern di URL.
  • Le app di chat mostrano l'anteprima di un link per messaggio. Se in un singolo messaggio sono presenti più link visualizzabili come anteprima, viene visualizzata solo l'anteprima del primo.
  • Le app di chat mostrano l'anteprima solo dei link che iniziano con https://, quindi https://support.example.com/cases/ viene visualizzato, ma support.example.com/cases/ no.
  • A meno che il messaggio non includa altre informazioni che vengono inviate all'app Chat, come un comando barra, solo l'URL del link viene inviato all'app Chat tramite le anteprime dei link.
  • Se un utente pubblica il link, un'app di chat può aggiornare la scheda di anteprima del link solo se gli utenti interagiscono con la scheda, ad esempio facendo clic su un pulsante. Non puoi chiamare il metodo update() dell'API Chat sulla risorsa Message per aggiornare in modo asincrono il messaggio di un utente.
  • Le app di chat devono mostrare l'anteprima dei link per tutti i membri dello spazio, pertanto il messaggio deve omettere il campo privateMessageViewer.

Quando implementi le anteprime dei link, potresti dover eseguire il debug della tua app Chat leggendo i relativi log. Per leggere i log, visita Esplora log nella console Google Cloud.