תצוגה מקדימה של הקישורים

כדי למנוע מצב שבו המשתמשים משתפים קישור ב-Google Chat, אפליקציית Chat יכולה להציג תצוגה מקדימה של הקישור. לשם כך, אפשר לצרף להודעה שלהם כרטיס שמספק מידע נוסף ומאפשר לאנשים לבצע פעולות ישירות מ-Google Chat.

לדוגמה, נניח שיש מרחב ב-Google Chat שכולל את כל סוכני שירות הלקוחות של חברה, וגם אפליקציית Chat בשם 'Case-y'. הרבה פעמים נציגים משתפים במרחבים ב-Chat קישורים לבקשות תמיכה של שירות לקוחות, ובכל פעם שהקולגות שלהם צריכים לפתוח את הקישור לפנייה כדי לראות פרטים כמו מקבל ההקצאה, הסטטוס והנושא. בדומה לכך, אם מישהו רוצה לקבל בעלות על בקשת תמיכה או לשנות את הסטטוס שלו, הוא צריך לפתוח את הקישור.

התצוגה המקדימה של הקישור מאפשרת לאפליקציית Chat, שגרת במרחב המשותף, קאסיי, לצרף כרטיס שבו מוצג מקבל ההקצאה, הסטטוס והנושא בכל פעם שמישהו משתף קישור לפנייה. הלחצנים בכרטיס מאפשרים לנציגים לקבל בעלות על הפנייה ולשנות את הסטטוס ישירות מהצ'אט.

כשמישהו יוסיף קישור להודעה שלו, יופיע צ'יפ שיודיע לו שאפליקציית Chat עשויה להציג את הקישור בתצוגה מקדימה.

צ'יפ שמציין שיכול להיות שתהיה תצוגה מקדימה של קישור באפליקציית Chat

אחרי שליחת ההודעה, הקישור נשלח לאפליקציית Chat, ואז יוצר ומצרף את הכרטיס להודעה של המשתמש.

אפליקציית Chat מציגה תצוגה מקדימה של קישור על ידי צירוף כרטיס להודעה

לצד הקישור, הכרטיס מספק מידע נוסף על הקישור, כולל רכיבים אינטראקטיביים כמו לחצנים. אפליקציית Chat יכולה לעדכן את הכרטיס המצורף בתגובה לאינטראקציות של משתמשים, כמו קליקים על לחצנים.

אם מישהו לא רוצה שאפליקציית Chat תוכל להציג את הקישור שלו בתצוגה מקדימה על ידי צירוף כרטיס להודעה, הוא יכול ללחוץ על בצ'יפ של התצוגה המקדימה כדי למנוע את הצגת התצוגה המקדימה. המשתמשים יכולים להסיר את הכרטיס המצורף בכל שלב בלחיצה על הסרת התצוגה המקדימה.

דרישות מוקדמות

Node.js

אפליקציית Google Chat שמופעלת בה תכונות אינטראקטיביות. כדי ליצור להשתמש בשירות HTTP באפליקציית Chat האינטראקטיבית. במדריך למתחילים מוסבר איך עושים את זה.

Apps Script

אפליקציית Google Chat שמופעלת בה תכונות אינטראקטיביות. כדי ליצור כדי להשתמש באפליקציית Chat האינטראקטיבית ב-Apps Script, צריך להשלים את המדריך למתחילים.

כדאי לרשום קישורים ספציפיים כמו example.com, support.example.com ו-support.example.com/cases/ – כתבניות URL בדף ההגדרות של אפליקציית Chat במסוף Google Cloud, כדי שאפליקציית Chat תוכל להציג אותם בתצוגה מקדימה.

תפריט ההגדרות של התצוגה המקדימה לקישורים

  1. פותחים את מסוף Google Cloud.
  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 בדומיין של דפוס המארח, משאירים את השדה Path prefix (קידומת נתיב).

    לדוגמה, אם דפוס המארח הוא support.example.com, כדי להתאים כתובות URL לבקשות תמיכה שמתארחות ב-support.example.com/cases/, צריך להזין cases/.

  8. לוחצים על סיום.

  9. לוחצים על שמירה.

