Vorschau von Links in Google Chat-Nachrichten

Damit Nutzer nicht den Kontext wechseln müssen, wenn sie einen Link in Google Chat teilen, kann Ihre Chat-App eine Vorschau des Links anzeigen, indem sie ihrer Nachricht eine Karte anhängt, die weitere Informationen enthält und es Nutzern ermöglicht, direkt in Google Chat Aktionen auszuführen.

Stellen Sie sich beispielsweise einen Google Chat-Bereich vor, der alle Kundenservicemitarbeiter eines Unternehmens sowie eine Chat-App namens Case-y enthält. Kundenservicemitarbeiter teilen häufig Links zu Kundenservicefällen im Chat-Bereich. Jedes Mal, wenn sie das tun, müssen ihre Kollegen den Fall-Link öffnen, um Details wie den zugewiesenen Mitarbeiter, den Status und den Betreff zu sehen. Wenn jemand die Inhaberschaft für einen Fall übernehmen oder den Status ändern möchte, muss er den Link öffnen.

Mit der Linkvorschau kann die in diesem Bereich verwendete Chat-App Case-y eine Karte mit dem zugewiesenen Nutzer, dem Status und dem Betreff anhängen, wenn jemand einen Fall-Link teilt. Über die Schaltflächen auf der Karte können Kundenservicemitarbeiter den Fall übernehmen und den Status direkt im Chat ändern.

Wenn jemand einen Link in seine Nachricht einfügt, wird ein Chip angezeigt, der ihn darüber informiert, dass eine Chat-App möglicherweise eine Vorschau des Links anzeigt.

Chip, der angibt, dass eine Chat-App möglicherweise eine Vorschau eines Links anzeigt

Nach dem Senden der Nachricht wird der Link an die Chat-App gesendet, die dann die Karte generiert und an die Nachricht des Nutzers anhängt.

Chat-App, die eine Vorschau eines Links durch Anhängen einer Karte an die Nachricht anzeigt

Neben dem Link enthält die Karte zusätzliche Informationen zum Link, darunter interaktive Elemente wie Schaltflächen. Ihre Chat-App kann die angehängte Karte als Reaktion auf Nutzerinteraktionen wie Schaltflächenklicks aktualisieren.

Wenn ein Nutzer nicht möchte, dass die Chat App eine Vorschau seines Links erstellt, indem sie eine Karte an seine Nachricht anhängt, kann er die Vorschau verhindern, indem er auf dem Vorschau-Chip auf  klickt. Nutzer können die angehängte Karte jederzeit entfernen, indem sie auf Vorschau entfernen klicken.

Vorbereitung

HTTP

Ein Google Workspace-Add‑on, das Google Chat erweitert. HTTP-Schnellstart

Apps Script

Ein Google Workspace-Add‑on, das Google Chat erweitert. Wenn Sie ein solches Tool erstellen möchten, folgen Sie der Apps Script-Kurzanleitung.

Registrieren Sie bestimmte Links wie example.com, support.example.com und support.example.com/cases/ als URL-Muster auf der Konfigurationsseite Ihrer Chat-App in der Google Cloud Console, damit Ihre Chat-App sie in der Vorschau anzeigen kann.

Konfigurationsmenü für Linkvorschauen

  1. Öffnen Sie die Google Cloud Console.
  2. Klicken Sie neben „Google Cloud“ auf den Abwärtspfeil  und öffnen Sie das Projekt Ihrer Chat-App.
  3. Geben Sie im Suchfeld Google Chat API ein und klicken Sie auf Google Chat API.
  4. Klicken Sie auf Verwalten > Konfiguration.
  5. Fügen Sie unter „Linkvorschauen“ ein URL-Muster hinzu oder bearbeiten Sie ein vorhandenes.
    1. Wenn Sie Linkvorschauen für ein neues URL-Muster konfigurieren möchten, klicken Sie auf URL-Muster hinzufügen.
    2. Wenn Sie die Konfiguration für ein vorhandenes URL-Muster bearbeiten möchten, klicken Sie auf den Abwärtspfeil .
  6. Geben Sie im Feld Host pattern (Hostmuster) die Domain des URL-Musters ein. Die Chat-App zeigt eine Vorschau von Links zu dieser Domain an.

    Wenn die Chat-App Links für eine bestimmte Subdomain wie subdomain.example.com in der Vorschau anzeigen soll, geben Sie die Subdomain an.

    Wenn die Chat App Links für die gesamte Domain in der Vorschau anzeigen soll, geben Sie ein Platzhalterzeichen mit einem Sternchen (*) als Subdomain an. Beispielsweise führt *.example.com zu Übereinstimmungen mit subdomain.example.com und any.number.of.subdomains.example.com.

  7. Geben Sie im Feld Pfadpräfix einen Pfad ein, der an die Domain des Hostmusters angehängt werden soll.

    Wenn alle URLs in der Domain des Hostmusters abgeglichen werden sollen, lassen Sie das Feld Pfadpräfix leer.

    Wenn das Hostmuster beispielsweise support.example.com lautet und Sie URLs für Fälle abgleichen möchten, die unter support.example.com/cases/ gehostet werden, geben Sie cases/ ein.

  8. Klicken Sie auf Fertig.

  9. Klicken Sie auf Speichern.

