הצגת תצוגה מקדימה של קישורים בהודעות ב-Google Chat

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

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

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

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

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

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

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

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

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

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

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

Node.js

תוסף ל-Google Workspace שמרחיב את Google Chat. כדי ליצור אחד, תוכלו להיעזר במדריך למתחילים בנושא HTTP.

Apps Script

תוסף ל-Google Workspace שמרחיב את Google Chat. כדי ליצור אחד, תוכלו לעיין במדריך למתחילים ב-Apps Script.

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

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

  1. פותחים את מסוף Google Cloud.
  2. לצד 'Google Cloud', לוחצים על החץ למטה ופותחים את הפרויקט של אפליקציית Chat.
  3. בשדה החיפוש, מקלידים Google Chat API ולוחצים על Google Chat API.
  4. לוחצים על ניהול > הגדרה.
  5. בקטע 'תצוגה מקדימה של קישורים', מוסיפים או עורכים תבנית של כתובת URL.
    1. כדי להגדיר תצוגות מקדימות של קישורים לתבנית חדשה של כתובת URL, לוחצים על הוספת תבנית של כתובת URL.
    2. כדי לערוך את ההגדרה של תבנית כתובת URL קיימת, לוחצים על החץ למטה .
  6. בשדה Host pattern (תבנית מארח), מזינים את הדומיין של תבנית ה-URL. אפליקציית Chat תציג תצוגה מקדימה של קישורים לדומיין הזה.

    כדי שאפשר יהיה לראות תצוגה מקדימה של קישורים בתת-דומיין ספציפי, כמו subdomain.example.com, צריך לכלול את תת-הדומיין.

    כדי שאפשר יהיה לראות תצוגה מקדימה של קישורים לכל הדומיין באפליקציית Chat, צריך לציין תו כללי לחיפוש עם כוכבית (*) בתור תת-הדומיין. לדוגמה, הערך *.example.com תואם לערך subdomain.example.com ולערך any.number.of.subdomains.example.com.

  7. בשדה Path prefix, מזינים נתיב שרוצים לצרף לדומיין של תבנית המארח.

    כדי להתאים לכל כתובות ה-URL בדומיין של תבנית המארח, משאירים את השדה תחילית הנתיב ריק.

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

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

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

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

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

במרחבים משותפים ב-Chat שכוללים את אפליקציית Chat, כשהודעה של משתמש מכילה קישור שתואם לדפוס של כתובת URL של תצוגה מקדימה של קישור, אפליקציית Chat מקבלת אובייקט אירוע עם MessagePayload. במטען הייעודי, האובייקט message.matchedUrl מכיל את הקישור שהמשתמש כלל בהודעה:

JSON

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

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

שליחת תשובה בהודעת טקסט

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

Node.js

/**
 * Google Cloud Function that handles messages that have links whose
 * URLs match URL patterns configured for link previewing.
 *
 *
 * @param {Object} req Request sent from Google Chat space
 * @param {Object} res Response to send back
 */
exports.previewLinks = function previewLinks(req, res) {
  const chatEvent = req.body.chat;

  // Handle MESSAGE events
  if(chatEvent.messagePayload) {
    return res.send(handlePreviewLink(chatEvent.messagePayload.message));
  // Handle button clicks
  } else if(chatEvent.buttonClickedPayload) {
    return res.send(handleCardClick(chatEvent.buttonClickedPayload.message));
  }
};

/**
 * Respond to messages that have links whose URLs match URL patterns configured
 * for link previewing.
 *
 * @param {Object} chatMessage The chat message object from Google Workspace Add On event.
 * @return {Object} Response to send back depending on the matched URL.
 */
function handlePreviewLink(chatMessage) {
  // If the Chat app does not detect a link preview URL pattern, reply
  // with a text message that says so.
  if (!chatMessage.matchedUrl) {
    return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
      text: 'No matchedUrl detected.'
    }}}}};
  }

  // Reply with a text message for URLs of the subdomain "text"
  if (chatMessage.matchedUrl.url.includes("text.example.com")) {
    return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
      text: 'event.chat.messagePayload.message.matchedUrl.url: ' + chatMessage.matchedUrl.url
    }}}}};
  }
}

