Ссылки для предварительного просмотра

Чтобы предотвратить переключение контекста, когда пользователи делятся ссылкой в Google Chat, ваше приложение Chat может выполнить предварительный просмотр ссылки, прикрепив к сообщению карточку , которая предоставляет дополнительную информацию и позволяет людям выполнять действия прямо из Google Chat.

Например, представьте себе пространство Google Chat, включающее всех агентов службы поддержки клиентов компании, а также чат-приложение Case-y. Агенты часто делятся ссылками на обращения в службу поддержки клиентов в пространстве Chat, и каждый раз, когда они это делают, их коллеги должны открывать ссылку на обращение, чтобы увидеть информацию, такую как ответственное лицо, статус и тема. Аналогично, если кто-то хочет взять на себя ответственность за обращение или изменить его статус, ему необходимо открыть ссылку.

Предварительный просмотр ссылок позволяет чат-приложению Case-y, встроенному в пространство, прикреплять карточку с указанием ответственного, статуса и темы к каждому обращению, которым кто-либо делится. Кнопки на карточке позволяют агентам взять на себя ответственность за обращение и изменить статус прямо из чата.

Когда кто-то добавляет ссылку в свое сообщение, появляется чип, информирующий о том, что приложение Chat может просмотреть ссылку.

Чип, указывающий, что приложение чата может просматривать ссылку

После отправки сообщения ссылка отправляется в приложение чата, которое затем генерирует и прикрепляет карточку к сообщению пользователя.

Приложение чата, просматривающее ссылку путем прикрепления карточки к сообщению

Помимо ссылки, карточка содержит дополнительную информацию о ней, включая интерактивные элементы, такие как кнопки. Ваше приложение Chat может обновлять прикреплённую карточку в ответ на действия пользователя, например, нажатие кнопок.

Если пользователь не хочет, чтобы приложение Chat открывало предварительный просмотр ссылки, прикрепляя карточку к сообщению, он может отменить предварительный просмотр, нажав на чипе предварительного просмотра. Пользователи могут в любой момент удалить прикреплённую карточку, нажав «Удалить предварительный просмотр» .

Предпосылки

Node.js

Приложение Google Chat, которое получает и реагирует на события взаимодействия . Чтобы создать интерактивное приложение Chat с использованием HTTP-сервиса, выполните это краткое руководство .

Питон

Приложение Google Chat, которое получает и реагирует на события взаимодействия . Чтобы создать интерактивное приложение Chat с использованием HTTP-сервиса, выполните это краткое руководство .

Ява

Приложение Google Chat, которое получает и реагирует на события взаимодействия . Чтобы создать интерактивное приложение Chat с использованием HTTP-сервиса, выполните это краткое руководство .

Скрипт приложений

Приложение Google Chat, которое получает и реагирует на события взаимодействия . Чтобы создать интерактивное приложение Chat в Apps Script, выполните это краткое руководство .

Зарегистрируйте определенные ссылки — например, example.com , support.example.com и support.example.com/cases/ — в качестве шаблонов URL на странице конфигурации вашего приложения Chat в консоли Google Cloud, чтобы ваше приложение Chat могло просматривать их.

Меню конфигурации предпросмотра ссылок

  1. Откройте консоль Google Cloud .
  2. Рядом с «Google Cloud» нажмите стрелку вниз и откройте проект приложения чата.
  3. В поле поиска введите Google Chat API и нажмите Google Chat API .
  4. Нажмите Управление > Конфигурация .
  5. В разделе «Предварительный просмотр ссылок» добавьте или отредактируйте шаблон URL.
    1. Чтобы настроить предварительный просмотр ссылок для нового шаблона URL, нажмите Добавить шаблон URL .
    2. Чтобы изменить конфигурацию существующего шаблона URL, нажмите стрелку вниз .
  6. В поле «Шаблон хоста» введите домен шаблона URL. Приложение чата будет отображать ссылки на этот домен.

    Чтобы получить ссылки предварительного просмотра приложения чата для определенного поддомена, например subdomain.example.com , включите этот поддомен.

    Чтобы ссылки предварительного просмотра приложения Chat отображались для всего домена, укажите подстановочный знак со звёздочкой (*) в качестве поддомена. Например, *.example.com соответствует subdomain.example.com и any.number.of.subdomains.example.com .

  7. В поле Префикс пути введите путь, который будет добавлен к домену шаблона хоста.

    Чтобы сопоставить все URL-адреса в домене шаблона хоста, оставьте префикс пути пустым.

    Например, если шаблон хоста — support.example.com , то для сопоставления URL-адресов для случаев, размещенных по адресу support.example.com/cases/ , введите cases/ .

  8. Нажмите Готово .

  9. Нажмите «Сохранить» .