מעכשיו, בכל פעם שמישהו יכלול קישור שתואם לתבנית כתובת ה-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 המטען הייעודי (Payload), אפליקציית Chat יכולה להוסיף מידע עם הקישור בתצוגה המקדימה. אפליקציית Chat יכולה או להשיב באמצעות הודעת טקסט פשוטה או לצרף כרטיס.

תשובה באמצעות הודעת טקסט

אפליקציית Chat יכולה לראות תצוגה מקדימה של הקישור בתשובות פשוטות באמצעות הודעת טקסט פשוטה, לקישור. בדוגמה הזו מצורפת הודעה שחוזרת על כתובת האתר של הקישור תואם לדפוס כתובת אתר של תצוגה מקדימה של קישור.

Node.js

node/preview-link/simple-text-message.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) {
    return res.send(
      'Hello! This function is meant to be used in a Google Chat Space.');
  }

  // Checks for the presence of event.message.matchedUrl and responds with a
  // text message if present
  if (req.body.message.matchedUrl) {
    return res.json({
      'text': 'req.body.message.matchedUrl.url: ' +
        req.body.message.matchedUrl.url,
    });
  }

  // If the Chat app doesn’t detect a link preview URL pattern, it says so.
  return res.json({'text': 'No matchedUrl detected.'});
};

Apps Script

