Xem trước đường liên kết trong tin nhắn trên Google Chat

Để ngăn việc chuyển đổi ngữ cảnh khi người dùng chia sẻ đường liên kết trong Google Chat, ứng dụng Chat 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ọ để cung cấp thêm thông tin và cho phép mọi người hành động ngay trong Google Chat.

Trong Google Chat, các tiện ích bổ sung sẽ xuất hiện với người dùng dưới dạng ứng dụng Google Chat. Để tìm hiểu thêm, hãy xem bài viết Tổng quan về việc mở rộng Google Chat.

Ví dụ: hãy tưởng tượng một không gian Google Chat bao gồm tất cả nhân viên hỗ trợ khách hàng của một công ty cùng với một ứng dụng Chat có tên Case-y. 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 Chat. Mỗi khi họ chia sẻ, các đồng nghiệp phải mở đường liên kết đến trường hợp đó để xem thông tin chi tiết như người được giao, trạng thái và tiêu đề. Tương tự, nếu muốn sở hữu một trường hợp hoặc thay đổi trạng thái, người dùng 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 nội bộ của không gian, Case-y, đính kèm một thẻ cho biết người được giao, trạng thái và tiêu đề bất cứ khi nào ai đó chia sẻ đường liên kết đến trường hợp. Các nút trên thẻ cho phép nhân viên hỗ trợ nhận quyền sở hữu trường hợp và thay đổi trạng thái ngay trong luồng trò chuyện.

Khi ai đó thêm đường liên kết vào tin nhắn, một khối 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 đó.

Khối cho biết một ứng dụng Chat có thể xem trước đườ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 trò chuyện xem trước đườ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 còn cung cấp thêm thông tin về đường liên kết, bao gồm cả các thành phần tương tác như nút. Ứng dụng Chat của bạn có thể cập nhật thẻ đính kèm để phản hồi các lượt 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 việc xem trước bằng cách nhấp vào trên khối 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 tiện ích bổ sung của Google Workspace mở rộng Google Chat. Để tạo một ứng dụng, hãy hoàn tất phần Bắt đầu nhanh về HTTP.

Apps Script

Một tiện ích bổ sung của Google Workspace mở rộng Google Chat. Để tạo một ứng dụng, hãy hoàn tất phần Bắt đầu nhanh với Apps Script.

Đă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 Google Cloud Console để ứ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ẫ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 các đường liên kết cho toàn bộ miền, hãy chỉ định một 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 URL cho các 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 ai đó thêm một đường liên kết khớp với mẫu URL của bản 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, ứ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 đó.

Bên trong không gian Chat có ứng dụng Chat, khi tin nhắn của ai đó 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 sẽ nhận được một đối tượng sự kiệnMessagePayload. Trong tải trọng, đối tượng message.matchedUrl chứa đường liên kết mà người dùng đưa vào tin nhắn:

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 bằng đường liên kết đã 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ó thể xem trước đường liên kết bằng cách trả lời bằng tin nhắn văn bản cho đườ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ẫu URL của bản xem trước đường liên kết.

Node.js

/**
 * Google Cloud Function that handles messages that have links whose
 * URLs match URL patterns configured for link previewing.
 *
 *
 * @param {Object} req Request sent from Google Chat space
 * @param {Object} res Response to send back
 */
exports.previewLinks = function previewLinks(req, res) {
  const chatEvent = req.body.chat;

  // Handle MESSAGE events
  if(chatEvent.messagePayload) {
    return res.send(handlePreviewLink(chatEvent.messagePayload.message));
  // Handle button clicks
  } else if(chatEvent.buttonClickedPayload) {
    return res.send(handleCardClick(chatEvent.buttonClickedPayload.message));
  }
};

/**
 * Respond to messages that have links whose URLs match URL patterns configured
 * for link previewing.
 *
 * @param {Object} chatMessage The chat message object from Google Workspace Add On event.
 * @return {Object} Response to send back depending on the matched URL.
 */
