Prévisualiser les liens dans les messages Google Chat

suivant suivant suivant

Pour éviter le changement de contexte lorsque les utilisateurs partagent un lien dans Google Chat, votre application Chat peut afficher un aperçu du lien en joignant une fiche à leur message. Cette fiche fournit plus d'informations et permet aux utilisateurs d'effectuer des actions directement depuis Google Chat.

Dans Google Chat, les modules complémentaires apparaissent aux utilisateurs comme des applications Google Chat. Pour en savoir plus, consultez la présentation de l'extension Google Chat.

Par exemple, imaginez un espace Google Chat qui inclut tous les agents du service client d'une entreprise, ainsi qu'une application Chat appelée Case-y. Les agents partagent fréquemment des liens vers des demandes de service client dans l'espace Chat. Chaque fois qu'ils le font, leurs collègues doivent ouvrir le lien de la demande pour voir des informations telles que l'agent responsable, l'état et l'objet. De même, si quelqu'un souhaite prendre en charge une demande ou modifier son état, il doit ouvrir le lien.

L'aperçu des liens permet à l'application Chat de l'espace, Case-y, d'ajouter une fiche indiquant le responsable, l'état et l'objet chaque fois qu'un utilisateur partage un lien vers une demande. Les boutons de la fiche permettent aux agents de prendre en charge la demande et de modifier son état directement depuis le flux de chat.

Lorsqu'un utilisateur ajoute un lien à son message, un chip s'affiche pour l'informer qu'une application Chat peut prévisualiser le lien.

Chip indiquant qu'une application Chat peut prévisualiser un lien

Après l'envoi du message, le lien est envoyé à l'application Chat, qui génère et joint la fiche au message de l'utilisateur.

Application Chat prévisualisant un lien en joignant une fiche au message

À côté du lien, la fiche fournit des informations supplémentaires sur celui-ci, y compris des éléments interactifs tels que des boutons. Votre application Chat peut mettre à jour la fiche jointe en réponse aux interactions de l'utilisateur, comme les clics sur un bouton.

Si un utilisateur ne souhaite pas que l'application Chat prévisualise son lien en joignant une fiche à son message, il peut empêcher la prévisualisation en cliquant sur  sur le chip d'aperçu. Les utilisateurs peuvent supprimer la fiche jointe à tout moment en cliquant sur Supprimer l'aperçu.

Prérequis

Node.js

Module complémentaire Google Workspace qui étend Google Chat. Pour en créer un, suivez le guide de démarrage rapide HTTP.

Apps Script

Module complémentaire Google Workspace qui étend Google Chat. Pour en créer un, suivez le guide de démarrage rapide Apps Script.

Enregistrez des liens spécifiques (comme example.com, support.example.com et support.example.com/cases/) en tant que modèles d'URL sur la page de configuration de votre application Chat dans la console Google Cloud afin qu'elle puisse les prévisualiser.

Menu de configuration des aperçus de lien

  1. Ouvrez Google Cloud Console.
  2. À côté de "Google Cloud", cliquez sur la flèche vers le bas , puis ouvrez le projet de votre application Chat.
  3. Dans le champ de recherche, saisissez Google Chat API, puis cliquez sur API Google Chat.
  4. Cliquez sur Gérer > Configuration.
  5. Sous "Aperçus des liens", ajoutez ou modifiez un format d'URL.
    1. Pour configurer des aperçus de lien pour un nouveau format d'URL, cliquez sur Ajouter un format d'URL.
    2. Pour modifier la configuration d'un format d'URL existant, cliquez sur la flèche vers le bas .
  6. Dans le champ Host pattern (Modèle d'hôte), saisissez le domaine du format d'URL. L'application Chat prévisualisera les liens vers ce domaine.

    Pour que l'application Chat prévisualise les liens pour un sous-domaine spécifique, comme subdomain.example.com, incluez le sous-domaine.

    Pour que l'application Chat prévisualise les liens pour l'ensemble du domaine, spécifiez un caractère générique avec un astérisque (*) comme sous-domaine. Par exemple, *.example.com correspond à subdomain.example.com et any.number.of.subdomains.example.com.

  7. Dans le champ Préfixe de chemin, saisissez un chemin à ajouter au domaine du format d'hôte.

    Pour faire correspondre toutes les URL du domaine du format d'hôte, laissez Préfixe de chemin vide.

    Par exemple, si le format d'hôte est support.example.com, saisissez cases/ pour faire correspondre les URL des demandes hébergées sur support.example.com/cases/.

  8. Cliquez sur OK.

  9. Cliquez sur Enregistrer.

Désormais, chaque fois qu'un utilisateur inclut un lien correspondant à un format d'URL d'aperçu de lien dans un message d'un espace Chat incluant votre application Chat, votre application prévisualise le lien.

Une fois que vous avez configuré la prévisualisation des liens pour un lien donné, votre application Chat peut le reconnaître et en prévisualiser le contenu en y joignant plus d'informations.

Dans les espaces Chat qui incluent votre application Chat, lorsque le message d'un utilisateur contient un lien correspondant à un format d'URL d'aperçu de lien, votre application Chat reçoit un objet d'événement avec un MessagePayload. Dans la charge utile, l'objet message.matchedUrl contient le lien que l'utilisateur a inclus dans le message:

JSON

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

En vérifiant la présence du champ matchedUrl dans la charge utile de l'événement MESSAGE, votre application Chat peut ajouter des informations au message avec le lien prévisualisé. Votre application Chat peut répondre par un message texte de base ou joindre une fiche.

Répondre par un message

Pour les réponses de base, votre application Chat peut prévisualiser un lien en répondant à un lien par un message texte. Cet exemple joint un message qui répète l'URL du lien correspondant à un format d'URL d'aperçu de lien.

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
    }}}}};
  }
}

