Vista previa de vínculos

Para evitar los cambios 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 al mensaje que proporciona más información y permite a las personas realizar acciones directamente desde 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 les permiten a los agentes hacerse cargo del caso y cambiar el estado directamente desde el flujo de chat.

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.

Chip que indica que una app de Chat podría obtener una vista previa de un vínculo

Después de enviar el mensaje, el vínculo se envía a la app de Chat, que genera y adjunta la tarjeta al mensaje del usuario.

App de chat que muestra una vista previa de un vínculo adjuntando una tarjeta al mensaje

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 las interacciones del usuario, como los 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

Una app de Google Chat habilitada para funciones interactivas Para crear una app de Chat interactiva con un servicio HTTP, completa esta guía de inicio rápido.

Python

Una app de Google Chat habilitada para funciones interactivas Para crear una app de Chat interactiva con un servicio HTTP, completa esta guía de inicio rápido.

Java

Una app de Google Chat habilitada para funciones interactivas Para crear una app de Chat interactiva con un servicio HTTP, completa esta guía de inicio rápido.

Apps Script

Una app de Google Chat habilitada para funciones interactivas Para crear una app de Chat interactiva en Apps Script, completa esta guía de inicio rápido.

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.

Menú de configuración de vistas previas de vínculos

  1. Abre Google Cloud Console
  2. Junto a “Google Cloud”, haz clic en la flecha hacia abajo y abre el proyecto de la app de Chat.
  3. En el campo de búsqueda, escribe Google Chat API y haz clic en API de Google Chat.
  4. Haz clic en Administrar > Configuración.
  5. En Vistas previas de vínculos, agrega o edita un patrón de URL.
    1. Para configurar vistas previas de vínculos para un nuevo patrón de URL, haz clic en Agregar patrón de URL.
    2. Para editar la configuración de un patrón de URL existente, haz clic en la flecha hacia abajo .
  6. 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 con subdomain.example.com y any.number.of.subdomains.example.com.

  7. 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 en support.example.com/cases/, ingresa cases/.

  8. Haz clic en Listo.

  9. 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.

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 adjunta más información.

En los espacios de Chat que incluyen tu app de Chat, cuando el mensaje de una persona contiene un vínculo que coincide con un patrón de URL de vista previa del vínculo, la app de Chat recibe un evento de interacción MESSAGE. La carga útil de JSON para el evento de interacción contiene el campo matchedUrl:

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 simple 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

node/preview-link/index.js
// Reply with a text message for URLs of the subdomain "text"
if (event.message.matchedUrl.url.includes("text.example.com")) {
  return {
    text: 'event.message.matchedUrl.url: ' + event.message.matchedUrl.url
  };
}

Python

python/preview-link/main.py
# Reply with a text message for URLs of the subdomain "text"
if 'text.example.com' in event.get('message').get('matchedUrl').get('url'):
  return {
    'text': 'event.message.matchedUrl.url: ' +
            event.get('message').get('matchedUrl').get('url')
  }

Java

java/preview-link/src/main/java/com/google/chat/preview/App.java
// Reply with a text message for URLs of the subdomain "text"
if (event.at("/message/matchedUrl/url").asText().contains("text.example.com")) {
  return new Message().setText("event.message.matchedUrl.url: " +
    event.at("/message/matchedUrl/url").asText());
}

Apps Script

apps-script/preview-link/preview-link.gs
// Reply with a text message for URLs of the subdomain "text"
if (event.message.matchedUrl.url.includes("text.example.com")) {
  return {
    text: 'event.message.matchedUrl.url: ' + event.message.matchedUrl.url
  };
}

Para adjuntar una tarjeta a un vínculo con vista previa, muestra un ActionResponse de tipo UPDATE_USER_MESSAGE_CARDS. En este ejemplo, se adjunta una tarjeta básica.

App de chat que muestra una vista previa de un vínculo adjuntando una tarjeta al mensaje

Node.js

node/preview-link/index.js
// Attach a card to the message for URLs of the subdomain "support"
if (event.message.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 {
    actionResponse: { type: 'UPDATE_USER_MESSAGE_CARDS' },
    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',
            onClick: { action: { function: 'assign'}}
          }]}}
        ]}]
      }
    }]
  };
}

Python

python/preview-link/main.py
# Attach a card to the message for URLs of the subdomain "support"
if 'support.example.com' in event.get('message').get('matchedUrl').get('url'):
  # 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 {
    'actionResponse': { 'type': 'UPDATE_USER_MESSAGE_CARDS' },
    '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',
            'onClick': { 'action': { 'function': 'assign'}}
          }]}}
        ]}]
      }
    }]
  }

Java