function handlePreviewLink(chatMessage) {
  // If the Chat app does not detect a link preview URL pattern, reply
  // with a text message that says so.
  if (!chatMessage.matchedUrl) {
    return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
      text: 'No matchedUrl detected.'
    }}}}};
  }

  // Reply with a text message for URLs of the subdomain "text"
  if (chatMessage.matchedUrl.url.includes("text.example.com")) {
    return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
      text: 'event.chat.messagePayload.message.matchedUrl.url: ' + chatMessage.matchedUrl.url
    }}}}};
  }
}

Apps Script

/**
 * Reply to messages that have links whose URLs match the pattern
 * "text.example.com" configured for link previewing.
 *
 * @param {Object} event The event object from Google Workspace Add-on.
 *
 * @return {Object} The action response.
 */
function onMessage(event) {
  // Stores the Google Chat event as a variable.
  const chatMessage = event.chat.messagePayload.message;

  // If the Chat app doesn't detect a link preview URL pattern, reply
  // with a text message that says so.
  if (!chatMessage.matchedUrl) {
    return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
      text: 'No matchedUrl detected.'
    }}}}};
  }

  // Reply with a text message for URLs of the subdomain "text".
  if (chatMessage.matchedUrl.url.includes("text.example.com")) {
    return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
      text: 'event.chat.messagePayload.message.matchedUrl.url: ' + chatMessage.matchedUrl.url
    }}}}};
  }
}

Để đính kèm thẻ vào đường liên kết đã xem trước, hãy trả về thao tác DataActions bằng đối tượng ChatDataActionMarkup thuộc loại UpdateInlinePreviewAction.

Trong ví dụ sau, ứng dụng Chat sẽ thêm thẻ xem trước vào các tin nhắn chứa mẫu URL support.example.com.

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

Node.js

/**
 * Google Cloud Function that handles messages that have links whose
 * URLs match URL patterns configured for link previewing.
 *
 *
 * @param {Object} req Request sent from Google Chat space
 * @param {Object} res Response to send back
 */
exports.previewLinks = function previewLinks(req, res) {
  const chatEvent = req.body.chat;

  // Handle MESSAGE events
  if(chatEvent.messagePayload) {
    return res.send(handlePreviewLink(chatEvent.messagePayload.message));
  // Handle button clicks
  } else if(chatEvent.buttonClickedPayload) {
    return res.send(handleCardClick(chatEvent.buttonClickedPayload.message));
  }
};

/**
 * Respond to messages that have links whose URLs match URL patterns configured
 * for link previewing.
 *
 * @param {Object} chatMessage The chat message object from Google Workspace Add On event.
 * @return {Object} Response to send back depending on the matched URL.
 */
function handlePreviewLink(chatMessage) {
  // Attach a card to the message for URLs of the subdomain "support"
  if (chatMessage.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 { hostAppDataAction: { chatDataAction: { updateInlinePreviewAction: { 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',
          // Use runtime environment variable set with self URL
          onClick: { action: { function: process.env.BASE_URL }}
        }]}}
        ]}]
      }
    }]}}}};
  }
}

Apps Script

Ví dụ này gửi thông báo thẻ bằng cách trả về JSON thẻ. Bạn cũng có thể sử dụng dịch vụ thẻ Apps Script.

/**
 * Attach a card to messages that have links whose URLs match the pattern
 * "support.example.com" configured for link previewing.
 *
 * @param {Object} event The event object from Google Workspace Add-on.
 *
 * @return {Object} The action response.
 */