Теперь, когда кто-то добавляет ссылку, соответствующую шаблону URL-адреса предварительного просмотра ссылки, в сообщение в чат-пространстве, включающем ваше приложение Chat, ваше приложение отображает предварительный просмотр ссылки.

После настройки предварительного просмотра для определенной ссылки ваше приложение Chat сможет распознавать и просматривать ссылку, прикрепляя к ней дополнительную информацию.

В чат-пространствах, включающих ваше приложение Chat, когда чьё-либо сообщение содержит ссылку, соответствующую шаблону URL-адреса для предварительного просмотра ссылки, ваше приложение Chat получает событие взаимодействия MESSAGE . Полезная нагрузка JSON для события взаимодействия содержит поле matchedUrl :

JSON

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

Проверяя наличие поля matchedUrl в полезной нагрузке события MESSAGE , ваше приложение Chat может добавлять информацию к сообщению с предварительно просмотренной ссылкой. Приложение Chat может либо ответить простым текстовым сообщением, либо прикрепить открытку.

Ответить текстовым сообщением

Для простых ответов ваше приложение Chat может выполнить предварительный просмотр ссылки, отправив на неё простое текстовое сообщение . В этом примере прикрепляется сообщение, повторяющее URL-адрес ссылки, соответствующий шаблону URL-адреса для предварительного просмотра ссылки.

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

Чтобы прикрепить карточку к ссылке предварительного просмотра, верните ActionResponse типа UPDATE_USER_MESSAGE_CARDS . В этом примере прикрепляется простая карточка.

Приложение чата, просматривающее ссылку путем прикрепления карточки к сообщению

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/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/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")))))))))))));
}

Скрипт приложений

Этот пример отправляет сообщение с картой, возвращая JSON-файл карты . Вы также можете использовать сервис карт 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'}}
          }]}}
        ]}]
      }
    }]
  };
}

Ваше приложение чата может обновлять карточку предварительного просмотра ссылки, когда пользователи взаимодействуют с ней, например, нажимают кнопку на карточке.

Чтобы обновить карточку, ваше приложение чата должно обработать событие взаимодействия CARD_CLICKED и вернуть actionResponse в зависимости от того, кто отправил сообщение, содержащее предварительный просмотр ссылки:

  • Если сообщение отправил пользователь, установите для actionResponse.type значение UPDATE_USER_MESSAGE_CARDS .
  • Если приложение чата отправило сообщение, установите для actionResponse.type значение UPDATE_MESSAGE .

Чтобы определить, кто отправил сообщение, можно использовать поле message.sender.type события взаимодействия, чтобы узнать, был ли отправитель HUMAN или BOT .

В следующем примере показано, как приложение чата обновляет предварительный просмотр ссылки всякий раз, когда пользователь нажимает кнопку « Назначить мне» , обновляя поле «Назначенный» карточки и отключая кнопку.

Приложение чата, просматривающее ссылку с обновленной версией карточки, прикрепленной к сообщению

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

Скрипт приложений

Этот пример отправляет сообщение с картой, возвращая JSON-файл карты . Вы также можете использовать сервис карт 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'}}
            }]}}
          ]}]
        }
      }]
    };
  }
}

Ограничения и соображения

При настройке предварительного просмотра ссылок для вашего приложения Chat обратите внимание на следующие ограничения и соображения:

  • Каждое приложение чата поддерживает предварительный просмотр ссылок для 5 шаблонов URL.
  • Приложения чата позволяют просматривать только одну ссылку в каждом сообщении. Если в одном сообщении есть несколько ссылок для просмотра, отображается только первая из них.
  • Приложения чата позволяют просматривать только ссылки, начинающиеся с https:// , поэтому https://support.example.com/cases/ выполняет предварительный просмотр, а support.example.com/cases/ нет.
  • Если сообщение не содержит другой информации, отправляемой в приложение Chat, например, команды с косой чертой , то при предварительном просмотре ссылок в приложение Chat отправляется только URL-адрес ссылки.
  • Если пользователь публикует ссылку, приложение Chat может обновить карточку предварительного просмотра ссылки только при взаимодействии пользователя с карточкой, например, при нажатии кнопки. Вы не можете вызвать метод update() API Chat для ресурса Message для асинхронного обновления сообщения пользователя.
  • Приложения чата должны предоставлять предварительный просмотр ссылок всем участникам чата, поэтому в сообщении не должно быть поля privateMessageViewer .

При реализации предварительного просмотра ссылок вам может потребоваться отладить приложение Chat, прочитав его логи. Чтобы ознакомиться с журналами, откройте Logs Explorer в консоли Google Cloud.