แสดงตัวอย่างลิงก์

เพื่อป้องกันไม่ให้ผู้ใช้เปลี่ยนบริบทเมื่อผู้ใช้แชร์ลิงก์ใน Google Chat แอป Chat จะแสดงตัวอย่างลิงก์ได้โดยแนบการ์ดไปกับข้อความเพื่อให้ข้อมูลเพิ่มเติมและช่วยให้ผู้ใช้ดำเนินการจาก Google Chat ได้โดยตรง

ตัวอย่างเช่น สมมติว่าพื้นที่ใน Google Chat ที่มีตัวแทนฝ่ายบริการลูกค้าของบริษัททั้งหมด 1 รายร่วมกับแอป Chat ชื่อ Case-y ตัวแทนมักจะแชร์ลิงก์เคสฝ่ายบริการลูกค้าในพื้นที่ใน Chat และทุกครั้งที่เพื่อนร่วมงานต้องเปิดลิงก์ของเคสเพื่อดูรายละเอียดต่างๆ เช่น ผู้รับมอบหมาย สถานะ และเรื่อง ในทำนองเดียวกัน หากมีผู้ต้องการเป็นเจ้าของเคสหรือเปลี่ยนสถานะ ก็จะต้องเปิดลิงก์

การแสดงตัวอย่างลิงก์จะช่วยให้ Case-y ที่เป็นแอป Chat ของพื้นที่ทำงานสามารถแนบการ์ดที่แสดงผู้ได้รับมอบหมาย สถานะ และเรื่องได้ทุกครั้งที่มีคนแชร์ลิงก์เคส ปุ่มบนการ์ดจะช่วยให้ตัวแทนเข้าเป็นเจ้าของเคสและเปลี่ยนสถานะจากสตรีมแชทได้โดยตรง

เมื่อมีคนเพิ่มลิงก์ในข้อความ ชิปจะปรากฏขึ้นเพื่อให้บุคคลดังกล่าวทราบว่าแอป Chat อาจดูตัวอย่างลิงก์

ชิประบุว่าแอป Chat อาจดูตัวอย่างลิงก์

หลังจากส่งข้อความ ระบบจะส่งลิงก์ไปยังแอป Chat ซึ่งจะสร้างและแนบการ์ดไปกับข้อความของผู้ใช้

แอป Chat แสดงตัวอย่างลิงก์โดยการแนบการ์ดไปกับข้อความ

ด้านข้างของลิงก์ การ์ดจะให้ข้อมูลเพิ่มเติมเกี่ยวกับลิงก์นั้น ซึ่งรวมถึงองค์ประกอบแบบอินเทอร์แอกทีฟ เช่น ปุ่ม แอป Chat จะอัปเดตการ์ดที่แนบมาเพื่อตอบสนองการโต้ตอบของผู้ใช้ เช่น การคลิกปุ่ม

หากผู้ใช้ไม่ต้องการให้แอป Chat แสดงตัวอย่างลิงก์ของตนเองโดยการแนบการ์ดลงในข้อความ ผู้ใช้จะไม่สามารถดูตัวอย่างได้โดยคลิก บนชิปตัวอย่าง ผู้ใช้นำการ์ดที่แนบออกได้ทุกเมื่อโดยคลิกนำตัวอย่างออก

ลงทะเบียนลิงก์ที่เจาะจง เช่น 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 ทั้งหมดในโดเมนรูปแบบโฮสต์ ให้เว้นคำนำหน้าเส้นทางว่างไว้

    ตัวอย่างเช่น ถ้ารูปแบบโฮสต์คือ 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 จะช่วยให้แอป Chat เพิ่มข้อมูลลงในข้อความได้ด้วยลิงก์ตัวอย่าง แอป Chat จะตอบกลับด้วยข้อความธรรมดาหรือแนบการ์ดก็ได้

ตอบกลับด้วย SMS

หากต้องการคำตอบง่ายๆ แอป Chat จะดูตัวอย่างลิงก์ได้โดยการตอบข้อความง่ายๆ ไปยังลิงก์ ตัวอย่างนี้จะแนบข้อความที่แสดง URL ของลิงก์ซ้ำซึ่งตรงกับรูปแบบ URL ของตัวอย่างลิงก์

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

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

ซึ่งทำได้ 2 วิธี ได้แก่ การระบุและตรวจหา 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

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

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 แบบไดนามิกโดยตรวจสอบประเภทผู้ส่ง

ตัวอย่างแบบเต็ม: กรณีตัวอย่างคือแอป 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

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 แต่ละแอปรองรับการแสดงตัวอย่างลิงก์สำหรับรูปแบบ URL สูงสุด 5 รูปแบบ
  • แอป Chat จะแสดงตัวอย่าง 1 ลิงก์ต่อข้อความ หากข้อความเดียวมีลิงก์ที่แสดงตัวอย่างได้หลายลิงก์ จะมีเพียงลิงก์ตัวอย่างแรกที่แสดงตัวอย่างได้
  • แอป Chat จะแสดงตัวอย่างเฉพาะลิงก์ที่ขึ้นต้นด้วย https:// ดังนั้น https://support.example.com/cases/ จึงจะแสดงตัวอย่าง แต่ support.example.com/cases/ จะไม่แสดงตัวอย่าง
  • ระบบจะส่งเฉพาะ URL ของลิงก์ไปยังแอป Chat ผ่านตัวอย่างลิงก์เท่านั้น เว้นแต่ว่าข้อความจะมีข้อมูลอื่นๆ ที่ส่งไปยังแอป Chat เช่น คำสั่งเครื่องหมายทับ
  • การ์ดที่แนบมากับลิงก์ตัวอย่างรองรับเฉพาะ ActionResponse ประเภท UPDATE_USER_MESSAGE_CARDS และตอบสนองต่อเหตุการณ์การโต้ตอบในแอป Chat เท่านั้น ตัวอย่างลิงก์ไม่รองรับคำขอ UPDATE_MESSAGE หรือคำขออัปเดตการ์ดที่แนบมากับลิงก์แสดงตัวอย่างผ่าน Chat API แบบไม่พร้อมกัน หากต้องการดูข้อมูลเพิ่มเติม โปรดดูหัวข้ออัปเดตการ์ด

เมื่อใช้ตัวอย่างลิงก์ คุณอาจต้องแก้ไขข้อบกพร่องของแอป Chat โดยการอ่านบันทึกของแอป หากต้องการอ่านบันทึก ให้ไปที่ Logs Explorer ในคอนโซล Google Cloud