java/preview-link/src/main/java/com/google/chat/preview/App.java
// Attach a card to the message for URLs of the subdomain "support"
if (event.at("/message/matchedUrl/url").asText().contains("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 new Message()
    .setActionResponse(new ActionResponse()
      .setType("UPDATE_USER_MESSAGE_CARDS"))
    .setCardsV2(List.of(new CardWithId()
      .setCardId("attachCard")
      .setCard(new GoogleAppsCardV1Card()
        .setHeader(new GoogleAppsCardV1CardHeader()
          .setTitle("Example Customer Service Case")
          .setSubtitle("Case basics"))
        .setSections(List.of(new GoogleAppsCardV1Section().setWidgets(List.of(
          new GoogleAppsCardV1Widget().setDecoratedText(new GoogleAppsCardV1DecoratedText()
            .setTopLabel("Case ID")
            .setText("case123")),
          new GoogleAppsCardV1Widget().setDecoratedText(new GoogleAppsCardV1DecoratedText()
            .setTopLabel("Assignee")
            .setText("Charlie")),
          new GoogleAppsCardV1Widget().setDecoratedText(new GoogleAppsCardV1DecoratedText()
            .setTopLabel("Status")
            .setText("Open")),
          new GoogleAppsCardV1Widget().setDecoratedText(new GoogleAppsCardV1DecoratedText()
            .setTopLabel("Subject")
            .setText("It won't turn on...")),
          new GoogleAppsCardV1Widget()
            .setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(
              new GoogleAppsCardV1Button()
                .setText("OPEN CASE")
                .setOnClick(new GoogleAppsCardV1OnClick()
                  .setOpenLink(new GoogleAppsCardV1OpenLink()
                    .setUrl("https://support.example.com/orders/case123"))),
              new GoogleAppsCardV1Button()
                .setText("RESOLVE CASE")
                .setOnClick(new GoogleAppsCardV1OnClick()
                  .setOpenLink(new GoogleAppsCardV1OpenLink()
                    .setUrl("https://support.example.com/orders/case123?resolved=y"))),
              new GoogleAppsCardV1Button()
                .setText("ASSIGN TO ME")
                .setOnClick(new GoogleAppsCardV1OnClick()
                  .setAction(new GoogleAppsCardV1Action().setFunction("assign")))))))))))));
}

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.

apps-script/preview-link/preview-link.gs
// Attach a card to the message for URLs of the subdomain "support"
if (event.message.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 {
    actionResponse: { type: 'UPDATE_USER_MESSAGE_CARDS' },
    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',
            onClick: { action: { function: 'assign'}}
          }]}}
        ]}]
      }
    }]
  };
}

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 controlar el evento de interacción CARD_CLICKED y mostrar un actionResponse según quién envió el mensaje que contiene la vista previa del vínculo:

  • Si un usuario envió el mensaje, configura actionResponse.type como UPDATE_USER_MESSAGE_CARDS.
  • Si la app de Chat envió el mensaje, configura actionResponse.type como UPDATE_MESSAGE.

Para determinar quién envió el mensaje, puedes usar el campo message.sender.type del evento de interacción para ver si el remitente era un usuario HUMAN o BOT.

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.

App de chat que muestra una vista previa de un vínculo con una versión actualizada de una tarjeta adjunta a un mensaje

Node.js

node/preview-link/index.js
/**
 * Updates a card that was attached to a message with a previewed link.
 *
 * @param {Object} event The event object from Chat.
 *
 * @return {Object} Response from the Chat app. Either a new card attached to
 * the message with the previewed link, or an update to an existing card.
 */
function onCardClick(event) {
  // To respond to the correct button, checks the button's actionMethodName.
  if (event.action.actionMethodName === 'assign') {
    // 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.

    // Checks whether the message event originated from a human or a Chat app
    // and sets actionResponse.type to "UPDATE_USER_MESSAGE_CARDS if human or
    // "UPDATE_MESSAGE" if Chat app.
    const actionResponseType = event.message.sender.type === 'HUMAN' ?
      'UPDATE_USER_MESSAGE_CARDS' :
      'UPDATE_MESSAGE';

    // Returns the updated card that displays "You" for the assignee
    // and that disables the button.
    return {
      actionResponse: { type: actionResponseType },
      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,
              onClick: { action: { function: 'assign'}}
            }]}}
          ]}]
        }
      }]
    };
  }
}

Python

python/preview-link/main.py
def on_card_click(event: dict) -> dict:
  """Updates a card that was attached to a message with a previewed link."""
  # To respond to the correct button, checks the button's actionMethodName.
  if 'assign' == event.get('action').get('actionMethodName'):
    # 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.

    # Checks whether the message event originated from a human or a Chat app
    # and sets actionResponse.type to "UPDATE_USER_MESSAGE_CARDS if human or
    # "UPDATE_MESSAGE" if Chat app.
    actionResponseType = 'UPDATE_USER_MESSAGE_CARDS' if \
      event.get('message').get('sender').get('type') == 'HUMAN' else \
      'UPDATE_MESSAGE'

    # Returns the updated card that displays "You" for the assignee
    # and that disables the button.
    return {
      'actionResponse': { 'type': actionResponseType },
      '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,
              'onClick': { 'action': { 'function': 'assign'}}
            }]}}
          ]}]
        }
      }]
    }

