Vista previa de vínculos

Para evitar 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 proporcione más información y permita a los usuarios realizar acciones directamente desde Google Chat.

Por ejemplo, imagina un espacio de Google Chat que incluye a todos los agentes de atención al cliente de una empresa y una app de Chat llamada Case-y. Con frecuencia, los agentes comparten 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 destinatario, el estado y el asunto. Del mismo modo, si alguien quiere hacerse cargo de un caso o cambiar el estado, debe abrir el vínculo.

La vista previa de vínculos permite que Case-y, la app de Chat residente del espacio, adjunte una tarjeta en la que se muestre el destinatario, el estado y el asunto cada vez que alguien comparta el vínculo de un 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 es posible que una app de Chat obtenga 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 adjunta una tarjeta al mensaje para obtener una vista previa de un vínculo

Junto al enlace, la tarjeta proporciona información adicional sobre el enlace, 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 obtenga una vista previa de su vínculo adjuntando una tarjeta al mensaje, puede impedir la vista previa haciendo clic en en el chip de vista previa. Los usuarios pueden hacer clic en Quitar vista previa para quitar la tarjeta adjunta en cualquier momento.

Requisitos previos

Node.js

Una app de Google Chat habilitada para funciones interactivas. Para crear un 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 un 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.

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 tu 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 las vistas previas de vínculos para un patrón de URL nuevo, 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 mostrará una vista previa de los vínculos a este dominio.

    Si quieres obtener vínculos de vista previa de la app de Chat para un subdominio específico, como subdomain.example.com, incluye el subdominio.

    Para tener vínculos de vista previa de la app de Chat para 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, ingresa la ruta de acceso que deseas adjuntar al dominio del patrón de host.

    Para que coincidan todas las URLs en el dominio del patrón de host, deja el campo Prefijo de ruta vacío.

    Por ejemplo, si el patrón de host es support.example.com, ingresa cases/ para que coincidan las URLs de los casos alojados en support.example.com/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 del vínculo con un mensaje en un espacio de Chat que incluya tu app de Chat, la app obtendrá una vista previa del vínculo.

Después de configurar la vista previa de un vínculo determinado, tu Chat puede reconocer el vínculo y obtener una vista previa adjuntando más información.

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

JSON

"message": {

  . . . // other message attributes redacted

  "matchedUrl": {
     "url": "https://support.example.com/cases/case123"
   },

  . . . // other message attributes redacted

}

Verifica la presencia del campo matchedUrl en el evento MESSAGE de Chat, la app de Chat puede agregar información mensaje con el vínculo de vista previa. Tu app de Chat puede hacer lo siguiente: puede responder con un mensaje de texto simple o adjuntar una tarjeta.

Responder con un mensaje de texto

Para respuestas simples, la app de Chat puede obtener una vista previa de un vínculo Puedes responder 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/simple-text-message.js
/**
 * Responds to messages that have links whose URLs match URL patterns
 * configured for link previewing.
 *
 * @param {Object} req Request sent from Google Chat.
 * @param {Object} res Response to send back.
 */
exports.onMessage = (req, res) => {
  if (req.method === 'GET' || !req.body.message) {
    return res.send(
      'Hello! This function is meant to be used in a Google Chat Space.');
  }

  // Checks for the presence of event.message.matchedUrl and responds with a
  // text message if present
  if (req.body.message.matchedUrl) {
    return res.json({
      'text': 'req.body.message.matchedUrl.url: ' +
        req.body.message.matchedUrl.url,
    });
  }

  // If the Chat app doesn’t detect a link preview URL pattern, it says so.
  return res.json({'text': 'No matchedUrl detected.'});
};

Apps Script

apps-script/preview-link/simple-text-message.gs
/**
 * Responds to messages that have links whose URLs match URL patterns
 * configured for link previewing.
 *
 * @param {Object} event The event object from Chat API.
 *
 * @return {Object} Response from the Chat app attached to the message with
 * the previewed link.
 */
