معاينة الروابط

لمنع تبديل السياق عندما يشارك المستخدمون رابطًا في Google Chat، يمكن لتطبيق Chat معاينة الرابط من خلال إرفاق بطاقة برسالته تقدّم المزيد من المعلومات وتسمح للمستخدمين باتخاذ إجراء مباشرةً من Google Chat.

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

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

عندما يضيف مستخدم رابطًا إلى رسالته، تظهر شريحة تُعلمه بأنّه قد تتم معاينة الرابط في تطبيق Chat.

شريحة تشير إلى أنّ تطبيق Chat قد يعرض معاينة لرابط

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

تطبيق Chat يعرِض معاينة لرابط من خلال إرفاق بطاقة بالرسالة

إلى جانب الرابط، تقدّم البطاقة معلومات إضافية عنه، بما في ذلك العناصر التفاعلية مثل الأزرار. يمكن لتطبيق Chat تعديل البطاقة المرفقة استجابةً لتفاعلات المستخدِم، مثل النقرات على الأزرار.

إذا لم يكن المستخدم يريد أن يعرِض تطبيق Chat مقتطفًا من الرابط من خلال إرفاق بطاقة برسالته، يمكنه منع المعاينة من خلال النقر على في شريحة المعاينة. يمكن للمستخدمين إزالة البطاقة المرفقة في أي وقت من خلال النقر على إزالة المعاينة.

المتطلبات الأساسية

Node.js

تطبيق Google Chat مفعَّل فيه الميزات التفاعلية لإنشاء تطبيق Chat تفاعلي باستخدام خدمة HTTP، أكمِل الخطوات الأساسية هذه.

Python

تطبيق Google Chat مفعَّل فيه الميزات التفاعلية لإنشاء تطبيق Chat تفاعلي باستخدام خدمة HTTP، أكمِل الخطوات الأساسية هذه.

Java

تطبيق Google Chat مفعَّل فيه الميزات التفاعلية لإنشاء تطبيق Chat تفاعلي باستخدام خدمة HTTP، أكمِل الخطوات الأساسية هذه.

برمجة تطبيقات

تطبيق Google Chat مفعَّل فيه الميزات التفاعلية لإنشاء تطبيق Chat تفاعلي في Apps Script، أكمِل الخطوات الأساسية هذه.

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

قائمة إعدادات معاينات الروابط

  1. افتح Google Cloud console.
  2. بجانب "Google Cloud"، انقر على السهم المتّجه للأسفل وافتح مشروع تطبيق Chat.
  3. في حقل البحث، اكتب Google Chat API وانقر على Google Chat API.
  4. انقر على إدارة > الإعداد.
  5. ضمن "معاينات الروابط"، أضِف نمط عنوان URL أو عدِّله.
    1. لضبط معاينات الروابط لنمط عنوان URL جديد، انقر على إضافة نمط عنوان URL.
    2. لتعديل الإعدادات الخاصة بنمط عنوان URL حالي، انقر على السهم المتّجه للأسفل .
  6. في الحقل نمط المضيف، أدخِل نطاق نمط عنوان URL. سيعاين تطبيق Chat الروابط المؤدية إلى هذا النطاق.

    لكي يعرض تطبيق Chat معاينات للروابط المتعلّقة بنطاق فرعي معيّن، مثل subdomain.example.com، يجب تضمين النطاق الفرعي.

    لكي يعرض تطبيق Chat معاينة الروابط للملف الشخصي بالكامل، حدِّد حرف بدل مع علامة النجمة (*) كاسم النطاق الفرعي. على سبيل المثال، يتطابق *.example.com مع subdomain.example.com و any.number.of.subdomains.example.com.

  7. في حقل بادئة المسار، أدخِل مسارًا لإضافته إلى نطاق نمط المضيف.

    لمطابقة جميع عناوين URL في نطاق نمط المضيف، اترك بادئة المسار فارغة.

    على سبيل المثال، إذا كان نمط المضيف هو support.example.com، لمطابقة عناوين URL لحالات العميل المُستضافة على support.example.com/cases/، أدخِل cases/.

  8. انقر على تم.

  9. انقر على حفظ.

الآن، عندما يُدرِج أحد المستخدمين رابطًا يتطابق مع نمط عنوان URL لمعاينة الرابط في رسالة في مساحة Chat تتضمّن تطبيق Chat، يُعاين تطبيقك الرابط.

بعد ضبط إعدادات معاينة الرابط لرابط معيّن، يمكن لتطبيق Chat التعرّف على الرابط ومعاينته من خلال إرفاق المزيد من المعلومات به.

