Xem trước đường liên kết

Để ngăn người dùng chuyển đổi ngữ cảnh khi chia sẻ đường liên kết trong Google Chat, ứng dụng Chat của bạn có thể xem trước đường liên kết bằng cách đính kèm một thẻ vào tin nhắn của họ. Thẻ này cung cấp thêm thông tin và cho phép mọi người thực hiện hành động ngay trong Google Chat.

Ví dụ: hãy tưởng tượng một không gian trên Google Chat bao gồm tất cả nhân viên dịch vụ khách hàng của một công ty, cộng với một ứng dụng Chat có tên là Case-y. Các nhân viên thường xuyên chia sẻ đường liên kết đến các trường hợp dịch vụ khách hàng trong không gian trò chuyện và mỗi khi họ làm như vậy, đồng nghiệp của họ phải mở đường liên kết đến trường hợp đó để xem các thông tin chi tiết như người được giao, trạng thái và chủ đề. Tương tự, nếu muốn tiếp nhận quyền sở hữu một trường hợp hoặc thay đổi trạng thái, thì họ cần mở đường liên kết.

Tính năng xem trước đường liên kết cho phép ứng dụng Chat thường trú của không gian, Case-y, đính kèm thẻ cho biết người được giao, trạng thái và tiêu đề bất cứ khi nào có người chia sẻ đường liên kết đến một trường hợp. Các nút trên thẻ cho phép nhân viên tiếp quản trường hợp và thay đổi trạng thái ngay trong luồng trò chuyện.

Khi người dùng thêm đường liên kết vào tin nhắn, một khối thông tin sẽ xuất hiện để cho họ biết rằng ứng dụng Chat có thể xem trước đường liên kết đó.

Chip cho biết một ứng dụng Chat có thể xem trước một đường liên kết

Sau khi gửi tin nhắn, đường liên kết sẽ được gửi đến ứng dụng Chat. Sau đó, ứng dụng này sẽ tạo và đính kèm thẻ vào tin nhắn của người dùng.

Ứng dụng Chat xem trước một đường liên kết bằng cách đính kèm thẻ vào tin nhắn

Bên cạnh đường liên kết, thẻ này cung cấp thêm thông tin về đường liên kết, bao gồm cả các phần tử tương tác như nút. Ứng dụng Chat có thể cập nhật thẻ đính kèm để phản hồi các hoạt động tương tác của người dùng, chẳng hạn như lượt nhấp vào nút.

Nếu không muốn ứng dụng Chat xem trước đường liên kết bằng cách đính kèm thẻ vào tin nhắn, người dùng có thể ngăn tính năng xem trước bằng cách nhấp vào biểu tượng trên chip xem trước. Người dùng có thể xoá thẻ đính kèm bất cứ lúc nào bằng cách nhấp vào Xoá bản xem trước.

Điều kiện tiên quyết

Node.js

Một ứng dụng Google Chat nhận và phản hồi sự kiện tương tác. Để tạo một ứng dụng Chat tương tác bằng dịch vụ HTTP, hãy hoàn tất hướng dẫn bắt đầu nhanh này.

Python

Một ứng dụng Google Chat nhận và phản hồi sự kiện tương tác. Để tạo một ứng dụng Chat tương tác bằng dịch vụ HTTP, hãy hoàn tất hướng dẫn bắt đầu nhanh này.

Java

Một ứng dụng Google Chat nhận và phản hồi sự kiện tương tác. Để tạo một ứng dụng Chat tương tác bằng dịch vụ HTTP, hãy hoàn tất hướng dẫn bắt đầu nhanh này.

Apps Script

Một ứng dụng Google Chat nhận và phản hồi sự kiện tương tác. Để tạo một ứng dụng Chat có tính tương tác trong Apps Script, hãy hoàn thành hướng dẫn bắt đầu nhanh này.