function onMessage(event) {
  // Checks for the presence of event.message.matchedUrl and responds with a
  // text message if present
  if (event.message.matchedUrl) {
    return {
      'text': 'event.message.matchedUrl.url: ' + event.message.matchedUrl.url,
    };
  }

  // If the Chat app doesn’t detect a link preview URL pattern, it says so.
  return {'text': 'No matchedUrl detected.'};
}

Adjuntar una tarjeta

Para adjuntar una tarjeta a un vínculo de vista previa, sigue estos pasos: devolver un ActionResponse del tipo UPDATE_USER_MESSAGE_CARDS. En este ejemplo, se adjunta una tarjeta simple.

App de Chat que adjunta una tarjeta al mensaje para obtener una vista previa de un vínculo

Node.js

node/preview-link/attach-card.js
/**
 * Responds to messages that have links whose URLs match URL patterns
 * configured for link previewing.
 *
 * @param {Object} req Request sent from Google Chat.
 * @param {Object} res Response to send back.
 */
exports.onMessage = (req, res) => {
  if (req.method === 'GET' || !req.body.message) {
    return res.send(
      'Hello! This function is meant to be used in a Google Chat Space.');
  }

  // Checks for the presence of event.message.matchedUrl and attaches a card
  // if present
  if (req.body.message.matchedUrl) {
    return res.json({
      'actionResponse': {'type': 'UPDATE_USER_MESSAGE_CARDS'},
      'cardsV2': [
        {
          'cardId': 'attachCard',
          'card': {
            'header': {
              'title': 'Example Customer Service Case',
              'subtitle': 'Case basics',
            },
            'sections': [
              {
                'widgets': [
                  {'keyValue': {'topLabel': 'Case ID', 'content': 'case123'}},
                  {'keyValue': {'topLabel': 'Assignee', 'content': 'Charlie'}},
                  {'keyValue': {'topLabel': 'Status', 'content': 'Open'}},
                  {
                    'keyValue': {
                      'topLabel': 'Subject', 'content': 'It won"t turn on...',
                    }
                  },
                ],
              },
              {
                'widgets': [
                  {
                    'buttons': [
                      {
                        'textButton': {
                          'text': 'OPEN CASE',
                          'onClick': {
                            'openLink': {
                              'url': 'https://support.example.com/orders/case123',
                            },
                          },
                        },
                      },
                      {
                        'textButton': {
                          'text': 'RESOLVE CASE',
                          'onClick': {
                            'openLink': {
                              'url': 'https://support.example.com/orders/case123?resolved=y',
                            },
                          },
                        },
                      },
                      {
                        'textButton': {
                          'text': 'ASSIGN TO ME',
                          'onClick': {
                            'action': {
                              'actionMethodName': 'assign',
                            },
                          },
                        },
                      },
                    ],
                  },
                ],
              },
            ],
          },
        },
      ],
    });
  }

  // If the Chat app doesn’t detect a link preview URL pattern, it says so.
  return res.json({'text': 'No matchedUrl detected.'});
};

Apps Script

En este ejemplo, se envía un mensaje de tarjeta mostrando JSON de la tarjeta. También puedes usar Servicio de tarjetas de Apps Script.

apps-script/preview-link/attach-card.gs
/**
 * Responds to messages that have links whose URLs match URL patterns
 * configured for link previewing.
 *
 * @param {Object} event The event object from Chat API.
 * @return {Object} Response from the Chat app attached to the message with
 * the previewed link.
 */