داخل مساحات Chat التي تتضمّن تطبيق Chat، عندما تحتوي رسالة أحد المستخدمين على رابط يتطابق مع نمط عنوان URL لمعاينة الرابط، يتلقّى تطبيق Chat حدث تفاعل MESSAGE. يحتوي ملف JSON المخصّص لحدث التفاعل على الحقل matchedUrl:

JSON

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

من خلال التحقّق من توفّر حقل matchedUrl في حمولة حدث MESSAGE، يمكن لتطبيق Chat إضافة معلومات إلى الرسالة التي تتضمّن الرابط الذي تمت معاينته. يمكن لتطبيق Chat إرسال ردّ باستخدام رسالة نصية أساسية أو إرفاق بطاقة.

الردّ برسالة نصية

بالنسبة إلى الردود الأساسية، يمكن لتطبيق Chat معاينة رابط من خلال الردّ على رابط باستخدام رسالة نصية بسيطة. يُرفِق هذا المثال رسالة تُكرّر عنوان 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/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. يُرفِق هذا المثال بطاقة أساسية.

تطبيق Chat يعرِض معاينة لرابط من خلال إرفاق بطاقة بالرسالة

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

برمجة تطبيقات

يُرسِل هذا المثال رسالة بطاقة من خلال عرض ملف 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'}}
          }]}}
        ]}]
      }
    }]
  };
}

يمكن لتطبيق Chat تعديل بطاقة معاينة الرابط عندما يتفاعل المستخدمون معها، مثلاً بالنقر على زر في البطاقة.

لتعديل البطاقة، يجب أن يعالج تطبيق Chat حدث التفاعل CARD_CLICKED ويعرض القيمة actionResponse استنادًا إلى المستخدم الذي أرسل الرسالة التي تحتوي على معاينة الرابط:

  • إذا أرسل مستخدم الرسالة، اضبط القيمة actionResponse.type على UPDATE_USER_MESSAGE_CARDS.
  • إذا أرسل تطبيق Chat الرسالة، اضبط القيمة actionResponse.type على UPDATE_MESSAGE.

لتحديد مُرسِل الرسالة، يمكنك استخدام حقل message.sender.type لحدث التفاعل لمعرفة ما إذا كان المُرسِل مستخدم HUMAN أو BOT.

يوضّح المثال التالي كيفية تعديل تطبيق Chat لمعاينة الرابط كلما نقر مستخدم على الزر إسناد إليّ من خلال تعديل حقل المخصّص في البطاقة وإيقاف الزر.

تطبيق Chat يعرِض معاينة لرابط يتضمّن نسخة معدَّلة من بطاقة مرفقة برسالة

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

برمجة تطبيقات

يُرسِل هذا المثال رسالة بطاقة من خلال عرض ملف 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'}}
            }]}}
          ]}]
        }
      }]
    };
  }
}

الحدود والاعتبارات

عند ضبط معاينات الروابط لتطبيق Chat، يُرجى مراعاة القيود والاعتبارات التالية:

  • يتيح كل تطبيق Chat معاينات الروابط لما يصل إلى 5 نماذج لعناوين URL.
  • تعرض تطبيقات Chat معاينة لرابط واحد في كل رسالة. إذا كانت هناك عدة روابط قابلة للمعاينة في رسالة واحدة، لن تتم معاينة سوى الرابط الأول القابل للمعاينة.
  • لا تعرض تطبيقات Chat سوى معاينات للروابط التي تبدأ بالرمز https://، لذا يتم عرض معاينات لتطبيق https://support.example.com/cases/، ولكن ليس لتطبيق support.example.com/cases/.
  • ما لم تتضمّن الرسالة معلومات أخرى يتم إرسالها إلى تطبيق Chat، مثل أمر الشرطة المائلة، يتم إرسال عنوان URL للرابط فقط إلى تطبيق Chat من خلال معاينات الروابط.
  • إذا نشر مستخدم الرابط، لا يمكن لتطبيق Chat تعديل بطاقة معاينة الرابط إلا إذا تفاعل المستخدمون مع البطاقة، مثلاً من خلال هُمسة زر. لا يمكنك استدعاء طريقة update() في Chat API على مورد Message لتعديل رسالة مستخدم بشكل غير متزامن.
  • يجب أن تُعاين تطبيقات المحادثة الروابط لجميع المستخدمين في المساحة، لذا يجب أن تحذف الرسالة الحقل privateMessageViewer.

أثناء تنفيذ معاينات الروابط، قد تحتاج إلى تصحيح أخطاء تطبيق Chat من خلال قراءة سجلات التطبيق. لقراءة السجلّات، انتقِل إلى مستكشف السجلّات في وحدة تحكّم Google Cloud.