Đăng ký các đường liên kết cụ thể (chẳng hạn như example.com, support.example.comsupport.example.com/cases/) dưới dạng mẫu URL trên trang cấu hình của ứng dụng Chat trong bảng điều khiển Google Cloud để ứng dụng Chat có thể xem trước các đường liên kết đó.

Trình đơn cấu hình bản xem trước đường liên kết

  1. Mở Google Cloud Console.
  2. Bên cạnh "Google Cloud", hãy nhấp vào biểu tượng Mũi tên xuống rồi mở dự án của ứng dụng Chat.
  3. Trong trường tìm kiếm, hãy nhập Google Chat API rồi nhấp vào Google Chat API.
  4. Nhấp vào Quản lý > Cấu hình.
  5. Trong phần Xem trước đường liên kết, hãy thêm hoặc chỉnh sửa một mẫu URL.
    1. Để định cấu hình bản xem trước đường liên kết cho một mẫu URL mới, hãy nhấp vào Thêm mẫu URL.
    2. Để chỉnh sửa cấu hình cho một mẫu URL hiện có, hãy nhấp vào biểu tượng Mũi tên xuống .
  6. Trong trường Mẫu máy chủ lưu trữ, hãy nhập miền của mẫu URL. Ứng dụng Chat sẽ xem trước các đường liên kết đến miền này.

    Để ứng dụng Chat xem trước đường liên kết cho một miền con cụ thể, chẳng hạn như subdomain.example.com, hãy thêm miền con đó.

    Để ứng dụng Chat xem trước đường liên kết cho toàn bộ miền, hãy chỉ định ký tự đại diện có dấu hoa thị (*) làm miền con. Ví dụ: *.example.com khớp với subdomain.example.comany.number.of.subdomains.example.com.

  7. Trong trường Tiền tố đường dẫn, hãy nhập một đường dẫn để thêm vào miền mẫu máy chủ lưu trữ.

    Để so khớp tất cả URL trong miền mẫu máy chủ, hãy để trống Tiền tố đường dẫn.

    Ví dụ: nếu Mẫu máy chủ lưu trữ là support.example.com, để so khớp các URL cho những trường hợp được lưu trữ tại support.example.com/cases/, hãy nhập cases/.

  8. Nhấp vào Xong.

  9. Nhấp vào Lưu.

Giờ đây, bất cứ khi nào có người thêm một đường liên kết khớp với mẫu URL xem trước đường liên kết vào một tin nhắn trong không gian Chat có ứng dụng Chat của bạn, thì ứng dụng của bạn sẽ xem trước đường liên kết đó.

Sau khi bạn định cấu hình tính năng xem trước đường liên kết cho một đường liên kết nhất định, ứng dụng Chat có thể nhận dạng và xem trước đường liên kết đó bằng cách đính kèm thêm thông tin vào đường liên kết.

Trong các không gian Chat có ứng dụng Chat của bạn, khi tin nhắn của người dùng chứa một đường liên kết khớp với mẫu URL xem trước đường liên kết, ứng dụng Chat của bạn sẽ nhận được sự kiện tương tác MESSAGE. Tải trọng JSON cho sự kiện tương tác chứa trường matchedUrl:

JSON

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

Bằng cách kiểm tra sự hiện diện của trường matchedUrl trong tải trọng sự kiện MESSAGE, ứng dụng Chat của bạn có thể thêm thông tin vào thông báo có đường liên kết được xem trước. Ứng dụng Chat có thể trả lời bằng tin nhắn văn bản cơ bản hoặc đính kèm thẻ.

Trả lời bằng tin nhắn văn bản

Đối với các câu trả lời cơ bản, ứng dụng Chat của bạn có thể xem trước một đường liên kết bằng cách trả lời bằng một tin nhắn văn bản đơn giản cho một đường liên kết. Ví dụ này đính kèm một thông báo lặp lại URL của đường liên kết khớp với một mẫu URL xem trước đường liên kết.

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

Để đính kèm một thẻ vào một đường liên kết được xem trước, hãy trả về một ActionResponse thuộc loại UPDATE_USER_MESSAGE_CARDS. Ví dụ này đính kèm một thẻ cơ bản.