Wenn jemand einen Link in eine Nachricht in einem Chatbereich einfügt, der Ihrer Chat-App entspricht, und der Link einem URL-Muster für Linkvorschauen entspricht, wird der Link von Ihrer App in der Vorschau angezeigt.

Nachdem Sie die Linkvorschau für einen bestimmten Link konfiguriert haben, kann Ihre Chat-App den Link erkennen und eine Vorschau davon anzeigen, indem sie weitere Informationen daran anhängt.

Wenn in Chatbereichen, die Ihre Chat-App enthalten, die Nachricht eines Nutzers einen Link enthält, der mit einem URL-Muster für die Linkvorschau übereinstimmt, empfängt Ihre Chat-App ein Ereignisobjekt mit einem MessagePayload. In der Nutzlast enthält das Objekt message.matchedUrl den Link, den der Nutzer in die Nachricht eingefügt hat:

JSON

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

Wenn Ihre Chat-App in der Nutzlast des MESSAGE-Ereignisses nach dem Feld matchedUrl sucht, kann sie der Nachricht mit dem Link in der Vorschau Informationen hinzufügen. Ihre Chat-App kann entweder mit einer einfachen Textnachricht antworten oder eine Karte anhängen.

Mit einer SMS antworten

Bei einfachen Antworten kann Ihre Chat-App eine Vorschau eines Links anzeigen, indem sie mit einer Textnachricht auf einen Link antwortet. In diesem Beispiel wird eine Nachricht angehängt, in der die Link-URL wiederholt wird, die einem URL-Muster für die Linkvorschau entspricht.

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

Wenn Sie einem Link mit Vorschau eine Karte anhängen möchten, geben Sie die Aktion DataActions mit dem ChatDataActionMarkup-Objekt vom Typ UpdateInlinePreviewAction zurück.

Im folgenden Beispiel fügt eine Chat-App Nachrichten, die das URL-Muster support.example.com enthalten, eine Vorschaukarte hinzu.

Chat-App, die eine Vorschau eines Links durch Anhängen einer Karte an die Nachricht anzeigt

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

In diesem Beispiel wird eine Kartenmitteilung gesendet, indem Karten-JSON zurückgegeben wird. Sie können auch den Apps Script-Kartendienst verwenden.

/**
 * 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'}}
        }]}}
        ]}]
      }
    }]}}}};
  }
}

Ihre Chat-App kann eine Linkvorschaukarten aktualisieren, wenn Nutzer damit interagieren, z. B. auf eine Schaltfläche auf der Karte klicken.

Damit die Karte aktualisiert werden kann, muss Ihre Chat-App die Aktion DataActions mit einem der folgenden ChatDataActionMarkup-Objekte zurückgeben:

Um festzustellen, wer die Nachricht gesendet hat, prüfen Sie in der Ereignis-Payload (buttonClickedPayload), ob der Absender (message.sender.type) auf HUMAN (Nutzer) oder BOT (Chat-App) festgelegt ist.

Im folgenden Beispiel wird gezeigt, wie eine Chat-App eine Linkvorschau aktualisiert, wenn ein Nutzer auf die Schaltfläche Mir zuweisen klickt. Dazu wird das Feld Assignee der Karte aktualisiert und die Schaltfläche deaktiviert.

Chat-App, in der ein Link mit einer aktualisierten Version einer Karte in einer Nachricht angezeigt wird

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

In diesem Beispiel wird eine Kartenmitteilung gesendet, indem Karten-JSON zurückgegeben wird. Sie können auch den Apps Script-Kartendienst verwenden.

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

Einschränkungen und Überlegungen

Beachten Sie beim Konfigurieren von Linkvorschauen für Ihre Chat-App die folgenden Einschränkungen und Überlegungen:

  • Jede Chat-App unterstützt Linkvorschauen für bis zu fünf URL-Muster.
  • Chat-Apps zeigen eine Vorschau für einen Link pro Nachricht an. Wenn in einer Nachricht mehrere Links mit Vorschau vorhanden sind, wird nur der erste Link mit Vorschau angezeigt.
  • Chat-Apps zeigen nur Vorschauen von Links an, die mit https:// beginnen. Daher wird https://support.example.com/cases/ als Vorschau angezeigt, support.example.com/cases/ jedoch nicht.
  • Sofern die Nachricht keine anderen Informationen enthält, die an die Chat-App gesendet werden, z. B. einen Slash-Befehl, wird bei Linkvorschauen nur die Link-URL an die Chat-App gesendet.
  • Wenn ein Nutzer den Link postet, kann eine Chat-App die Linkvorschaukarte nur aktualisieren, wenn Nutzer mit der Karte interagieren, z. B. durch Klicken auf eine Schaltfläche. Sie können die update()-Methode der Chat API nicht für die Message-Ressource aufrufen, um die Nachricht eines Nutzers asynchron zu aktualisieren.
  • Chat-Apps müssen Links für alle Teilnehmer des Gruppenbereichs in der Vorschau anzeigen. Daher muss das Feld privateMessageViewer in der Nachricht weggelassen werden.

Wenn Sie Link-Vorschauen implementieren, müssen Sie möglicherweise Fehler in Ihrer Chat-App beheben, indem Sie die App-Logs lesen. Die Logs finden Sie in der Google Cloud Console im Log-Explorer.