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

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

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

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

عندما يضيف مستخدم رابطًا إلى رسالته، يظهر رمز صغير يتيح له معرفة أنّ تطبيق 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" ليتمكّن تطبيق Chat من معاينتها.

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

  1. افتح Google Cloud Console.
  2. بجانب "Google Cloud"، انقر على السهم المتّجه للأسفل وافتح مشروع تطبيق Chat.
  3. في حقل البحث، اكتب Google Chat API وانقر على واجهة برمجة تطبيقات Google Chat.
  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.
  • تعرض تطبيقات المحادثة معاينة لرابط واحد في كل رسالة. إذا كانت رسالة واحدة تتضمّن روابط متعددة يمكن معاينتها، ستتم معاينة الرابط الأول فقط.
  • تعرض تطبيقات الدردشة معاينات للروابط التي تبدأ بـ https:// فقط، لذا تعرض https://support.example.com/cases/ معاينات، ولكن support.example.com/cases/ لا تعرضها.
  • ما لم تتضمّن الرسالة معلومات أخرى يتم إرسالها إلى تطبيق Chat، مثل أمر يبدأ بشرطة مائلة، لن يتم إرسال سوى عنوان URL للرابط إلى تطبيق Chat من خلال معاينات الروابط.
  • إذا نشر مستخدم الرابط، لا يمكن لتطبيق Chat تعديل بطاقة معاينة الرابط إلا إذا تفاعل المستخدمون مع البطاقة، مثلاً من خلال النقر على زر. لا يمكنك استدعاء طريقة update() في Chat API على المورد Message لتعديل رسالة مستخدم بشكل غير متزامن.
  • يجب أن تعاين تطبيقات الدردشة الروابط لجميع المشاركين في المساحة، لذا يجب أن تحذف الرسالة الحقل privateMessageViewer.

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