Ứng dụng Chat xem trước một đường liên kết bằng cách đính kèm thẻ vào tin nhắn

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

Ví dụ này gửi một thông báo dạng thẻ bằng cách trả về JSON thẻ. Bạn cũng có thể sử dụng dịch vụ thẻ 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'}}
          }]}}
        ]}]
      }
    }]
  };
}

Ứng dụng Chat có thể cập nhật thẻ xem trước đường liên kết khi người dùng tương tác với thẻ đó, chẳng hạn như nhấp vào một nút trên thẻ.

Để cập nhật thẻ, ứng dụng Chat của bạn phải xử lý sự kiện tương tác CARD_CLICKED và trả về actionResponse dựa trên người đã gửi thông báo có chứa bản xem trước đường liên kết:

  • Nếu người dùng đã gửi thông báo, hãy đặt actionResponse.type thành UPDATE_USER_MESSAGE_CARDS.
  • Nếu ứng dụng Chat đã gửi tin nhắn, hãy đặt actionResponse.type thành UPDATE_MESSAGE.

Để xác định người gửi tin nhắn, bạn có thể sử dụng trường message.sender.type của sự kiện tương tác để xem người gửi là người dùng HUMAN hay BOT.

Ví dụ sau đây cho thấy cách một ứng dụng trò chuyện cập nhật bản xem trước đường liên kết bất cứ khi nào người dùng nhấp vào nút Giao cho tôi bằng cách cập nhật trường Người được giao của thẻ và vô hiệu hoá nút này.

Ứng dụng trò chuyện xem trước một đường liên kết có phiên bản thẻ mới nhất được đính kèm vào một tin nhắn

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

Ví dụ này gửi một thông báo dạng thẻ bằng cách trả về JSON thẻ. Bạn cũng có thể sử dụng dịch vụ thẻ 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'}}
            }]}}
          ]}]
        }
      }]
    };
  }
}

Giới hạn và điểm cần cân nhắc

Khi bạn định cấu hình bản xem trước đường liên kết cho ứng dụng Chat, hãy lưu ý những giới hạn và điểm cần cân nhắc sau:

  • Mỗi ứng dụng Chat hỗ trợ tính năng xem trước đường liên kết cho tối đa 5 mẫu URL.
  • Các ứng dụng trò chuyện xem trước một đường liên kết cho mỗi tin nhắn. Nếu có nhiều đường liên kết có thể xem trước trong một tin nhắn, thì chỉ đường liên kết có thể xem trước đầu tiên được xem trước.
  • Các ứng dụng trò chuyện chỉ xem trước những đường liên kết bắt đầu bằng https://, vì vậy, https://support.example.com/cases/ có thể xem trước, nhưng support.example.com/cases/ thì không.
  • Trừ phi tin nhắn có chứa thông tin khác được gửi đến ứng dụng Chat, chẳng hạn như lệnh gạch chéo, nếu không, chỉ URL của đường liên kết được gửi đến ứng dụng Chat bằng tính năng xem trước đường liên kết.
  • Nếu người dùng đăng đường liên kết, thì ứng dụng Chat chỉ có thể cập nhật thẻ xem trước đường liên kết nếu người dùng tương tác với thẻ, chẳng hạn như nhấp vào nút. Bạn không thể gọi phương thức update() của Chat API trên tài nguyên Message để cập nhật thông báo của người dùng một cách không đồng bộ.
  • Các ứng dụng trò chuyện phải xem trước đường liên kết cho mọi người trong không gian, vì vậy, thông báo phải bỏ qua trường privateMessageViewer.

Khi triển khai tính năng xem trước đường liên kết, có thể bạn cần gỡ lỗi ứng dụng Chat bằng cách đọc nhật ký của ứng dụng. Để đọc nhật ký, hãy truy cập vào Trình khám phá nhật ký trên bảng điều khiển Google Cloud.