หากต้องการป้องกันการเปลี่ยนบริบทเมื่อผู้ใช้แชร์ลิงก์ใน Google Chat แอป Chat จะดูตัวอย่างลิงก์ได้โดยการแนบการ์ดไปกับข้อความที่จะให้ข้อมูลเพิ่มเติมและช่วยให้ผู้ใช้ดำเนินการจาก Google Chat ได้โดยตรง
ตัวอย่างเช่น สมมติว่าพื้นที่ใน Google Chat ที่มีตัวแทนฝ่ายบริการลูกค้าของบริษัททั้งหมด บวกกับแอป Chat ที่ชื่อว่า Case-y ตัวแทนมักจะแชร์ลิงก์ของเคสฝ่ายบริการลูกค้าในพื้นที่ใน Chat และทุกครั้งที่เพื่อนร่วมงานต้องเปิดลิงก์ของเคสเพื่อดูรายละเอียด เช่น ผู้ได้รับมอบหมาย สถานะ และเรื่อง ในทำนองเดียวกัน หากมีคนต้องการเข้าเป็นเจ้าของเคสหรือเปลี่ยนสถานะ ก็จะต้องเปิดลิงก์นั้น
การแสดงตัวอย่างลิงก์จะช่วยให้ Case-y ที่เป็นแอป Chat ของพื้นที่ทำงานสามารถแนบการ์ดที่แสดงผู้ได้รับมอบหมาย สถานะ และเรื่องได้เมื่อมีคนแชร์ลิงก์เคส ปุ่มบนการ์ดจะช่วยให้ตัวแทนเข้าเป็นเจ้าของเคสและเปลี่ยนสถานะจากสตรีมแชทได้โดยตรง
วิธีการทำงานของการแสดงตัวอย่างลิงก์
เมื่อมีผู้เพิ่มลิงก์ในข้อความ ชิปจะปรากฏขึ้นเพื่อแจ้งให้ทราบว่าแอป Chat อาจดูตัวอย่างลิงก์

หลังจากส่งข้อความ ระบบจะส่งลิงก์ไปยังแอป Chat ซึ่งจะสร้างและแนบการ์ดไปกับข้อความของผู้ใช้

ข้างๆ ลิงก์จะมีข้อมูลเพิ่มเติมเกี่ยวกับลิงก์ ซึ่งรวมถึงองค์ประกอบแบบอินเทอร์แอกทีฟ เช่น ปุ่ม แอป Chat สามารถอัปเดตการ์ดที่แนบมาตามการโต้ตอบของผู้ใช้ เช่น การคลิกปุ่ม
หากไม่ต้องการให้แอป Chat แสดงตัวอย่างลิงก์โดยการแนบการ์ดลงในข้อความ ผู้ใช้จะไม่สามารถดูตัวอย่างได้โดยคลิก cancel บนชิปการแสดงตัวอย่าง ผู้ใช้สามารถนำการ์ดที่แนบออกได้ทุกเมื่อโดยคลิกนำการแสดงตัวอย่างออก
ลงทะเบียนลิงก์เฉพาะ เช่น example.com
, support.example.com
และ support.example.com/cases/
เป็นรูปแบบ URL ในหน้าการกำหนดค่าของแอป Chat ในคอนโซล Google Cloud เพื่อให้แอป Chat ดูตัวอย่างได้

