카드에 대화형 UI 요소 추가

이 페이지에서는 사용자가 버튼을 클릭하거나 정보를 제출하는 등 Google Chat 앱과 상호작용할 수 있도록 위젯 및 UI 요소를 카드에 추가하는 방법을 설명합니다.

채팅 앱은 다음 Chat 인터페이스를 사용하여 대화형 카드를 빌드할 수 있습니다.

  • 카드를 하나 이상 포함하는 메시지
  • 홈페이지: Chat 앱의 채팅 메시지에서 탭에 표시되는 카드입니다.
  • 대화상자: 메시지 및 홈페이지에서 새 창에서 열리는 카드.

사용자가 카드와 상호작용할 때 Chat 앱은 수신한 데이터를 사용하여 적절하게 처리하고 응답할 수 있습니다. 자세한 내용은 Google Chat 사용자로부터 정보 수집 및 처리하기를 참고하세요.


카드 작성 도구를 사용하여 Chat 앱의 메시지 및 사용자 인터페이스를 디자인하고 미리 볼 수 있습니다.

카드 빌더를 엽니다.

기본 요건

대화형 기능이 사용 설정된 Google Chat 앱 대화형 Chat 앱을 만들려면 사용하려는 앱 아키텍처에 따라 다음 빠른 시작 중 하나를 완료하세요.

버튼 추가

ButtonList 위젯은 버튼 집합을 표시합니다. 버튼은 텍스트나 아이콘을 표시하거나 텍스트와 아이콘을 모두 표시할 수 있습니다. 각 Button는 사용자가 버튼을 클릭할 때 발생하는 OnClick 작업을 지원합니다. 예를 들면 다음과 같습니다.

  • 사용자에게 추가 정보를 제공하기 위해 OpenLink로 하이퍼링크를 엽니다.
  • API 호출과 같이 커스텀 함수를 실행하는 action를 실행합니다.

접근성을 위해 버튼은 대체 텍스트를 지원합니다.

맞춤 함수를 실행하는 버튼 추가

다음은 버튼이 2개인 ButtonList 위젯으로 구성된 카드입니다. 버튼 하나만 누르면 새 탭에서 Google Chat 개발자 문서가 열립니다. 다른 버튼은 goToView()라는 맞춤 함수를 실행하고 viewType="BIRD EYE VIEW" 매개변수를 전달합니다.

Material Design 스타일로 버튼 추가

다음은 다양한 Material Design 버튼 스타일로 버튼 집합을 표시합니다.

Material Design 스타일을 적용하려면 'color' 속성을 포함하지 마세요.

맞춤 색상 및 비활성화된 버튼이 있는 버튼 추가

"disabled": "true"를 설정하여 사용자가 버튼을 클릭하지 못하게 할 수 있습니다.

다음은 버튼 2개가 있는 ButtonList 위젯으로 구성된 카드를 보여줍니다. 한 버튼은 Color 필드를 사용하여 버튼의 배경 색상을 맞춤설정합니다. 다른 버튼은 Disabled 필드로 비활성화되어 사용자가 버튼을 클릭하고 함수를 실행하지 못하도록 합니다.

아이콘이 있는 버튼 추가

다음은 두 개의 아이콘 Button 위젯과 함께 ButtonList 위젯으로 구성된 카드를 보여줍니다. 한 버튼은 knownIcon 필드를 사용하여 Google Chat의 내장 이메일 아이콘을 표시합니다. 다른 버튼은 iconUrl 필드를 사용하여 맞춤 아이콘 위젯을 표시합니다.

아이콘 및 텍스트가 있는 버튼 추가

다음은 사용자에게 이메일을 보내라는 메시지를 표시하는 ButtonList 위젯으로 구성된 카드를 보여줍니다. 첫 번째 버튼에는 이메일 아이콘이 표시되고 두 번째 버튼에는 텍스트가 표시됩니다. 사용자는 아이콘 또는 텍스트 버튼을 클릭하여 sendEmail 함수를 실행할 수 있습니다.

접을 수 있는 섹션의 버튼 맞춤설정

카드 내 섹션을 접고 펼치는 컨트롤 버튼을 맞춤설정합니다. 다양한 아이콘 또는 이미지 중에서 선택하여 섹션의 콘텐츠를 시각적으로 나타내면 사용자가 정보를 더 쉽게 이해하고 상호작용할 수 있습니다.