Pour joindre une fiche à un lien prévisualisé, renvoyez l'action DataActions avec l'objet ChatDataActionMarkup de type UpdateInlinePreviewAction.

Dans l'exemple suivant, une application Chat ajoute une fiche d'aperçu aux messages contenant le modèle d'URL support.example.com.

Application Chat prévisualisant un lien en joignant une fiche au message

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

Cet exemple envoie un message de carte en renvoyant un fichier JSON de carte. Vous pouvez également utiliser le service de carte 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'}}
        }]}}
        ]}]
      }
    }]}}}};
  }
}

Votre application Chat peut mettre à jour une fiche d'aperçu de lien lorsque les utilisateurs interagissent avec elle, par exemple en cliquant sur un bouton de la fiche.

Pour mettre à jour la fiche, votre application Chat doit renvoyer l'action DataActions avec l'un des objets ChatDataActionMarkup suivants:

Pour déterminer qui a envoyé le message, utilisez la charge utile de l'événement (buttonClickedPayload) pour vérifier si l'expéditeur (message.sender.type) est défini sur HUMAN (utilisateur) ou BOT (application Chat).

L'exemple suivant montre comment une application Chat met à jour un aperçu de lien chaque fois qu'un utilisateur clique sur le bouton M'attribuer en mettant à jour le champ Affectation de la fiche et en désactivant le bouton.

Application Chat prévisualisant un lien avec une version mise à jour d'une fiche jointe à un message

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

Cet exemple envoie un message de carte en renvoyant un fichier JSON de carte. Vous pouvez également utiliser le service de carte 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 }}};
  }
}

Limites et considérations

Lorsque vous configurez des aperçus de liens pour votre application Chat, tenez compte des limites et des considérations suivantes:

  • Chaque application Chat prend en charge les aperçus de liens pour un maximum de cinq modèles d'URL.
  • Les applications Chat prévisualisent un lien par message. Si plusieurs liens pouvant être prévisualisés sont présents dans un même message, seul le premier est prévisualisé.
  • Les applications de chat n'affichent que les liens commençant par https://. https://support.example.com/cases/ est donc prévisualisé, mais support.example.com/cases/ ne l'est pas.
  • Sauf si le message inclut d'autres informations envoyées à l'application Chat, comme une commande à barre oblique, seule l'URL du lien est envoyée à l'application Chat par les aperçus de lien.
  • Si un utilisateur publie le lien, une application Chat ne peut mettre à jour la fiche d'aperçu du lien que si les utilisateurs interagissent avec la fiche, par exemple en cliquant sur un bouton. Vous ne pouvez pas appeler la méthode update() de l'API Chat sur la ressource Message pour mettre à jour le message d'un utilisateur de manière asynchrone.
  • Les applications de chat doivent prévisualiser les liens pour tous les membres de l'espace. Le message doit donc omettre le champ privateMessageViewer.

Lorsque vous implémentez des aperçus de lien, vous devrez peut-être déboguer votre application Chat en lisant ses journaux. Pour lire les journaux, accédez à l'explorateur de journaux dans la console Google Cloud.