لمنع تبديل السياق عند مشاركة المستخدمين لرابط في Google Chat، يمكن لتطبيق Chat معاينة الرابط من خلال إرفاق بطاقة برسالتهم لتوفير المزيد من المعلومات والسماح للمستخدمين باتخاذ إجراء من Google Chat مباشرةً.
على سبيل المثال، تخيل مساحة في Google Chat تتضمن جميع موظفي خدمة العملاء في الشركة بالإضافة إلى تطبيق Chat باسم Case-y. يشارك موظّفو الدعم بشكل متكرر روابط إلى طلبات الحصول على خدمة العملاء في "مساحة Chat"، وفي كل مرة يجرون فيها ذلك، على زملائهم فتح رابط الطلب للاطّلاع على تفاصيل مثل المُسنَد إليه والحالة والموضوع. وبالمثل، إذا أراد شخص ما الحصول على ملكية إحدى الحالات أو تغيير الحالة، عليه فتح الرابط.
تتيح معاينة الروابط لتطبيق Chat، Case-y، المتوفّر في المساحة، إرفاق بطاقة توضّح المُسنَد إليه والحالة والموضوع عندما يشارك أحد الأشخاص رابط طلب. تتيح الأزرار على البطاقة للوكلاء الحصول على ملكية الطلب وتغيير الحالة مباشرةً من سلسلة المحادثات.
آلية عمل معاينة الروابط
عندما يضيف مستخدم رابطًا إلى رسالته، تظهر شريحة تُعلمك بأنّ تطبيق Chat قد يعاين الرابط.

بعد إرسال الرسالة، يتم إرسال الرابط إلى تطبيق Chat الذي ينشئ البطاقة ويرفقها برسالة المستخدم.

بجانب الرابط، توفر البطاقة معلومات إضافية حول الرابط، بما في ذلك عناصر تفاعلية مثل الأزرار. يمكن لتطبيق Chat تعديل البطاقة المرفقة استجابةً لتفاعلات المستخدمين، مثل النقرات على الأزرار.
إذا لم يريد أحد المستخدمين أن يعاين تطبيق Chat رابطه من خلال إرفاق بطاقة برسالته، يمكنه منع المعاينة من خلال النقر على cancel على شريحة المعاينة. يمكن للمستخدمين إزالة البطاقة المرفقة في أي وقت بالنقر على إزالة المعاينة.
يمكنك تسجيل روابط محدّدة، مثل example.com
وsupport.example.com
وsupport.example.com/cases/
، كأنماط عناوين URL على صفحة ضبط تطبيق Chat في Google Cloud Console حتى يتمكّن تطبيق Chat من معاينتها.

- افتَح Google Cloud Console.
- بجانب "Google Cloud"، انقر على السهم المتّجه للأسفل arrow_drop_down وافتح مشروع تطبيق Chat.
- في حقل البحث، اكتب
Google Chat API
وانقر على Google Chat API.
- انقر على إدارة > الضبط.
- ضمن "معاينات الروابط"، أضِف نمط عنوان 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 إما الرد برسالة نصية بسيطة أو إرفاق بطاقة.
الرد برسالة نصية
للحصول على ردود بسيطة، يمكن لتطبيق 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.'});
};
برمجة تطبيقات
/**
* 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 تحديث هذه البطاقات من خلال استدعاء Chat API
بشكل غير متزامن.
لا تتيح معاينة الروابط عرض رمز ActionResponse
من النوع UPDATE_MESSAGE
. بما أنّ تطبيق UPDATE_MESSAGE
يعدّل الرسالة بأكملها بدلاً من البطاقة فقط، لن يعمل إلا إذا كان تطبيق Chat قد أنشأ الرسالة الأصلية. تؤدّي ميزة "معاينة الرابط" إلى إرفاق بطاقة برسالة أنشأها المستخدم، لذا لا يملك تطبيق Chat إذنًا لتعديلها.
لضمان تعديل وظيفة لكل من البطاقات التي أنشأها المستخدمون وتلك التي أنشأها التطبيق في ساحة مشاركات Chat، يمكنك ضبط ActionResponse
ديناميكيًا استنادًا إلى ما إذا كان تطبيق Chat أو المستخدم قد أنشأ الرسالة.
- وإذا أنشأ مستخدم الرسالة، اضبط
ActionResponse
على UPDATE_USER_MESSAGE_CARDS
.
- إذا أنشأ تطبيق Chat الرسالة، اضبط
ActionResponse
على UPDATE_MESSAGE
.
هناك طريقتان لتنفيذ ذلك: تحديد 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',
},
},
},
},
],
},
],
},
],
}
},
],
};
}
برمجة تطبيقات
/**
* 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 معاينات الروابط لما يصل إلى 5 أنماط لعناوين URL.
- تعاين تطبيقات Chat رابطًا واحدًا لكل رسالة. في حال توفُّر روابط متعددة قابلة للمعاينة في رسالة واحدة، يتم فقط معاينات الرابط الأول القابل للمعاينة.
- لا تعاين تطبيقات Chat سوى الروابط التي تبدأ بـ
https://
، في حين لا تتم معاينة الروابط من خلال https://support.example.com/cases/
، على عكس support.example.com/cases/
.
- ما لم تتضمّن الرسالة معلومات أخرى يتم إرسالها إلى تطبيق Chat، مثل أمر شرطة مائلة، يتم إرسال عنوان URL للرابط فقط إلى تطبيق Chat من خلال معاينات الروابط.
- تتوافق البطاقات المرفقة بالروابط التي تمت معاينتها مع
ActionResponse
من النوع UPDATE_USER_MESSAGE_CARDS
فقط، وتستجيب لحدث تفاعل مع تطبيق Chat فقط. لا تتوافق معاينات الروابط مع طلبات UPDATE_MESSAGE
أو الطلبات غير المتزامنة لتعديل البطاقات المرتبطة برابط تمت معاينتها من خلال Chat API. لمزيد من المعلومات، يُرجى الاطِّلاع على تعديل بطاقة.
تصحيح أخطاء معاينات الروابط
أثناء تنفيذ معاينات الروابط، قد تحتاج إلى تصحيح الأخطاء في تطبيق Chat من خلال قراءة سجلات التطبيق. لقراءة السجلات، يُرجى الانتقال إلى مستكشف السجلات على Google Cloud Console.