더보기 메뉴 추가

Overflow menu는 채팅 카드에서 추가 옵션과 작업을 제공하는 데 사용할 수 있습니다. 카드 인터페이스를 복잡하게 만들지 않으면서 더 많은 옵션을 포함하여 깔끔하고 체계적인 디자인을 유지할 수 있습니다.

칩 목록 추가

ChipList 위젯은 다재다능하고 시각적으로 매력적인 정보를 표시하는 방법을 제공합니다. 칩 목록을 사용하여 태그, 카테고리 또는 기타 관련 데이터를 표시하면 사용자가 콘텐츠를 더 쉽게 탐색하고 상호작용할 수 있습니다.

사용자로부터 정보 수집

이 섹션에서는 텍스트나 선택 항목과 같은 정보를 수집하는 위젯을 추가하는 방법을 설명합니다.

사용자가 입력한 내용을 처리하는 방법을 알아보려면 Google Chat 사용자의 정보 수집 및 처리를 참조하세요.

텍스트 수집

TextInput 위젯은 사용자가 텍스트를 입력할 수 있는 필드를 제공합니다. 이 위젯은 사용자가 균일한 데이터를 입력하는 데 도움이 되는 추천과 텍스트 입력란에서 변경사항이 발생할 때 실행되는 Actions인 변경 시 작업(예: 사용자의 텍스트 추가 또는 삭제)을 지원합니다.

사용자로부터 추상적이거나 알 수 없는 데이터를 수집해야 하는 경우 이 TextInput 위젯을 사용합니다. 사용자로부터 정의된 데이터를 수집하려면 SelectionInput 위젯을 대신 사용하세요.

다음은 TextInput 위젯으로 구성된 카드입니다.

날짜 또는 시간 수집

DateTimePicker 위젯을 사용하면 사용자가 날짜, 시간 또는 날짜와 시간을 모두 입력할 수 있습니다. 또는 사용자가 선택 도구를 사용하여 날짜와 시간을 선택할 수 있습니다. 사용자가 잘못된 날짜 또는 시간을 입력하면 선택 도구에 사용자가 정보를 올바르게 입력하라는 오류 메시지가 표시됩니다.

다음은 세 가지 유형의 DateTimePicker 위젯으로 구성된 카드를 보여줍니다.

사용자가 항목을 선택하도록 허용

SelectionInput 위젯은 체크박스, 라디오 버튼, 스위치, 드롭다운 메뉴와 같은 선택 가능한 항목 집합을 제공합니다. 이 위젯을 사용하여 정의되고 표준화된 데이터를 사용자로부터 수집할 수 있습니다. 사용자로부터 정의되지 않은 데이터를 수집하려면 대신 TextInput 위젯을 사용하세요.

SelectionInput 위젯은 사용자가 균일한 데이터를 입력하는 데 도움이 되는 추천과 선택 입력란에서 변경사항이 발생할 때 실행되는 Actions인 변경 시 작업(예: 사용자 선택 또는 선택 해제)을 지원합니다.

채팅 앱은 선택된 항목의 값을 수신하고 처리할 수 있습니다. 양식 입력란 작업에 관한 자세한 내용은 사용자가 입력한 정보 처리를 참고하세요.

이 섹션에서는 SelectionInput 위젯을 사용하는 카드의 예시를 제공합니다. 예에서는 다양한 유형의 섹션 입력을 사용합니다.

체크박스 추가

다음은 체크박스를 사용하는 SelectionInput 위젯과 함께 연락처가 전문 연락처인지, 개인 연락처인지, 둘 다인지 지정하라는 카드가 표시됩니다.

라디오 버튼 추가

다음은 라디오 버튼을 사용하는 SelectionInput 위젯을 통해 사용자에게 연락처가 업무용인지 개인용인지 지정하라는 카드가 표시됩니다.

스위치 추가

다음은 스위치를 사용하는 SelectionInput 위젯을 통해 사용자가 업무용 연락처인지, 업무용 연락처인지, 개인용 연락처인지 둘 다인지 지정하라는 카드가 표시됩니다.

다음은 드롭다운 메뉴를 사용하는 SelectionInput 위젯을 통해 사용자에게 연락처가 업무용인지 개인용인지 지정하라는 카드가 표시됩니다.