Java

java/preview-link/src/main/java/com/google/chat/preview/App.java
// Updates a card that was attached to a message with a previewed link.
Message onCardClick(JsonNode event) {
  // To respond to the correct button, checks the button's actionMethodName.
  if (event.at("/action/actionMethodName").asText().equals("assign")) {
    // 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.

    // Checks whether the message event originated from a human or a Chat app
    // and sets actionResponse.type to "UPDATE_USER_MESSAGE_CARDS if human or
    // "UPDATE_MESSAGE" if Chat app.
    String actionResponseType =
      event.at("/message/sender/type").asText().equals("HUMAN")
      ? "UPDATE_USER_MESSAGE_CARDS" : "UPDATE_MESSAGE";

    // Returns the updated card that displays "You" for the assignee
    // and that disables the button.
    return new Message()
    .setActionResponse(new ActionResponse()
      .setType(actionResponseType))
    .setCardsV2(List.of(new CardWithId()
      .setCardId("attachCard")
      .setCard(new GoogleAppsCardV1Card()
        .setHeader(new GoogleAppsCardV1CardHeader()
          .setTitle("Example Customer Service Case")
          .setSubtitle("Case basics"))
        .setSections(List.of(new GoogleAppsCardV1Section().setWidgets(List.of(
          new GoogleAppsCardV1Widget().setDecoratedText(new GoogleAppsCardV1DecoratedText()
            .setTopLabel("Case ID")
            .setText("case123")),
          new GoogleAppsCardV1Widget().setDecoratedText(new GoogleAppsCardV1DecoratedText()
            .setTopLabel("Assignee")
            // The assignee is now "You"
            .setText("You")),
          new GoogleAppsCardV1Widget().setDecoratedText(new GoogleAppsCardV1DecoratedText()
            .setTopLabel("Status")
            .setText("Open")),
          new GoogleAppsCardV1Widget().setDecoratedText(new GoogleAppsCardV1DecoratedText()
            .setTopLabel("Subject")
            .setText("It won't turn on...")),
          new GoogleAppsCardV1Widget()
            .setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(
              new GoogleAppsCardV1Button()
                .setText("OPEN CASE")
                .setOnClick(new GoogleAppsCardV1OnClick()
                  .setOpenLink(new GoogleAppsCardV1OpenLink()
                    .setUrl("https://support.example.com/orders/case123"))),
              new GoogleAppsCardV1Button()
                .setText("RESOLVE CASE")
                .setOnClick(new GoogleAppsCardV1OnClick()
                  .setOpenLink(new GoogleAppsCardV1OpenLink()
                    .setUrl("https://support.example.com/orders/case123?resolved=y"))),
              new GoogleAppsCardV1Button()
                .setText("ASSIGN TO ME")
                // The button is now disabled
                .setDisabled(true)
                .setOnClick(new GoogleAppsCardV1OnClick()
                  .setAction(new GoogleAppsCardV1Action().setFunction("assign")))))))))))));
  }
  return null;
}

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.

apps-script/preview-link/preview-link.gs
/**
 * Updates a card that was attached to a message with a previewed link.
 *
 * @param {Object} event The event object from Chat.
 *
 * @return {Object} Response from the Chat app. Either a new card attached to
 * the message with the previewed link, or an update to an existing card.
 */
function onCardClick(event) {
  // To respond to the correct button, checks the button's actionMethodName.
  if (event.action.actionMethodName === 'assign') {
    // 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.

    // Checks whether the message event originated from a human or a Chat app
    // and sets actionResponse.type to "UPDATE_USER_MESSAGE_CARDS if human or
    // "UPDATE_MESSAGE" if Chat app.
    const actionResponseType = event.message.sender.type === 'HUMAN' ?
      'UPDATE_USER_MESSAGE_CARDS' :
      'UPDATE_MESSAGE';

    // Returns the updated card that displays "You" for the assignee
    // and that disables the button.
    return {
      actionResponse: { type: actionResponseType },
      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,
              onClick: { action: { function: 'assign'}}
            }]}}
          ]}]
        }
      }]
    };
  }
}

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 de vista previa en un solo mensaje, solo se mostrará la vista previa del primer vínculo correspondiente.
  • Las apps de Chat solo tienen una vista previa de los vínculos que comienzan con https://, por lo que https://support.example.com/cases/ muestra una vista previa, pero support.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 mediante las vistas previas del vínculo.
  • 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 recurso Message 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 participantes del espacio, por lo que el mensaje debe omitir el campo privateMessageViewer.

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.