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

لمنع تبديل السياق عندما يشارك المستخدمون رابطًا في 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 تفاعلي في "برمجة تطبيقات Google"، أكمِل البدء السريع هذا.

يمكنك تسجيل روابط محدّدة، مثل example.com وsupport.example.com وsupport.example.com/cases/، كأنماط عناوين URL في صفحة ضبط تطبيق Chat ضمن Google Cloud Console حتى يتمكّن تطبيق 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 للبطاقة. يمكنك أيضًا استخدام خدمة بطاقة "برمجة تطبيقات Google".

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

العقدة/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.