다중 선택 메뉴 추가

다음은 사용자에게 다중 선택 메뉴에서 연락처를 선택하라는 메시지를 표시하는 카드를 보여줍니다.

Google Workspace의 다음 데이터 소스에서 다중 선택 메뉴의 항목을 채울 수 있습니다.

  • Google Workspace 사용자: 동일한 Google Workspace 조직 내의 사용자만 채울 수 있습니다.
  • Chat 스페이스: 다중 선택 메뉴의 사용자 입력 항목은 Google Workspace 조직 내에서 자신이 속한 스페이스만 보고 선택할 수 있습니다.

Google Workspace 데이터 소스를 사용하려면 platformDataSource 필드를 지정합니다. 다른 선택 입력 유형과 달리 이러한 선택 항목은 Google Workspace에서 동적으로 가져오므로 SectionItem 객체는 생략합니다.

다음 코드는 Google Workspace 사용자의 다중 선택 메뉴를 보여줍니다. 사용자를 채우기 위해 선택 입력은 commonDataSourceUSER로 설정합니다.

JSON

{
  "selectionInput": {
    "name": "contacts",
    "type": "MULTI_SELECT",
    "label": "Selected contacts",
    "multiSelectMaxSelectedItems": 5,
    "multiSelectMinQueryLength": 1,
    "platformDataSource": {
      "commonDataSource": "USER"
    }
  }
}

다음 코드는 Chat 스페이스의 다중 선택 메뉴를 보여줍니다. 선택 입력은 스페이스를 채우기 위해 hostAppDataSource 필드를 지정합니다. 다중 선택 메뉴는 defaultToCurrentSpacetrue로 설정하여 현재 스페이스를 메뉴의 기본 선택 항목으로 만듭니다.

JSON

{
  "selectionInput": {
    "name": "spaces",
    "type": "MULTI_SELECT",
    "label": "Selected contacts",
    "multiSelectMaxSelectedItems": 3,
    "multiSelectMinQueryLength": 1,
    "platformDataSource": {
      "hostAppDataSource": {
        "chatDataSource": {
          "spaceDataSource": {
            "defaultToCurrentSpace": true
          }
        }
      }
    }
  }
}

다중 선택 메뉴에서 서드 파티 또는 외부 데이터 소스의 항목을 채울 수도 있습니다. 예를 들어 다중 선택 메뉴를 사용하여 사용자가 고객 관계 관리 (CRM) 시스템의 판매 리드 목록에서 선택할 수 있도록 할 수 있습니다.

외부 데이터 소스를 사용하려면 externalDataSource 필드를 사용하여 데이터 소스에서 항목을 반환하는 함수를 지정합니다.

외부 데이터 소스에 대한 요청을 줄이기 위해 사용자가 메뉴를 입력하기 전에 멀티셀렉션 메뉴에 표시되는 추천 항목을 포함할 수 있습니다. 예를 들어 사용자의 최근에 검색한 연락처를 채울 수 있습니다. 외부 데이터 소스의 추천 항목을 채우려면 SelectionItem 객체를 지정합니다.

다음 코드는 사용자의 외부 연락처 세트에서 항목의 다중 선택 메뉴를 보여줍니다. 메뉴에는 기본적으로 연락처 하나가 표시되고 getContacts 함수를 실행하여 외부 데이터 소스에서 항목을 검색하고 채웁니다.

Node.js

node/selection-input/index.js
selectionInput: {
  name: "contacts",
  type: "MULTI_SELECT",
  label: "Selected contacts",
  multiSelectMaxSelectedItems: 3,
  multiSelectMinQueryLength: 1,
  externalDataSource: { function: "getContacts" },
  // Suggested items loaded by default.
  // The list is static here but it could be dynamic.
  items: [getContact("3")]
}

Python

python/selection-input/main.py
'selectionInput': {
  'name': "contacts",
  'type': "MULTI_SELECT",
  'label': "Selected contacts",
  'multiSelectMaxSelectedItems': 3,
  'multiSelectMinQueryLength': 1,
  'externalDataSource': { 'function': "getContacts" },
  # Suggested items loaded by default.
  # The list is static here but it could be dynamic.
  'items': [get_contact("3")]
}

자바