Apps Script

/**
 * Reply to messages that have links whose URLs match the pattern
 * "text.example.com" configured for link previewing.
 *
 * @param {Object} event The event object from Google Workspace Add-on.
 *
 * @return {Object} The action response.
 */
function onMessage(event) {
  // Stores the Google Chat event as a variable.
  const chatMessage = event.chat.messagePayload.message;

  // If the Chat app doesn't detect a link preview URL pattern, reply
  // with a text message that says so.
  if (!chatMessage.matchedUrl) {
    return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
      text: 'No matchedUrl detected.'
    }}}}};
  }

  // Reply with a text message for URLs of the subdomain "text".
  if (chatMessage.matchedUrl.url.includes("text.example.com")) {
    return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
      text: 'event.chat.messagePayload.message.matchedUrl.url: ' + chatMessage.matchedUrl.url
    }}}}};
  }
}

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

בדוגמה הבאה, אפליקציית Chat מוסיפה כרטיס תצוגה מקדימה להודעות שמכילות את תבנית כתובת ה-URL support.example.com.

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

Node.js

/**
 * Google Cloud Function that handles messages that have links whose
 * URLs match URL patterns configured for link previewing.
 *
 *
 * @param {Object} req Request sent from Google Chat space
 * @param {Object} res Response to send back
 */
exports.previewLinks = function previewLinks(req, res) {
  const chatEvent = req.body.chat;

  // Handle MESSAGE events
  if(chatEvent.messagePayload) {
    return res.send(handlePreviewLink(chatEvent.messagePayload.message));
  // Handle button clicks
  } else if(chatEvent.buttonClickedPayload) {
    return res.send(handleCardClick(chatEvent.buttonClickedPayload.message));
  }
};

/**
 * Respond to messages that have links whose URLs match URL patterns configured
 * for link previewing.
 *
 * @param {Object} chatMessage The chat message object from Google Workspace Add On event.
 * @return {Object} Response to send back depending on the matched URL.
 */
function handlePreviewLink(chatMessage) {
  // Attach a card to the message for URLs of the subdomain "support"
  if (chatMessage.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 { hostAppDataAction: { chatDataAction: { updateInlinePreviewAction: { 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',
          // Use runtime environment variable set with self URL
          onClick: { action: { function: process.env.BASE_URL }}
        }]}}
        ]}]
      }
    }]}}}};
  }
}

Apps Script

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

/**
 * Attach a card to messages that have links whose URLs match the pattern
 * "support.example.com" configured for link previewing.
 *
 * @param {Object} event The event object from Google Workspace Add-on.
 *
 * @return {Object} The action response.
 */
function onMessage(event) {
  // Stores the Google Chat event as a variable.
  const chatMessage = event.chat.messagePayload.message;

  // Attach a card to the message for URLs of the subdomain "support".
  if (chatMessage.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 { hostAppDataAction: { chatDataAction: { updateInlinePreviewAction: { cardsV2: [{
      cardId: 'attachCard',
      card: {
        header: {
          title: 'Example Customer Service Case',
          subtitle: 'Case summary',
        },
        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',
          // Clicking this button triggers the execution of the function
          // "assign" from the Apps Script project.
          onClick: { action: { function: 'assign'}}
        }]}}
        ]}]
      }
    }]}}}};
  }
}

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

כדי לעדכן את הכרטיס, אפליקציית Chat צריכה להחזיר את הפעולה DataActions עם אחד מהאובייקטים הבאים של ChatDataActionMarkup:

כדי לקבוע מי שלח את ההודעה, משתמשים בתוכן של האירוע (buttonClickedPayload) כדי לבדוק אם השולח (message.sender.type) מוגדר כ-HUMAN (משתמש) או כ-BOT (אפליקציית Chat).

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

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

Node.js

/**
 * Google Cloud Function that handles messages that have links whose
 * URLs match URL patterns configured for link previewing.
 *
 *
 * @param {Object} req Request sent from Google Chat space
 * @param {Object} res Response to send back
 */