function onMessage(event) {
  // Checks for the presence of event.message.matchedUrl and attaches a card
  // if present
  if (event.message.matchedUrl) {
    return {
      'actionResponse': {
        'type': 'UPDATE_USER_MESSAGE_CARDS',
      },
      'cardsV2': [{
        'cardId': 'attachCard',
        'card': {
          'header': {
            'title': 'Example Customer Service Case',
            'subtitle': 'Case basics',
          },
          'sections': [{
            'widgets': [
              {'keyValue': {'topLabel': 'Case ID', 'content': 'case123'}},
              {'keyValue': {'topLabel': 'Assignee', 'content': 'Charlie'}},
              {'keyValue': {'topLabel': 'Status', 'content': 'Open'}},
              {
                'keyValue': {
                  'topLabel': 'Subject', 'content': 'It won\'t turn on...',
                },
              },
            ],
          },
          {
            'widgets': [{
              'buttons': [
                {
                  'textButton': {
                    'text': 'OPEN CASE',
                    'onClick': {
                      'openLink': {
                        'url': 'https://support.example.com/orders/case123',
                      },
                    },
                  },
                },
                {
                  'textButton': {
                    'text': 'RESOLVE CASE',
                    'onClick': {
                      'openLink': {
                        'url': 'https://support.example.com/orders/case123?resolved=y',
                      },
                    },
                  },
                },
                {
                  'textButton': {
                    'text': 'ASSIGN TO ME',
                    'onClick': {'action': {'actionMethodName': 'assign'}},
                  },
                },
              ],
            }],
          }],
        },
      }],
    };
  }

  // If the Chat app doesn’t detect a link preview URL pattern, it says so.
  return {'text': 'No matchedUrl detected.'};
}

Actualizar una tarjeta

Para actualizar la tarjeta adjunta a un vínculo de vista previa, muestra un ActionResponse del tipo UPDATE_USER_MESSAGE_CARDS. Las apps de Chat solo pueden actualizarse tarjetas que muestran una vista previa de los vínculos como respuesta a un Evento de interacción con la app de Chat. Las apps de Chat no pueden actualizar estas tarjetas llamando a la API de Chat de forma asíncrona.

La vista previa de vínculos no admite que se muestre un ActionResponse de tipo UPDATE_MESSAGE. Dado que UPDATE_MESSAGE actualiza el mensaje completo en lugar de solo la tarjeta, solo funciona si la app de Chat creó el mensaje original. La vista previa de vínculos adjunta una tarjeta a un mensaje creado por el usuario, por lo que la app de Chat no tiene permiso para actualizarla.

Para garantizar que una función actualice las tarjetas creadas por el usuario y por la app en el flujo de Chat, configura de forma dinámica ActionResponse en función de si la app de Chat o un usuario crearon el mensaje.

  • Si un usuario creó el mensaje, establece ActionResponse en UPDATE_USER_MESSAGE_CARDS.
  • Si una app de Chat creó el mensaje, establece ActionResponse en UPDATE_MESSAGE.

Existen dos maneras de hacerlo: especificar y verificar una actionMethodName personalizada como parte de la propiedad onclick de la tarjeta adjunta (que identifica el mensaje como creado por el usuario) o comprobar si un usuario creó el mensaje.

Opción 1: Busca actionMethodName

Si deseas usar actionMethodName para controlar correctamente los eventos de interacción de CARD_CLICKED en las tarjetas con vista previa, establece una actionMethodName personalizada como parte de la propiedad onclick de la tarjeta adjunta:

JSON

. . . // Preview card details
{
  "textButton": {
    "text": "ASSIGN TO ME",
    "onClick": {

      // actionMethodName identifies the button to help determine the
      // appropriate ActionResponse.
      "action": {
        "actionMethodName": "assign",
      }
    }
  }
}
. . . // Preview card details

Si "actionMethodName": "assign" identifica el botón como parte de una vista previa de vínculo, es posible que se muestre de forma dinámica el ActionResponse correcto si se busca un actionMethodName coincidente:

Node.js

node/preview-link/update-card.js
/**
 * Responds to messages that have links whose URLs match URL patterns
 * configured for link previewing.
 *
 * @param {Object} req Request sent from Google Chat.
 * @param {Object} res Response to send back.
 */
exports.onMessage = (req, res) => {
  if (req.method === 'GET' || !req.body.message) {
    return res.send(
      'Hello! This function is meant to be used in a Google Chat Space.');
  }

  // Respond to button clicks on attached cards
  if (req.body.type === 'CARD_CLICKED') {
    // Checks for the presence of "actionMethodName": "assign" and sets
    // actionResponse.type to "UPDATE_USER"MESSAGE_CARDS" if present or
    // "UPDATE_MESSAGE" if absent.
    const actionResponseType = req.body.action.actionMethodName === 'assign' ?
      'UPDATE_USER_MESSAGE_CARDS' :
      'UPDATE_MESSAGE';

    if (req.body.action.actionMethodName === 'assign') {
      return res.json({
        'actionResponse': {

          // Dynamically returns the correct actionResponse type.
          'type': actionResponseType,
        },

        // Preview card details
        'cardsV2': [{}],
      });
    }
  }
};