java/selection-input/src/main/java/com/google/chat/selectionInput/App.java
.setSelectionInput(new GoogleAppsCardV1SelectionInput()
  .setName("contacts")
  .setType("MULTI_SELECT")
  .setLabel("Selected contacts")
  .setMultiSelectMaxSelectedItems(3)
  .setMultiSelectMinQueryLength(1)
  .setExternalDataSource(new GoogleAppsCardV1Action().setFunction("getContacts"))
  .setItems(List.of(getContact("3")))))))))));

Apps Script

apps-script/selection-input/selection-input.gs
selectionInput: {
  name: "contacts",
  type: "MULTI_SELECT",
  label: "Selected contacts",
  multiSelectMaxSelectedItems: 3,
  multiSelectMinQueryLength: 1,
  externalDataSource: { function: "getContacts" },
  // Suggested items loaded by default.
  // The list is static here but it could be dynamic.
  items: [getContact("3")]
}

외부 데이터 소스의 경우 사용자가 다중 선택 메뉴에서 입력을 시작하는 항목을 자동 완성할 수도 있습니다. 예를 들어 사용자가 미국의 도시를 채우는 메뉴에 Atl를 입력하기 시작하면 사용자가 입력을 완료하기 전에 Chat 앱에서 Atlanta를 자동 추천할 수 있습니다. 최대 100개의 항목을 자동 완성할 수 있습니다.

항목을 자동 완성하려면 사용자가 멀티셀렉션 메뉴에 입력할 때마다 외부 데이터 소스를 쿼리하고 항목을 반환하는 함수를 만듭니다. 함수는 다음을 실행해야 합니다.

  • 메뉴와의 사용자 상호작용을 나타내는 이벤트 객체를 전달합니다.
  • 상호작용 이벤트의 invokedFunction 값이 externalDataSource 필드의 함수와 일치하는지 확인합니다.
  • 함수가 일치하면 외부 데이터 소스에서 추천 항목을 반환합니다. 사용자가 입력한 내용을 기반으로 항목을 추천하려면 autocomplete_widget_query 키의 값을 가져옵니다. 이 값은 사용자가 메뉴에 입력하는 내용을 나타냅니다.

다음 코드는 외부 데이터 리소스에서 항목을 자동 완성합니다. 이전 예를 사용하면 채팅 앱은 getContacts 함수가 트리거되는 시점에 따라 항목을 추천합니다.

Node.js

node/selection-input/index.js
/**
 * Responds to a WIDGET_UPDATE event in Google Chat.
 *
 * @param {Object} event The event object from Chat API.
 * @return {Object} Response from the Chat app.
 */
function onWidgetUpdate(event) {
  if (event.common["invokedFunction"] === "getContacts") {
    const query = event.common.parameters["autocomplete_widget_query"];
    return { actionResponse: {
      type: "UPDATE_WIDGET",
      updatedWidget: { suggestions: { items: [
        // The list is static here but it could be dynamic.
        getContact("1"), getContact("2"), getContact("3"), getContact("4"), getContact("5")
      // Only return items based on the query from the user
      ].filter(e => !query || e.text.includes(query))}}
    }};
  }
}

/**
 * Generate a suggested contact given an ID.
 *
 * @param {String} id The ID of the contact to return.
 * @return {Object} The contact formatted as a suggested item for selectors.
 */
function getContact(id) {
  return {
    value: id,
    startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    text: "Contact " + id
  };
}

Python

python/selection-input/main.py
def on_widget_update(event: dict) -> dict:
  """Responds to a WIDGET_UPDATE event in Google Chat."""
  if "getContacts" == event.get("common").get("invokedFunction"):
    query = event.get("common").get("parameters").get("autocomplete_widget_query")
    return { 'actionResponse': {
      'type': "UPDATE_WIDGET",
      'updatedWidget': { 'suggestions': { 'items': list(filter(lambda e: query is None or query in e["text"], [
        # The list is static here but it could be dynamic.
        get_contact("1"), get_contact("2"), get_contact("3"), get_contact("4"), get_contact("5")
      # Only return items based on the query from the user
      ]))}}
    }}


def get_contact(id: str) -> dict:
  """Generate a suggested contact given an ID."""
  return {
    'value': id,
    'startIconUri': "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    'text': "Contact " + id
  }

자바