apps-script/preview-link/simple-text-message.gs
/**
 * 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 responds with a
  // text message if present
  if (event.message.matchedUrl) {
    return {
      'text': 'event.message.matchedUrl.url: ' + event.message.matchedUrl.url,
    };
  }

  // 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 מציגה תצוגה מקדימה של קישור על ידי צירוף כרטיס להודעה

Node.js

node/preview-link/attach-card.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) {
    return 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) {
    return 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.
  return res.json({'text': 'No matchedUrl detected.'});
};

Apps Script

בדוגמה הזו, נשלחת הודעת כרטיס על ידי חזרה כרטיס JSON. אפשר גם להשתמש שירות הכרטיסים של Apps Script.

apps-script/preview-link/attach-card.gs
/**
 * 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 של הכרטיס המצורף (שמזהה את ההודעה כהודעה שנוצרה על ידי משתמש) או לבדוק אם ההודעה נוצרה על ידי משתמש.

אפשרות 1: מחפשים את actionMethodName

כדי להשתמש ב-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 תואם:

Node.js

node/preview-link/update-card.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) {
    return res.send(
      'Hello! This function is meant to be used in a Google Chat Space.');
  }

  // Respond to button clicks on attached cards
  if (req.body.type === 'CARD_CLICKED') {
    // Checks for the presence of "actionMethodName": "assign" and sets
    // actionResponse.type to "UPDATE_USER"MESSAGE_CARDS" if present or
    // "UPDATE_MESSAGE" if absent.
    const actionResponseType = req.body.action.actionMethodName === 'assign' ?
      'UPDATE_USER_MESSAGE_CARDS' :
      'UPDATE_MESSAGE';

    if (req.body.action.actionMethodName === 'assign') {
      return res.json({
        'actionResponse': {

          // Dynamically returns the correct actionResponse type.
          'type': actionResponseType,
        },

        // Preview card details
        'cardsV2': [{}],
      });
    }
  }
};

Apps Script

בדוגמה הזו, נשלחת הודעה בכרטיס על ידי חזרה כרטיס JSON. אפשר גם להשתמש שירות הכרטיסים של Apps Script.

apps-script/preview-link/update-card.gs
/**
 * 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 for the presence of "actionMethodName": "assign" and sets
  // actionResponse.type to "UPDATE_USER"MESSAGE_CARDS" if present or
  // "UPDATE_MESSAGE" if absent.
  const actionResponseType = event.action.actionMethodName === 'assign' ?
    'UPDATE_USER_MESSAGE_CARDS' :
    'UPDATE_MESSAGE';

  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,
    },
    // Preview card details
    'cardsV2': [{}],
  };
}

אפשרות 2: בודקים את סוג השולח

צריך לבדוק אם הערך של message.sender.type הוא HUMAN או BOT. אם הערך הוא HUMAN, צריך להגדיר את ActionResponse לערך UPDATE_USER_MESSAGE_CARDS. אחרת, צריך להגדיר את ActionResponse לערך UPDATE_MESSAGE. לשם כך:

Node.js

node/preview-link/sender-type.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) {
    return res.send(
      'Hello! This function is meant to be used in a Google Chat Space.');
  }

  // 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';

    return res.json({
      'actionResponse': {

        // Dynamically returns the correct actionResponse type.
        'type': actionResponseType,
      },

      // Preview card details
      'cardsV2': [{}],
    });
  }
};

Apps Script

בדוגמה הזו, נשלחת הודעת כרטיס על ידי חזרה כרטיס JSON. אפשר גם להשתמש שירות הכרטיסים של Apps Script.

apps-script/preview-link/sender-type.gs
/**
 * 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.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';

  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,
    },
    // Preview card details
    'cardsV2': [{}],
  };
}

סיבה טיפוסית לעדכון כרטיס היא קליק על לחצן. לזכור את הלחצן הקצאה לי מהקטע הקודם, צירוף כרטיס. בדוגמה המלאה שבהמשך מוצג עדכון של הכרטיס כך שיהיה כתוב שהוא מוקצה אל 'את/ה'. אחרי שמשתמש לוחץ על הקצאה לי. בדוגמה הזו מגדירים באופן דינמי את ActionResponse על ידי בדיקת סוג השולח.

לדוגמה: (case-y), אפליקציית Chat של שירות הלקוחות.

הנה הקוד המלא של Case-y, אפליקציית Chat שמציגה תצוגה מקדימה של קישורים לבקשות תמיכה ששותפו במרחב ב-Chat שבו נציגי שירות לקוחות עובדים.

Node.js

node/preview-link/preview-link.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) {
    return res.send(
      'Hello! This function is meant to be used in a Google Chat Space.');
  }

  // 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') {
      return res.json(createMessage(actionResponseType, 'You'));
    }
  }

  // Checks for the presence of event.message.matchedUrl and attaches a card
  // if present
  if (req.body.message.matchedUrl) {
    return res.json(createMessage());
  }

  // If the Chat app doesn’t detect a link preview URL pattern, it says so.
  return 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

בדוגמה הזו, נשלחת הודעה בכרטיס על ידי חזרה כרטיס JSON. אפשר גם להשתמש שירות הכרטיסים של Apps Script.

apps-script/preview-link/preview-link.gs
/**
 * 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 בתצוגה מקדימה.
  • תצוגה מקדימה של קישור אחד לכל הודעה מאפליקציות צ'אט. אם בהודעה אחת יש כמה קישורים שאפשר להציג בתצוגה מקדימה, רק הקישור הראשון בתצוגה מקדימה מופיע בתצוגה מקדימה.
  • אפליקציות צ'אט מציגות תצוגה מקדימה של קישורים שמתחילים ב-https:// בלבד, כך שהתצוגה המקדימה של https://support.example.com/cases/ לא מופיעה בתצוגה המקדימה של support.example.com/cases/.
  • אלא אם ההודעה כוללת מידע נוסף שנשלח לאפליקציית Chat, כמו פקודת לוכסן, רק כתובת ה-URL של הקישור נשלחת לאפליקציית Chat באמצעות תצוגה מקדימה של קישורים.
  • כרטיסים שמצורפים לקישורים שמוצגים בתצוגה מקדימה תומכים רק ב-ActionResponse מסוג UPDATE_USER_MESSAGE_CARDS, ורק בתגובה לאירוע אינטראקציה של אפליקציית Chat. התצוגה המקדימה של הקישורים לא תומכת ב-UPDATE_MESSAGE או בבקשות אסינכרוניות לעדכון כרטיסים שמצורפים לקישור שמוצג בתצוגה מקדימה דרך Chat API. מידע נוסף על עדכון כרטיס
  • אפליקציות צ'אט חייבות לראות תצוגה מקדימה של הקישורים לכל מי שבמרחב המשותף, ההודעה חייבת להשמיט את השדה privateMessageViewer השדה הזה.

כשמטמיעים תצוגות מקדימות של קישורים, יכול להיות שתצטרכו לקרוא את היומנים של האפליקציה כדי לנפות באגים באפליקציית Chat. כדי לקרוא את היומנים, צריך להיכנס אל Logs Explorer במסוף Google Cloud.