exports.previewLinks = function previewLinks(req, res) {
  const chatEvent = req.body.chat;

  // Handle MESSAGE events
  if(chatEvent.messagePayload) {
    return res.send(handlePreviewLink(chatEvent.messagePayload.message));
  // Handle button clicks
  } else if(chatEvent.buttonClickedPayload) {
    return res.send(handleCardClick(chatEvent.buttonClickedPayload.message));
  }
};

/**
 * Respond to clicks by assigning user and updating the card that was attached to a
 * message with a previewed link.
 *
 * @param {Object} chatMessage The chat message object from Google Workspace Add On event.
 * @return {Object} Action response depending on the original message.
 */
function handleCardClick(chatMessage) {
  // Creates the updated card that displays "You" for the assignee
  // and that disables the button.
  //
  // 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.
  const message = { 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,
          // Use runtime environment variable set with self URL
          onClick: { action: { function: process.env.BASE_URL }}
        }]}}
      ]}]
    }
  }]};

  // Checks whether the message event originated from a human or a Chat app
  // to return the adequate action response.
  if(chatMessage.sender.type === 'HUMAN') {
    return { hostAppDataAction: { chatDataAction: { updateInlinePreviewAction: message }}};
  } else {
    return { hostAppDataAction: { chatDataAction: { updateMessageAction: message }}};
  }
}

Apps Script

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

/**
 * Assigns and updates the card that's attached to a message with a
 * previewed link of the pattern "support.example.com".
 *
 * @param {Object} event The event object from the Google Workspace Add-on.
 *
 * @return {Object} Action response depending on the message author.
 */
function assign(event) {
  // Creates the updated card that displays "You" for the assignee
  // and that disables the button.
  //
  // 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.
  const message = { cardsV2: [{
    cardId: 'attachCard',
    card: {
      header: {
        title: 'Example Customer Service Case',
        subtitle: 'Case summary',
      },
      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'}}
        }]}}
      ]}]
    }
  }]};

  // Use the adequate action response type. It depends on whether the message
  // the preview link card is attached to was created by a human or a Chat app.
  if(event.chat.buttonClickedPayload.message.sender.type === 'HUMAN') {
    return { hostAppDataAction: { chatDataAction: { updateInlinePreviewAction: message }}};
  } else {
    return { hostAppDataAction: { chatDataAction: { updateMessageAction: message }}};
  }
}

מגבלות ושיקולים

כשמגדירים תצוגות מקדימות של קישורים באפליקציית Chat, חשוב לשים לב למגבלות ולשיקולים הבאים:

  • בכל אפליקציית Chat יש תמיכה בתצוגות מקדימות של קישורים עד 5 דפוסי כתובות URL.
  • באפליקציות Chat מוצגת תצוגה מקדימה של קישור אחד בכל הודעה. אם יש כמה קישורים שאפשר להציג תצוגה מקדימה שלהם בהודעה אחת, רק התצוגה המקדימה של הקישור הראשון תופיע.
  • אפליקציות צ'אט מציגות תצוגה מקדימה רק של קישורים שמתחילים ב-https://, כך ש-https://support.example.com/cases/ מציגה תצוגה מקדימה אבל support.example.com/cases/ לא.
  • אלא אם ההודעה כוללת מידע נוסף שנשלח לאפליקציית Chat, כמו פקודת קו נטוי, רק כתובת ה-URL של הקישור נשלחת לאפליקציית Chat באמצעות תצוגות מקדימות של קישורים.
  • אם משתמש מפרסם את הקישור, אפליקציית Chat יכולה לעדכן את הכרטיס עם התצוגה המקדימה של הקישור רק אם המשתמשים יוצרים אינטראקציה עם הכרטיס, למשל לוחצים על לחצן. אי אפשר להפעיל את השיטה update() של Chat API במשאב Message כדי לעדכן הודעה של משתמש באופן אסינכרוני.
  • אפליקציות צ'אט צריכות להציג תצוגה מקדימה של קישורים לכל המשתתפים במרחב המשותף, ולכן אסור לכלול את השדה privateMessageViewer בהודעה.

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