java/selection-input/src/main/java/com/google/chat/selectionInput/App.java
// Responds to a WIDGET_UPDATE event in Google Chat.
Message onWidgetUpdate(JsonNode event) {
  if ("getContacts".equals(event.at("/invokedFunction").asText())) {
    String query = event.at("/common/parameters/autocomplete_widget_query").asText();
    return new Message().setActionResponse(new ActionResponse()
      .setType("UPDATE_WIDGET")
      .setUpdatedWidget(new UpdatedWidget()
        .setSuggestions(new SelectionItems().setItems(List.of(
          // The list is static here but it could be dynamic.
          getContact("1"), getContact("2"), getContact("3"), getContact("4"), getContact("5")
        // Only return items based on the query from the user
        ).stream().filter(e -> query == null || e.getText().indexOf(query) > -1).toList()))));
  }
  return null;
}

// Generate a suggested contact given an ID.
GoogleAppsCardV1SelectionItem getContact(String id) {
  return new GoogleAppsCardV1SelectionItem()
    .setValue(id)
    .setStartIconUri("https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png")
    .setText("Contact " + id);
}

Apps Script

apps-script/selection-input/selection-input.gs
/**
 * Responds to a WIDGET_UPDATE event in Google Chat.
 *
 * @param {Object} event The event object from Chat API.
 * @return {Object} Response from the Chat app.
 */
function onWidgetUpdate(event) {
  if (event.common["invokedFunction"] === "getContacts") {
    const query = event.common.parameters["autocomplete_widget_query"];
    return { actionResponse: {
      type: "UPDATE_WIDGET",
      updatedWidget: { suggestions: { items: [
        // The list is static here but it could be dynamic.
        getContact("1"), getContact("2"), getContact("3"), getContact("4"), getContact("5")
      // Only return items based on the query from the user
      ].filter(e => !query || e.text.includes(query))}}
    }};
  }
}

/**
 * Generate a suggested contact given an ID.
 *
 * @param {String} id The ID of the contact to return.
 * @return {Object} The contact formatted as a suggested item for selectors.
 */
function getContact(id) {
  return {
    value: id,
    startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    text: "Contact " + id
  };
}

카드에 입력된 데이터 유효성 검사

이 페이지에서는 카드의 action 및 위젯에 입력된 데이터의 유효성을 검사하는 방법을 설명합니다. 예를 들어 텍스트 입력란에 사용자가 입력한 텍스트가 있는지 또는 특정 수의 문자가 포함되어 있는지 검사할 수 있습니다.

작업에 필요한 위젯 설정

카드의 action의 일부로 액션에 필요한 위젯의 이름을 requiredWidgets 목록에 추가합니다.

이 작업이 호출될 때 여기에 나열된 위젯에 값이 없으면 양식 작업 제출이 취소됩니다.

작업에 "all_widgets_are_required": "true"를 설정하면 이 작업에 카드의 모든 위젯이 필요합니다.

다중 선택에서 all_widgets_are_required 작업 설정

JSON

{
  "sections": [
    {
      "header": "Select contacts",
      "widgets": [
        {
          "selectionInput": {
            "type": "MULTI_SELECT",
            "label": "Selected contacts",
            "name": "contacts",
            "multiSelectMaxSelectedItems": 3,
            "multiSelectMinQueryLength": 1,
            "onChangeAction": {
              "all_widgets_are_required": true
            },
            "items": [
              {
                "value": "contact-1",
                "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                "text": "Contact 1",
                "bottomText": "Contact one description",
                "selected": false
              },
              {
                "value": "contact-2",
                "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                "text": "Contact 2",
                "bottomText": "Contact two description",
                "selected": false
              },
              {
                "value": "contact-3",
                "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                "text": "Contact 3",
                "bottomText": "Contact three description",
                "selected": false
              },
              {
                "value": "contact-4",
                "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                "text": "Contact 4",
                "bottomText": "Contact four description",
                "selected": false
              },
              {
                "value": "contact-5",
                "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                "text": "Contact 5",
                "bottomText": "Contact five description",
                "selected": false
              }
            ]
          }
        }
      ]
    }
  ]
}
dateTimePicker에서 all_widgets_are_required 작업 설정

JSON