Apps Script

En este ejemplo, se envía un mensaje de tarjeta mostrando JSON de la tarjeta. También puedes usar Servicio de tarjetas de Apps Script.

apps-script/preview-link/update-card.gs
/**
 * Updates a card that was attached to a message with a previewed link.
 *
 * @param {Object} event The event object from Chat API.
 * @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) {
  // Checks for the presence of "actionMethodName": "assign" and sets
  // actionResponse.type to "UPDATE_USER"MESSAGE_CARDS" if present or
  // "UPDATE_MESSAGE" if absent.
  const actionResponseType = event.action.actionMethodName === 'assign' ?
    'UPDATE_USER_MESSAGE_CARDS' :
    'UPDATE_MESSAGE';

  if (event.action.actionMethodName === 'assign') {
    return assignCase(actionResponseType);
  }
}

/**
 * Updates a card to say that "You" are the assignee after clicking the Assign
 * to Me button.
 *
 * @param {String} actionResponseType Which actionResponse the Chat app should
 * use to update the attached card based on who created the message.
 * @return {Object} Response from the Chat app. Updates the card attached to
 * the message with the previewed link.
 */
function assignCase(actionResponseType) {
  return {
    'actionResponse': {

      // Dynamically returns the correct actionResponse type.
      'type': actionResponseType,
    },
    // Preview card details
    'cardsV2': [{}],
  };
}

Opción 2: Verifica el tipo de remitente

Comprueba si message.sender.type es HUMAN o BOT. Si es HUMAN, establece ActionResponse en UPDATE_USER_MESSAGE_CARDS; de lo contrario, establece ActionResponse en UPDATE_MESSAGE. A continuación, le indicamos cómo hacerlo:

Node.js

node/preview-link/sender-type.js
/**
 * Responds to messages that have links whose URLs match URL patterns
 * configured for link previewing.
 *
 * @param {Object} req Request sent from Google Chat.
 * @param {Object} res Response to send back.
 */
exports.onMessage = (req, res) => {
  if (req.method === 'GET' || !req.body.message) {
    return res.send(
      'Hello! This function is meant to be used in a Google Chat Space.');
  }

  // Respond to button clicks on attached cards
  if (req.body.type === 'CARD_CLICKED') {
    // 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 = req.body.action.actionMethodName === 'HUMAN' ?
      'UPDATE_USER_MESSAGE_CARDS' :
      'UPDATE_MESSAGE';

    return res.json({
      'actionResponse': {

        // Dynamically returns the correct actionResponse type.
        'type': actionResponseType,
      },

      // Preview card details
      'cardsV2': [{}],
    });
  }
};

Apps Script

En este ejemplo, se envía un mensaje de tarjeta mostrando JSON de la tarjeta. También puedes usar Servicio de tarjetas de Apps Script.

apps-script/preview-link/sender-type.gs
/**
 * Updates a card that was attached to a message with a previewed link.
 *
 * @param {Object} event The event object from Chat API.
 * @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) {
  // 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';

  return assignCase(actionResponseType);
}

/**
 * Updates a card to say that "You" are the assignee after clicking the Assign
 * to Me button.
 *
 * @param {String} actionResponseType Which actionResponse the Chat app should
 * use to update the attached card based on who created the message.
 * @return {Object} Response from the Chat app. Updates the card attached to
 * the message with the previewed link.
 */
function assignCase(actionResponseType) {
  return {
    'actionResponse': {

      // Dynamically returns the correct actionResponse type.
      'type': actionResponseType,
    },
    // Preview card details
    'cardsV2': [{}],
  };
}

Un motivo típico para actualizar una tarjeta es en respuesta a un clic en un botón. Recuerda el botón Assign to Me de la sección anterior, Attach a card. En el siguiente ejemplo completo, se actualiza la tarjeta para que indique que se asignó a "Tú" Después de que un usuario hace clic en Asignar a mí En el ejemplo, se verifica el tipo de remitente para configurar ActionResponse de forma dinámica.