- เปิดคอนโซล Google Cloud
- ถัดจาก "Google Cloud" ให้คลิกลูกศรลง arrow_drop_down แล้วเปิดโปรเจ็กต์ของแอป Chat
- ในช่องค้นหา ให้พิมพ์
Google Chat API
แล้วคลิก Google Chat API
- คลิก Manage > Configuration
- ในส่วนตัวอย่างลิงก์ ให้เพิ่มหรือแก้ไขรูปแบบ URL
- หากต้องการกำหนดค่าตัวอย่างลิงก์สำหรับรูปแบบ URL ใหม่ ให้คลิกเพิ่มรูปแบบ URL
- หากต้องการแก้ไขการกำหนดค่าสำหรับรูปแบบ URL ที่มีอยู่ ให้คลิกลูกศรลง expand_more
ในช่องรูปแบบโฮสต์ ให้ป้อนโดเมนของรูปแบบ URL แอป Chat จะแสดงตัวอย่างลิงก์ไปยังโดเมนนี้
หากต้องการมีลิงก์แสดงตัวอย่างแอป Chat สำหรับโดเมนย่อยที่เฉพาะเจาะจง เช่น subdomain.example.com
ให้ใส่โดเมนย่อย
หากต้องการลิงก์แสดงตัวอย่างแอป Chat สำหรับทั้งโดเมน ให้ระบุอักขระไวลด์การ์ดที่มีเครื่องหมายดอกจัน (*) เป็นโดเมนย่อย ตัวอย่างเช่น *.example.com
ตรงกับ subdomain.example.com
และ any.number.of.subdomains.example.com
ในช่องคำนำหน้าเส้นทาง ให้ป้อนเส้นทางที่จะต่อท้ายโดเมนรูปแบบโฮสต์
หากต้องการจับคู่ URL ทั้งหมดในโดเมนรูปแบบโฮสต์ ให้เว้นคำนำหน้าเส้นทางว่างไว้
เช่น หากรูปแบบโฮสต์คือ support.example.com
เพื่อจับคู่ URL สำหรับเคสที่โฮสต์ที่ support.example.com/cases/
ให้ป้อน cases/
คลิกเสร็จสิ้น
คลิกบันทึก
ในตอนนี้ เมื่อมีคนใส่ลิงก์ที่ตรงกับรูปแบบ URL ตัวอย่างลิงก์กับข้อความในพื้นที่ใน Chat ที่มีแอป Chat ของคุณ แอปจะแสดงตัวอย่างลิงก์ดังกล่าว
แสดงตัวอย่างลิงก์
หลังจากกำหนดค่าการแสดงตัวอย่างลิงก์สำหรับลิงก์หนึ่งๆ แล้ว แอป Chat จะจดจำและดูตัวอย่างลิงก์ได้โดยการแนบข้อมูลเพิ่มเติมไปกับลิงก์
ภายในพื้นที่ใน Chat ที่มีแอป Chat เมื่อข้อความของผู้อื่นมีลิงก์ที่ตรงกับรูปแบบ URL ของตัวอย่างลิงก์ แอป Chat จะได้รับเหตุการณ์การโต้ตอบ MESSAGE
เพย์โหลด JSON สำหรับเหตุการณ์การโต้ตอบมีช่อง matchedUrl
ดังนี้
JSON
message {
. . . // other message attributes redacted
"matchedUrl": {
"url": "https://support.example.com/cases/case123"
},
. . . // other message attributes redacted
}
การตรวจหาช่อง matchedUrl
ในเพย์โหลดเหตุการณ์ MESSAGE
จะช่วยให้แอป Chat เพิ่มข้อมูลลงในข้อความได้ด้วยลิงก์แสดงตัวอย่าง แอป Chat สามารถ
ตอบกลับด้วยข้อความง่ายๆ หรือแนบการ์ดก็ได้
ตอบกลับด้วย SMS
สำหรับคำตอบอย่างง่าย แอป Chat สามารถดูตัวอย่างลิงก์ได้โดยการตอบกลับด้วยข้อความตัวอักษรง่ายๆ
ไปยังลิงก์ ตัวอย่างนี้แนบข้อความที่ระบุ URL ของลิงก์ซ้ำซึ่งตรงกับรูปแบบ URL ของตัวอย่างลิงก์
แนบบัตร
หากต้องการแนบการ์ดไปยังลิงก์ที่แสดงตัวอย่าง ให้แสดงผล ActionResponse
ประเภท UPDATE_USER_MESSAGE_CARDS
ตัวอย่างนี้แนบการ์ดแบบง่ายมาด้วย