{
  "sections": [
    {
      "widgets": [
        {
          "textParagraph": {
            "text": "A datetime picker widget with both date and time:"
          }
        },
        {
          "divider": {}
        },
        {
          "dateTimePicker": {
            "name": "date_time_picker_date_and_time",
            "label": "meeting",
            "type": "DATE_AND_TIME"
          }
        },
        {
          "textParagraph": {
            "text": "A datetime picker widget with just date:"
          }
        },
        {
          "divider": {}
        },
        {
          "dateTimePicker": {
            "name": "date_time_picker_date_only",
            "label": "Choose a date",
            "type": "DATE_ONLY",
            "onChangeAction":{
              "all_widgets_are_required": true
            }
          }
        },
        {
          "textParagraph": {
            "text": "A datetime picker widget with just time:"
          }
        },
        {
          "divider": {}
        },
        {
          "dateTimePicker": {
            "name": "date_time_picker_time_only",
            "label": "Select a time",
            "type": "TIME_ONLY"
          }
        }
      ]
    }
  ]
}
드롭다운 메뉴에서 all_widgets_are_required 작업 설정

JSON

{
  "sections": [
    {
      "header": "Section Header",
      "collapsible": true,
      "uncollapsibleWidgetsCount": 1,
      "widgets": [
        {
          "selectionInput": {
            "name": "location",
            "label": "Select Color",
            "type": "DROPDOWN",
            "onChangeAction": {
              "all_widgets_are_required": true
            },
            "items": [
              {
                "text": "Red",
                "value": "red",
                "selected": false
              },
              {
                "text": "Green",
                "value": "green",
                "selected": false
              },
              {
                "text": "White",
                "value": "white",
                "selected": false
              },
              {
                "text": "Blue",
                "value": "blue",
                "selected": false
              },
              {
                "text": "Black",
                "value": "black",
                "selected": false
              }
            ]
          }
        }
      ]
    }
  ]
}

텍스트 입력 위젯의 유효성 검사 설정

textInput 위젯의 유효성 검사 필드에서 이 텍스트 입력 위젯의 글자 수 제한과 입력 유형을 지정할 수 있습니다.

텍스트 입력 위젯의 글자 수 제한 설정

JSON

{
  "sections": [
    {
      "header": "Tell us about yourself",
      "collapsible": true,
      "uncollapsibleWidgetsCount": 2,
      "widgets": [
        {
          "textInput": {
            "name": "favoriteColor",
            "label": "Favorite color",
            "type": "SINGLE_LINE",
            "validation": {"character_limit":15},
            "onChangeAction":{
              "all_widgets_are_required": true
            }
          }
        }
      ]
    }
  ]
}
텍스트 입력 위젯의 입력 유형 설정

JSON

{
  "sections": [
    {
      "header": "Validate text inputs by input types",
      "collapsible": true,
      "uncollapsibleWidgetsCount": 2,
      "widgets": [
        {
          "textInput": {
            "name": "mailing_address",
            "label": "Please enter a valid email address",
            "type": "SINGLE_LINE",
            "validation": {
              "input_type": "EMAIL"
            },
            "onChangeAction": {
              "all_widgets_are_required": true
            }
          }
        },
        {
          "textInput": {
            "name": "validate_integer",
            "label": "Please enter a number",
              "type": "SINGLE_LINE",
            "validation": {
              "input_type": "INTEGER"
            }
          }
        },
        {
          "textInput": {
            "name": "validate_float",
            "label": "Please enter a number with a decimal",
            "type": "SINGLE_LINE",
            "validation": {
              "input_type": "FLOAT"
            }
          }
        }
      ]
    }
  ]
}

문제 해결

Google Chat 앱 또는 카드가 오류를 반환하면 Chat 인터페이스에 '문제가 발생했습니다'라는 메시지가 표시됩니다. '요청을 처리할 수 없습니다' 채팅 UI에는 오류 메시지가 표시되지 않지만 채팅 앱 또는 카드에서 예기치 않은 결과가 발생하는 경우가 있습니다. 예를 들어 카드 메시지가 표시되지 않을 수 있습니다.

Chat UI에 오류 메시지가 표시되지 않을 수 있지만 채팅 앱의 오류 로깅이 사용 설정되어 있을 때 오류 메시지 및 로그 데이터를 사용하여 오류를 해결할 수 있습니다. 확인, 디버깅, 오류 수정에 관한 도움말은 Google Chat 오류 문제 해결을 참고하세요.