function onMessage(event) {
  // Stores the Google Chat event as a variable.
  const chatMessage = event.chat.messagePayload.message;

  // Attach a card to the message for URLs of the subdomain "support".
  if (chatMessage.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 { hostAppDataAction: { chatDataAction: { updateInlinePreviewAction: { cardsV2: [{
      cardId: 'attachCard',
      card: {
        header: {
          title: 'Example Customer Service Case',
          subtitle: 'Case summary',
        },
        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',
          // Clicking this button triggers the execution of the function
          // "assign" from the Apps Script project.
          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 trả về thao tác DataActions với một trong các đối tượng ChatDataActionMarkup sau:

Để xác định người gửi tin nhắn, hãy sử dụng tải trọng sự kiện (buttonClickedPayload) để kiểm tra xem người gửi (message.sender.type) có được đặt thành HUMAN (người dùng) hay BOT (ứng dụng Chat) hay không.

Ví dụ sau đây cho thấy cách một ứng dụng Chat 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 Gán cho tôi bằng cách cập nhật trường Người được giao của thẻ và tắt 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 cập nhật được đính kèm vào một tin nhắn

Node.js

/**
 * Google Cloud Function that handles messages that have links whose
 * URLs match URL patterns configured for link previewing.
 *
 *
 * @param {Object} req Request sent from Google Chat space
 * @param {Object} res Response to send back
 */
exports.previewLinks = function previewLinks(req, res) {
  const chatEvent = req.body.chat;

  // Handle MESSAGE events
  if(chatEvent.messagePayload) {
    return res.send(handlePreviewLink(chatEvent.messagePayload.message));
  // Handle button clicks
  } else if(chatEvent.buttonClickedPayload) {
    return res.send(handleCardClick(chatEvent.buttonClickedPayload.message));
  }
};

/**
 * Respond to clicks by assigning user and updating the card that was attached to a
 * message with a previewed link.
 *
 * @param {Object} chatMessage The chat message object from Google Workspace Add On event.
 * @return {Object} Action response depending on the original message.
 */
function handleCardClick(chatMessage) {
  // Creates the updated card that displays "You" for the assignee
  // and that disables the button.
  //
  // 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.
  const message = { 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,
          // Use runtime environment variable set with self URL
          onClick: { action: { function: process.env.BASE_URL }}
        }]}}
      ]}]
    }
  }]};

  // Checks whether the message event originated from a human or a Chat app
  // to return the adequate action response.
  if(chatMessage.sender.type === 'HUMAN') {
    return { hostAppDataAction: { chatDataAction: { updateInlinePreviewAction: message }}};
  } else {
    return { hostAppDataAction: { chatDataAction: { updateMessageAction: message }}};
  }
}

Apps Script

Ví dụ này gửi thông báo thẻ bằng cách trả về JSON thẻ. Bạn cũng có thể sử dụng dịch vụ thẻ Apps Script.

/**
 * Assigns and updates the card that's attached to a message with a
 * previewed link of the pattern "support.example.com".
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 *
 * @return {Object} Action response depending on the message author.
 */
function assign(event) {
  // Creates the updated card that displays "You" for the assignee
  // and that disables the button.
  //
  // 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.
  const message = { cardsV2: [{
    cardId: 'attachCard',
    card: {
      header: {
        title: 'Example Customer Service Case',
        subtitle: 'Case summary',
      },
      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'}}
        }]}}
      ]}]
    }
  }]};

  // Use the adequate action response type. It depends on whether the message
  // the preview link card is attached to was created by a human or a Chat app.
  if(event.chat.buttonClickedPayload.message.sender.type === 'HUMAN') {
    return { hostAppDataAction: { chatDataAction: { updateInlinePreviewAction: message }}};
  } else {
    return { hostAppDataAction: { chatDataAction: { updateMessageAction: message }}};
  }
}

Giới hạn và điều 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ều cần cân nhắc sau:

  • Mỗi ứng dụng Chat hỗ trợ bản xem trước đường liên kết cho tối đa 5 mẫu URL.
  • Ứng dụng trò chuyện xem trước một đường liên kết cho mỗi tin nhắn. Nếu một tin nhắn có nhiều đường liên kết có thể xem trước, thì chỉ đường liên kết có thể xem trước đầu tiên mới xem trước.
  • Ứng dụng trò chuyện chỉ xem trước các đường liên kết bắt đầu bằng https://, vì vậy, https://support.example.com/cases/ sẽ 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, thì chỉ URL của đường liên kết mới được gửi đến ứng dụng Chat thông qua bản 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ư bằng một lượt 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 tin nhắn của người dùng một cách không đồng bộ.
  • Ứng dụng nhắn tin phải xem trước đường liên kết cho mọi người trong không gian, vì vậy, tin nhắn phải bỏ qua trường privateMessageViewer.

Khi triển khai bản xem trước đường liên kết, bạn có thể 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 Google Cloud Console.