Ejemplo completo: Case-y, la app de Chat de atención al cliente

Este es el código completo de Case-y, una app de Chat que muestra una vista previa de los vínculos a los casos compartidos en un espacio de Chat en el que colaboran los agentes de atención al cliente.

Node.js

node/preview-link/preview-link.js
/**
 * Responds to messages that have links whose URLs match URL patterns
 * configured for link previewing.
 *
 * @param {Object} req Request sent from Google Chat.
 * @param {Object} res Response to send back.
 */
exports.onMessage = (req, res) => {
  if (req.method === 'GET' || !req.body.message) {
    return res.send(
      'Hello! This function is meant to be used in a Google Chat Space.');
  }

  // Respond to button clicks on attached cards
  if (req.body.type === 'CARD_CLICKED') {
    // 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 = req.body.action.actionMethodName === 'HUMAN' ?
      'UPDATE_USER_MESSAGE_CARDS' :
      'UPDATE_MESSAGE';

    if (req.body.action.actionMethodName === 'assign') {
      return res.json(createMessage(actionResponseType, 'You'));
    }
  }

  // Checks for the presence of event.message.matchedUrl and attaches a card
  // if present
  if (req.body.message.matchedUrl) {
    return res.json(createMessage());
  }

  // If the Chat app doesn’t detect a link preview URL pattern, it says so.
  return res.json({'text': 'No matchedUrl detected.'});
};

/**
 * Message to create a card with the correct response type and assignee.
 *
 * @param {string} actionResponseType
 * @param {string} assignee
 * @return {Object} a card with URL preview
 */
function createMessage(
  actionResponseType = 'UPDATE_USER_MESSAGE_CARDS',
  assignee = 'Charlie'
) {
  return {
    'actionResponse': {'type': actionResponseType},
    'cardsV2': [
      {
        'cardId': 'previewLink',
        'card': {
          'header': {
            'title': 'Example Customer Service Case',
            'subtitle': 'Case basics',
          },
          'sections': [
            {
              'widgets': [
                {'keyValue': {'topLabel': 'Case ID', 'content': 'case123'}},
                {'keyValue': {'topLabel': 'Assignee', 'content': assignee}},
                {'keyValue': {'topLabel': 'Status', 'content': 'Open'}},
                {
                  'keyValue': {
                    'topLabel': 'Subject', 'content': 'It won"t turn on...',
                  },
                },
              ],
            },
            {
              'widgets': [
                {
                  'buttons': [
                    {
                      'textButton': {
                        'text': 'OPEN CASE',
                        'onClick': {
                          'openLink': {
                            'url': 'https://support.example.com/orders/case123',
                          },
                        },
                      },
                    },
                    {
                      'textButton': {
                        'text': 'RESOLVE CASE',
                        'onClick': {
                          'openLink': {
                            'url': 'https://support.example.com/orders/case123?resolved=y',
                          },
                        },
                      },
                    },
                    {
                      'textButton': {
                        'text': 'ASSIGN TO ME',
                        'onClick': {
                          'action': {
                            'actionMethodName': 'assign',
                          },
                        },
                      },
                    },
                  ],
                },
              ],
            },
          ],
        }
      },
    ],
  };
}

Apps Script

En este ejemplo, se envía un mensaje de tarjeta mostrando JSON de la tarjeta. También puedes usar Servicio de tarjetas de Apps Script.

apps-script/preview-link/preview-link.gs
/**
 * Responds to messages that have links whose URLs match URL patterns
 * configured for link previews.
 *
 * @param {Object} event The event object from Chat API.
 * @return {Object} Response from the Chat app attached to the message with
 * the previewed link.
 */