Node.js
/**
* Responds to messages that have links whose URLs match URL patterns
* configured for link previewing.
*
* @param {Object} req Request sent from Google Chat.
* @param {Object} res Response to send back.
*/
exports.onMessage = (req, res) => {
if (req.method === 'GET' || !req.body.message) {
res.send(
'Hello! This function is meant to be used in a Google Chat Space.');
}
// Checks for the presence of event.message.matchedUrl and attaches a card
// if present
if (req.body.message.matchedUrl) {
res.json({
'actionResponse': {'type': 'UPDATE_USER_MESSAGE_CARDS'},
'cardsV2': [
{
'cardId': 'attachCard',
'card': {
'header': {
'title': 'Example Customer Service Case',
'subtitle': 'Case basics',
},
'sections': [
{
'widgets': [
{'keyValue': {'topLabel': 'Case ID', 'content': 'case123'}},
{'keyValue': {'topLabel': 'Assignee', 'content': 'Charlie'}},
{'keyValue': {'topLabel': 'Status', 'content': 'Open'}},
{
'keyValue': {
'topLabel': 'Subject', 'content': 'It won"t turn on...',
}
},
],
},
{
'widgets': [
{
'buttons': [
{
'textButton': {
'text': 'OPEN CASE',
'onClick': {
'openLink': {
'url': 'https://support.example.com/orders/case123',
},
},
},
},
{
'textButton': {
'text': 'RESOLVE CASE',
'onClick': {
'openLink': {
'url': 'https://support.example.com/orders/case123?resolved=y',
},
},
},
},
{
'textButton': {
'text': 'ASSIGN TO ME',
'onClick': {
'action': {
'actionMethodName': 'assign',
},
},
},
},
],
},
],
},
],
},
},
],
});
}
// If the Chat app doesn’t detect a link preview URL pattern, it says so.
res.json({'text': 'No matchedUrl detected.'});
};
Apps Script
/**
* Responds to messages that have links whose URLs match URL patterns
* configured for link previewing.
*
* @param {Object} event The event object from Chat API.
* @return {Object} Response from the Chat app attached to the message with
* the previewed link.
*/
function onMessage(event) {
// Checks for the presence of event.message.matchedUrl and attaches a card
// if present
if (event.message.matchedUrl) {
return {
'actionResponse': {
'type': 'UPDATE_USER_MESSAGE_CARDS',
},
'cardsV2': [{
'cardId': 'attachCard',
'card': {
'header': {
'title': 'Example Customer Service Case',
'subtitle': 'Case basics',
},
'sections': [{
'widgets': [
{'keyValue': {'topLabel': 'Case ID', 'content': 'case123'}},
{'keyValue': {'topLabel': 'Assignee', 'content': 'Charlie'}},
{'keyValue': {'topLabel': 'Status', 'content': 'Open'}},
{
'keyValue': {
'topLabel': 'Subject', 'content': 'It won\'t turn on...',
},
},
],
},
{
'widgets': [{
'buttons': [
{
'textButton': {
'text': 'OPEN CASE',
'onClick': {
'openLink': {
'url': 'https://support.example.com/orders/case123',
},
},
},
},
{
'textButton': {
'text': 'RESOLVE CASE',
'onClick': {
'openLink': {
'url': 'https://support.example.com/orders/case123?resolved=y',
},
},
},
},
{
'textButton': {
'text': 'ASSIGN TO ME',
'onClick': {'action': {'actionMethodName': 'assign'}},
},
},
],
}],
}],
},
}],
};
}
// If the Chat app doesn’t detect a link preview URL pattern, it says so.
return {'text': 'No matchedUrl detected.'};
}
อัปเดตบัตร
หากต้องการอัปเดตการ์ดที่แนบมากับลิงก์ที่แสดงตัวอย่าง ให้แสดงผล ActionResponse
ประเภท UPDATE_USER_MESSAGE_CARDS
แอปใน Chat จะอัปเดตการ์ดที่แสดงตัวอย่างลิงก์เป็นการตอบกลับไปยังเหตุการณ์การโต้ตอบในแอป Chat เท่านั้น
แอปแชทจะอัปเดตการ์ดเหล่านี้โดยเรียกใช้ Chat API แบบไม่พร้อมกันไม่ได้
การแสดงตัวอย่างลิงก์ไม่รองรับการส่งคืน ActionResponse
ประเภท UPDATE_MESSAGE
เนื่องจาก UPDATE_MESSAGE
จะอัปเดตข้อความทั้งหมดแทนการ์ด จึงจะอัปเดตได้เฉพาะเมื่อแอป Chat สร้างข้อความต้นฉบับเท่านั้น การแสดงตัวอย่างลิงก์จะแนบการ์ดไปกับข้อความที่ผู้ใช้สร้างขึ้น แอป Chat จึงไม่มีสิทธิ์อัปเดตการ์ด
หากต้องการให้ฟังก์ชันอัปเดตทั้งการ์ดที่ผู้ใช้สร้างขึ้นและที่แอปสร้างขึ้นในสตรีม Chat ให้ตั้งค่า ActionResponse
แบบไดนามิกโดยพิจารณาว่าแอป Chat หรือผู้ใช้เป็นผู้สร้างข้อความหรือไม่
- หากผู้ใช้สร้างข้อความ ให้ตั้งค่า
ActionResponse
เป็น UPDATE_USER_MESSAGE_CARDS
- หากแอป Chat สร้างข้อความขึ้น ให้ตั้งค่า
ActionResponse
เป็น UPDATE_MESSAGE
ซึ่งทำได้ 2 วิธี ได้แก่ การระบุและตรวจหา actionMethodName
ที่กําหนดเองซึ่งเป็นส่วนหนึ่งของพร็อพเพอร์ตี้ onclick
ของการ์ดที่แนบมา (ซึ่งระบุว่าข้อความเป็นสิ่งที่ผู้ใช้สร้าง) หรือตรวจสอบว่าข้อความสร้างโดยผู้ใช้หรือไม่
หากต้องการใช้ actionMethodName
เพื่อจัดการเหตุการณ์การโต้ตอบ CARD_CLICKED
ในการ์ดที่แสดงตัวอย่างอย่างเหมาะสม ให้ตั้งค่า actionMethodName
ที่กำหนดเองเป็นส่วนหนึ่งของพร็อพเพอร์ตี้ onclick
ของการ์ดที่แนบ ดังนี้
JSON
. . . // Preview card details
{
"textButton": {
"text": "ASSIGN TO ME",
"onClick": {
// actionMethodName identifies the button to help determine the
// appropriate ActionResponse.
"action": {
"actionMethodName": "assign",
}
}
}
}
. . . // Preview card details
เมื่อใช้ "actionMethodName": "assign"
ในการระบุปุ่มซึ่งเป็นส่วนหนึ่งของตัวอย่างลิงก์ คุณจะแสดงผล ActionResponse
ที่ถูกต้องแบบไดนามิกได้โดยตรวจสอบ actionMethodName
ที่ตรงกัน ดังนี้
ตัวเลือกที่ 2: ตรวจสอบประเภทผู้ส่ง
ตรวจสอบว่า message.sender.type
เป็น HUMAN
หรือ BOT
หาก HUMAN
ให้ตั้งค่า ActionResponse
เป็น UPDATE_USER_MESSAGE_CARDS
หรือตั้งค่า ActionResponse
เป็น UPDATE_MESSAGE
ดังนี้
สาเหตุทั่วไปในการอัปเดตการ์ดคือการตอบสนองต่อการคลิกปุ่ม กดปุ่มมอบหมายให้กับฉันจากส่วนก่อนหน้าในหัวข้อแนบการ์ด ตัวอย่างทั้งหมดต่อไปนี้เป็นการอัปเดตการ์ดเพื่อให้มีการระบุว่าเป็น "คุณ" หลังจากที่ผู้ใช้คลิกมอบหมายให้กับฉัน ตัวอย่างนี้จะตั้งค่า ActionResponse
แบบไดนามิกโดยตรวจสอบประเภทผู้ส่ง
ตัวอย่างที่สมบูรณ์: Case-y แอป Chat ฝ่ายบริการลูกค้า
นี่คือรหัสที่สมบูรณ์ของ Case-y ซึ่งเป็นแอป Chat ที่แสดงตัวอย่างลิงก์ไปยังเคสที่แชร์ในพื้นที่ใน Chat ซึ่งตัวแทนฝ่ายบริการลูกค้าทำงานร่วมกัน
Node.js
/**
* Responds to messages that have links whose URLs match URL patterns
* configured for link previewing.
*
* @param {Object} req Request sent from Google Chat.
* @param {Object} res Response to send back.
*/
exports.onMessage = (req, res) => {
if (req.method === 'GET' || !req.body.message) {
res.send(
'Hello! This function is meant to be used in a Google Chat Space.');
}
// Checks for the presence of event.message.matchedUrl and attaches a card
// if present
if (req.body.message.matchedUrl) {
res.json(createMessage());
}
// Respond to button clicks on attached cards
if (req.body.type === 'CARD_CLICKED') {
// Checks whether the message event originated from a human or a Chat app
// and sets actionResponse.type to "UPDATE_USER_MESSAGE_CARDS if human or
// "UPDATE_MESSAGE" if Chat app.
const actionResponseType = req.body.action.actionMethodName === 'HUMAN' ?
'UPDATE_USER_MESSAGE_CARDS' :
'UPDATE_MESSAGE';
if (req.body.action.actionMethodName === 'assign') {
res.json(createMessage(actionResponseType, 'You'));
}
}
// If the Chat app doesn’t detect a link preview URL pattern, it says so.
res.json({'text': 'No matchedUrl detected.'});
};
/**
* Message to create a card with the correct response type and assignee.
*
* @param {string} actionResponseType
* @param {string} assignee
* @return {Object} a card with URL preview
*/
function createMessage(
actionResponseType = 'UPDATE_USER_MESSAGE_CARDS',
assignee = 'Charlie'
) {
return {
'actionResponse': {'type': actionResponseType},
'cardsV2': [
{
'cardId': 'previewLink',
'card': {
'header': {
'title': 'Example Customer Service Case',
'subtitle': 'Case basics',
},
'sections': [
{
'widgets': [
{'keyValue': {'topLabel': 'Case ID', 'content': 'case123'}},
{'keyValue': {'topLabel': 'Assignee', 'content': assignee}},
{'keyValue': {'topLabel': 'Status', 'content': 'Open'}},
{
'keyValue': {
'topLabel': 'Subject', 'content': 'It won"t turn on...',
},
},
],
},
{
'widgets': [
{
'buttons': [
{
'textButton': {
'text': 'OPEN CASE',
'onClick': {
'openLink': {
'url': 'https://support.example.com/orders/case123',
},
},
},
},
{
'textButton': {
'text': 'RESOLVE CASE',
'onClick': {
'openLink': {
'url': 'https://support.example.com/orders/case123?resolved=y',
},
},
},
},
{
'textButton': {
'text': 'ASSIGN TO ME',
'onClick': {
'action': {
'actionMethodName': 'assign',
},
},
},
},
],
},
],
},
],
}
},
],
};
}
Apps Script
/**
* Responds to messages that have links whose URLs match URL patterns
* configured for link previews.
*
* @param {Object} event The event object from Chat API.
* @return {Object} Response from the Chat app attached to the message with
* the previewed link.
*/
function onMessage(event) {
// Checks for the presence of event.message.matchedUrl and attaches a card
// if present
if (event.message.matchedUrl) {
return {
'actionResponse': {
'type': 'UPDATE_USER_MESSAGE_CARDS',
},
'cardsV2': [{
'cardId': 'previewLink',
'card': {
'header': {
'title': 'Example Customer Service Case',
'subtitle': 'Case basics',
},
'sections': [{
'widgets': [
{'keyValue': {'topLabel': 'Case ID', 'content': 'case123'}},
{'keyValue': {'topLabel': 'Assignee', 'content': 'Charlie'}},
{'keyValue': {'topLabel': 'Status', 'content': 'Open'}},
{
'keyValue': {
'topLabel': 'Subject', 'content': 'It won\'t turn on...',
}
},
],
},
{
'widgets': [{
'buttons': [
{
'textButton': {
'text': 'OPEN CASE',
'onClick': {
'openLink': {
'url': 'https://support.example.com/orders/case123',
},
},
},
},
{
'textButton': {
'text': 'RESOLVE CASE',
'onClick': {
'openLink': {
'url': 'https://support.example.com/orders/case123?resolved=y',
},
},
},
},
{
'textButton': {
'text': 'ASSIGN TO ME',
'onClick': {'action': {'actionMethodName': 'assign'}}
},
},
],
}],
}],
},
}],
};
}
// If the Chat app doesn’t detect a link preview URL pattern, it says so.
return {'text': 'No matchedUrl detected.'};
}
/**
* Updates a card that was attached to a message with a previewed link.
*
* @param {Object} event The event object from Chat API.
* @return {Object} Response from the Chat app. Either a new card attached to
* the message with the previewed link, or an update to an existing card.
*/
function onCardClick(event) {
// Checks whether the message event originated from a human or a Chat app
// and sets actionResponse to "UPDATE_USER_MESSAGE_CARDS if human or
// "UPDATE_MESSAGE" if Chat app.
const actionResponseType = event.message.sender.type === 'HUMAN' ?
'UPDATE_USER_MESSAGE_CARDS' :
'UPDATE_MESSAGE';
// To respond to the correct button, checks the button's actionMethodName.
if (event.action.actionMethodName === 'assign') {
return assignCase(actionResponseType);
}
}
/**
* Updates a card to say that "You" are the assignee after clicking the Assign
* to Me button.
*
* @param {String} actionResponseType Which actionResponse the Chat app should
* use to update the attached card based on who created the message.
* @return {Object} Response from the Chat app. Updates the card attached to
* the message with the previewed link.
*/
function assignCase(actionResponseType) {
return {
'actionResponse': {
// Dynamically returns the correct actionResponse type.
'type': actionResponseType,
},
'cardsV2': [{
'cardId': 'assignCase',
'card': {
'header': {
'title': 'Example Customer Service Case',
'subtitle': 'Case basics',
},
'sections': [{
'widgets': [
{'keyValue': {'topLabel': 'Case ID', 'content': 'case123'}},
{'keyValue': {'topLabel': 'Assignee', 'content': 'You'}},
{'keyValue': {'topLabel': 'Status', 'content': 'Open'}},
{
'keyValue': {
'topLabel': 'Subject', 'content': 'It won\'t turn on...',
}
},
],
},
{
'widgets': [{
'buttons': [
{
'textButton': {
'text': 'OPEN CASE',
'onClick': {
'openLink': {
'url': 'https://support.example.com/orders/case123',
},
},
},
},
{
'textButton': {
'text': 'RESOLVE CASE',
'onClick': {
'openLink': {
'url': 'https://support.example.com/orders/case123?resolved=y',
},
},
},
},
{
'textButton': {
'text': 'ASSIGN TO ME',
'onClick': {'action': {'actionMethodName': 'assign'}},
},
},
],
}],
}],
},
}],
};
}
ข้อจำกัดและข้อควรพิจารณา
โปรดคํานึงถึงขีดจํากัดและข้อควรพิจารณาต่อไปนี้เมื่อกําหนดค่าตัวอย่างลิงก์สําหรับแอป Chat
- แอป Chat แต่ละแอปรองรับตัวอย่างลิงก์สําหรับรูปแบบ URL สูงสุด 5 รูปแบบ
- แอป Chat จะแสดงตัวอย่าง 1 ลิงก์ต่อข้อความ หากข้อความเดียวมีลิงก์ที่แสดงตัวอย่างได้หลายรายการ เฉพาะลิงก์แรกที่แสดงตัวอย่างได้
- แอป Chat จะแสดงตัวอย่างเฉพาะลิงก์ที่ขึ้นต้นด้วย
https://
ดังนั้น https://support.example.com/cases/
จะแสดงตัวอย่าง แต่ support.example.com/cases/
ไม่ได้แสดงตัวอย่าง
- ระบบจะส่งเฉพาะ URL ของลิงก์ไปยังแอป Chat ผ่านการแสดงตัวอย่างลิงก์ เว้นแต่ว่าข้อความจะมีข้อมูลอื่นๆ ที่ส่งไปยังแอป Chat เช่น คำสั่งเครื่องหมายทับ
- การ์ดที่แนบกับลิงก์แสดงตัวอย่างจะรองรับเฉพาะ
ActionResponse
ประเภท UPDATE_USER_MESSAGE_CARDS
และตอบสนองต่อเหตุการณ์การโต้ตอบกับแอปใน Chat เท่านั้น ตัวอย่างลิงก์ไม่รองรับคำขออัปเดตการ์ด (UPDATE_MESSAGE
) หรือแบบไม่พร้อมกันเพื่ออัปเดตการ์ดที่แนบมากับลิงก์แสดงตัวอย่างผ่าน Chat API หากต้องการดูข้อมูลเพิ่มเติม โปรดดูหัวข้ออัปเดตการ์ด
แก้ไขข้อบกพร่องตัวอย่างลิงก์
เมื่อใช้ตัวอย่างลิงก์ คุณอาจต้องแก้ไขข้อบกพร่องของแอป Chat โดยการอ่านบันทึกของแอป หากต้องการอ่านบันทึก ให้ไปที่ Logs Explorer ในคอนโซล Google Cloud