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

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

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

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

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

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

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

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

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

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

Предварительные требования

Node.js

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

Python

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

Java

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

Apps Script

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

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

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

  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 , укажите этот поддомен.

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

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

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

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

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

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

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

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

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

JSON

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

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

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

Для простых ответов ваше приложение чата может предварительно просмотреть ссылку, ответив простым текстовым сообщением . В этом примере к сообщению прикреплен 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

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

Чтобы прикрепить карточку к предварительно просмотренной ссылке, верните 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

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

В этом примере отправляется сообщение в виде карточки, возвращая 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

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

В этом примере отправляется сообщение в виде карточки, возвращая 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'}}
            }]}}
          ]}]
        }
      }]
    };
  }
}

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

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

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

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