링크 미리보기

사용자가 Google Chat에서 링크를 공유할 때 컨텍스트 전환을 방지하기 위해 채팅 앱에서 메시지에 카드를 첨부하여 링크를 미리 볼 수 있습니다. 이 카드를 통해 자세한 정보를 제공하고 사용자가 Google Chat에서 바로 작업을 실행할 수 있습니다.

예를 들어 회사의 모든 고객 서비스 상담사와 Case-y라는 채팅 앱이 포함된 Google Chat 스페이스가 있다고 가정해 보겠습니다. 상담사는 Chat 스페이스에서 고객 서비스 케이스 링크를 자주 공유하며, 동료는 매번 케이스 링크를 열어 담당자, 상태, 제목과 같은 세부정보를 확인해야 합니다. 마찬가지로 누군가 케이스의 소유권을 가져가거나 상태를 변경하려면 링크를 열어야 합니다.

링크 미리보기를 사용하면 스페이스의 상주 채팅 앱인 Case-y에서 누군가 케이스 링크를 공유할 때마다 담당자, 상태, 제목이 표시된 카드를 첨부할 수 있습니다. 상담사는 카드에 있는 버튼을 사용하여 채팅 스트림에서 직접 케이스의 소유권을 가져오고 상태를 변경할 수 있습니다.

누군가 메시지에 링크를 추가하면 채팅 앱에서 링크를 미리 볼 수 있음을 알리는 칩이 표시됩니다.

채팅 앱이 링크를 미리 볼 수 있음을 나타내는 칩

메시지를 보내면 채팅 앱으로 링크가 전송되고 채팅 앱에서 카드를 생성하여 사용자의 메시지에 첨부합니다.

메시지에 카드를 첨부하여 링크를 미리 보는 채팅 앱

링크 옆에 있는 카드는 버튼과 같은 상호작용 요소를 포함하여 링크에 관한 추가 정보를 제공합니다. 채팅 앱은 버튼 클릭과 같은 사용자 상호작용에 응답하여 연결된 카드를 업데이트할 수 있습니다.

사용자가 채팅 앱에서 메시지에 카드를 첨부하여 링크를 미리 보지 못하도록 하려면 미리보기 칩에서 를 클릭하여 미리보기를 차단할 수 있습니다. 사용자는 미리보기 삭제를 클릭하여 언제든지 첨부된 카드를 삭제할 수 있습니다.

특정 링크(예: example.com, support.example.com, support.example.com/cases/)를 채팅 앱에서 미리 볼 수 있도록 Google Cloud 콘솔의 채팅 앱 구성 페이지에 URL 패턴으로 등록합니다.

링크 미리보기 구성 메뉴

  1. Google Cloud 콘솔을 엽니다. 
  2. 'Google Cloud' 옆에 있는 아래쪽 화살표 를 클릭하고 채팅 앱의 프로젝트를 엽니다.
  3. 검색창에 Google Chat API를 입력하고 Google Chat API를 클릭합니다.
  4. 관리 > 구성을 클릭합니다.
  5. 링크 미리보기에서 URL 패턴을 추가하거나 수정합니다.
    1. 새 URL 패턴에 대한 링크 미리보기를 구성하려면 URL 패턴 추가를 클릭합니다.
    2. 기존 URL 패턴의 구성을 수정하려면 아래쪽 화살표 를 클릭합니다.
  6. 호스트 패턴 입력란에 URL 패턴의 도메인을 입력합니다. 채팅 앱이 이 도메인으로 연결되는 링크를 미리 봅니다.

    subdomain.example.com와 같은 특정 하위 도메인의 채팅 앱 미리보기 링크를 사용하려면 하위 도메인을 포함합니다.

    전체 도메인에 Chat 앱 미리보기 링크를 표시하려면 별표 (*)가 있는 와일드 카드 문자를 하위 도메인으로 지정합니다. 예를 들어 *.example.comsubdomain.example.comany.number.of.subdomains.example.com와 일치합니다.

  7. 경로 프리픽스 입력란에 호스트 패턴 도메인에 추가할 경로를 입력합니다.

    호스트 패턴 도메인의 모든 URL과 일치시키려면 경로 프리픽스를 비워 둡니다.

    예를 들어 호스트 패턴이 support.example.com인 경우 support.example.com/cases/에 호스팅된 케이스의 URL과 일치시키려면 cases/을 입력합니다.

  8. 완료를 클릭합니다.

  9. 저장을 클릭합니다.

이제 누군가 채팅 앱이 포함된 Chat 스페이스의 메시지에 링크 미리보기 URL 패턴과 일치하는 링크를 포함할 때마다 앱에서 링크 미리보기를 표시합니다.

특정 링크의 링크 미리보기를 구성하면 채팅 앱이 링크에 추가 정보를 첨부하여 링크를 인식하고 미리 볼 수 있습니다.

채팅 앱이 포함된 Chat 공간 내에서 다른 사용자의 메시지에 링크 미리보기 URL 패턴과 일치하는 링크가 포함된 경우 채팅 앱은 MESSAGE 상호작용 이벤트를 수신합니다. 상호작용 이벤트의 JSON 페이로드에는 matchedUrl 필드가 포함됩니다.

JSON

message {

  . . . // other message attributes redacted

  "matchedUrl": {
     "url": "https://support.example.com/cases/case123"
   },

  . . . // other message attributes redacted

}