function onMessage(event) {
  // Checks for the presence of event.message.matchedUrl and attaches a card
  // if present
  if (event.message.matchedUrl) {
    return {
      'actionResponse': {
        'type': 'UPDATE_USER_MESSAGE_CARDS',
      },
      'cardsV2': [{
        'cardId': 'previewLink',
        'card': {
          'header': {
            'title': 'Example Customer Service Case',
            'subtitle': 'Case basics',
          },
          'sections': [{
            'widgets': [
              {'keyValue': {'topLabel': 'Case ID', 'content': 'case123'}},
              {'keyValue': {'topLabel': 'Assignee', 'content': 'Charlie'}},
              {'keyValue': {'topLabel': 'Status', 'content': 'Open'}},
              {
                'keyValue': {
                  'topLabel': 'Subject', 'content': 'It won\'t turn on...',
                }
              },
            ],
          },
          {
            'widgets': [{
              'buttons': [
                {
                  'textButton': {
                    'text': 'OPEN CASE',
                    'onClick': {
                      'openLink': {
                        'url': 'https://support.example.com/orders/case123',
                      },
                    },
                  },
                },
                {
                  'textButton': {
                    'text': 'RESOLVE CASE',
                    'onClick': {
                      'openLink': {
                        'url': 'https://support.example.com/orders/case123?resolved=y',
                      },
                    },
                  },
                },
                {
                  'textButton': {
                    'text': 'ASSIGN TO ME',
                    'onClick': {'action': {'actionMethodName': 'assign'}}
                  },
                },
              ],
            }],
          }],
        },
      }],
    };
  }

  // If the Chat app doesn’t detect a link preview URL pattern, it says so.
  return {'text': 'No matchedUrl detected.'};
}

/**
 * Updates a card that was attached to a message with a previewed link.
 *
 * @param {Object} event The event object from Chat API.
 * @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) {
  // Checks whether the message event originated from a human or a Chat app
  // and sets actionResponse 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';

  // To respond to the correct button, checks the button's actionMethodName.
  if (event.action.actionMethodName === 'assign') {
    return assignCase(actionResponseType);
  }
}

/**
 * Updates a card to say that "You" are the assignee after clicking the Assign
 * to Me button.
 *
 * @param {String} actionResponseType Which actionResponse the Chat app should
 * use to update the attached card based on who created the message.
 * @return {Object} Response from the Chat app. Updates the card attached to
 * the message with the previewed link.
 */
function assignCase(actionResponseType) {
  return {
    'actionResponse': {

      // Dynamically returns the correct actionResponse type.
      'type': actionResponseType,
    },
    'cardsV2': [{
      'cardId': 'assignCase',
      'card': {
        'header': {
          'title': 'Example Customer Service Case',
          'subtitle': 'Case basics',
        },
        'sections': [{
          'widgets': [
            {'keyValue': {'topLabel': 'Case ID', 'content': 'case123'}},
            {'keyValue': {'topLabel': 'Assignee', 'content': 'You'}},
            {'keyValue': {'topLabel': 'Status', 'content': 'Open'}},
            {
              'keyValue': {
                'topLabel': 'Subject', 'content': 'It won\'t turn on...',
              }
            },
          ],
        },
        {
          'widgets': [{
            'buttons': [
              {
                'textButton': {
                  'text': 'OPEN CASE',
                  'onClick': {
                    'openLink': {
                      'url': 'https://support.example.com/orders/case123',
                    },
                  },
                },
              },
              {
                'textButton': {
                  'text': 'RESOLVE CASE',
                  'onClick': {
                    'openLink': {
                      'url': 'https://support.example.com/orders/case123?resolved=y',
                    },
                  },
                },
              },
              {
                'textButton': {
                  'text': 'ASSIGN TO ME',
                  'onClick': {'action': {'actionMethodName': '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 obtienen 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/ obtiene 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 se envía la URL del vínculo a la app de Chat mediante las vistas previas del vínculo.
  • Las tarjetas adjuntas a los vínculos con vista previa solo admiten un ActionResponse de tipo UPDATE_USER_MESSAGE_CARDS y solo en respuesta a un evento de interacción con la app de Chat. Las vistas previas de vínculos no admiten UPDATE_MESSAGE ni solicitudes asíncronas para actualizar tarjetas adjuntas a un vínculo de vista previa a través de la API de Chat. Para obtener más información, consulta Cómo actualizar una tarjeta.
  • Las apps de Chat deben tener una vista previa de los vínculos para todos los participantes del espacio, por lo que el mensaje debe omitir privateMessageViewer .

A medida que implementas 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.