MESSAGE 이벤트 페이로드에 matchedUrl 필드가 있는지 확인하면 채팅 앱은 미리보기된 링크로 메시지에 정보를 추가할 수 있습니다. 채팅 앱은 간단한 문자 메시지로 답장하거나 카드를 첨부할 수 있습니다.

문자 메시지로 답장하기

간단한 응답의 경우 채팅 앱에서 링크에 간단한 문자 메시지로 회신하여 링크를 미리 볼 수 있습니다. 이 예에서는 링크 미리보기 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.'};
}

카드 첨부

미리보기된 링크에 카드를 연결하려면 UPDATE_USER_MESSAGE_CARDS 유형의 ActionResponse를 반환합니다. 이 예에서는 간단한 카드를 첨부합니다.

메시지에 카드를 첨부하여 링크를 미리 보는 채팅 앱

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.'};
}

카드 업데이트

미리보기된 링크에 연결된 카드를 업데이트하려면 UPDATE_USER_MESSAGE_CARDS 유형의 ActionResponse를 반환합니다. 채팅 앱은 채팅 앱 상호작용 이벤트에 대한 응답으로 링크를 미리 보는 카드만 업데이트할 수 있습니다. 채팅 앱은 Chat API를 비동기식으로 호출하여 이러한 카드를 업데이트할 수 없습니다.

링크 미리보기에서는 UPDATE_MESSAGE 유형의 ActionResponse 반환이 지원되지 않습니다. UPDATE_MESSAGE는 카드만 업데이트하는 것이 아니라 전체 메시지를 업데이트하므로 채팅 앱에서 원본 메시지를 만든 경우에만 작동합니다. 링크 미리보기는 사용자가 만든 메시지에 카드를 첨부하므로 채팅 앱에 이를 업데이트할 권한이 없습니다.

기능이 채팅 스트림에서 사용자가 만든 카드를 모두 업데이트하도록 하려면 채팅 앱 또는 사용자가 메시지를 작성했는지에 따라 ActionResponse을 동적으로 설정합니다.

  • 사용자가 메시지를 만든 경우 ActionResponseUPDATE_USER_MESSAGE_CARDS로 설정합니다.
  • 채팅 앱에서 메시지를 만든 경우 ActionResponseUPDATE_MESSAGE로 설정합니다.

이를 위한 두 가지 방법이 있습니다. 연결된 카드의 onclick 속성 일부로 맞춤 actionMethodName를 지정 및 확인하거나 (사용자가 만든 메시지임을 식별함) 메시지를 사용자가 만들었는지 확인하는 것입니다.

옵션 1: actionMethodName 확인하기

actionMethodName를 사용하여 미리보기된 카드에서 CARD_CLICKED 상호작용 이벤트를 올바르게 처리하려면 연결된 카드의 onclick 속성의 일부로 맞춤 actionMethodName를 설정합니다.

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"로 버튼을 링크 미리보기의 일부로 식별하면 일치하는 actionMethodName를 확인하여 올바른 ActionResponse를 동적으로 반환할 수 있습니다.

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.typeHUMAN인지 BOT인지 확인합니다. HUMAN인 경우 ActionResponseUPDATE_USER_MESSAGE_CARDS로 설정하고 그렇지 않으면 ActionResponseUPDATE_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를 동적으로 설정합니다.

전체 예: 고객 서비스 채팅 앱 Case-y

다음은 고객 서비스 상담사가 공동작업하는 Chat 스페이스에서 공유된 케이스의 링크를 미리 보는 채팅 앱인 Case-y의 전체 코드입니다.

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'}},
                },
              },
            ],
          }],
        }],
      },
    }],
  };
}

제한사항 및 고려사항

채팅 앱의 링크 미리보기를 구성할 때 다음 한도 및 고려사항에 유의하세요.

  • 각 채팅 앱은 최대 5개의 URL 패턴에 대한 링크 미리보기를 지원합니다.
  • 채팅 앱에서는 메시지당 링크 1개를 미리 볼 수 있습니다. 미리보기 가능한 링크가 단일 메시지에 여러 개 있는 경우 미리보기 가능한 첫 번째 링크만 미리 볼 수 있습니다.
  • 채팅 앱은 https://로 시작하는 링크만 미리 볼 수 있으므로 https://support.example.com/cases/는 미리 볼 수 있지만 support.example.com/cases/는 미리 볼 수 없습니다.
  • 메시지에 슬래시 명령어와 같이 채팅 앱으로 전송되는 다른 정보가 포함되어 있지 않다면 링크 미리보기를 통해 링크 URL만 채팅 앱으로 전송됩니다.
  • 미리보기된 링크에 연결된 카드는 UPDATE_USER_MESSAGE_CARDS 유형의 ActionResponse만 지원하고 Chat 앱 상호작용 이벤트에 대한 응답으로만 지원합니다. 링크 미리보기는 UPDATE_MESSAGE 또는 Chat API를 통해 미리보기된 링크에 연결된 카드를 업데이트하는 비동기 요청을 지원하지 않습니다. 자세한 내용은 카드 업데이트를 참고하세요.

링크 미리보기를 구현할 때 앱의 로그를 읽어 채팅 앱을 디버그해야 할 수도 있습니다. 로그를 읽으려면 Google Cloud 콘솔의 로그 탐색기로 이동하세요.