대화형 대화상자 열기

이 페이지에서는 채팅 앱에서 대화상자를 여는 방법을 설명합니다. 응답해야 합니다

대화상자: 창으로 표시되는 카드 기반 인터페이스 Chat 스페이스 또는 메시지에서 열리는 스페이스 대화상자와 해당 콘텐츠를 연 사용자에게만 표시됩니다.

채팅 앱은 대화상자를 사용하여 채팅 사용자(다단계 양식 포함) 자세한 내용은 양식 입력 작성에 대한 자세한 내용은 사용자 정보 수집 및 처리를 참고하세요.

<ph type="x-smartling-placeholder">

기본 요건

Node.js

  • 양방향 기능이 사용 설정된 Google Chat 앱 대화형 채팅 앱을 사용하려면 이 빠른 시작을 완료하세요.

Python

  • 양방향 기능이 사용 설정된 Google Chat 앱 대화형 채팅 앱을 사용하려면 이 빠른 시작을 완료하세요.

Apps Script

  • 양방향 기능이 사용 설정된 Google Chat 앱 Apps Script에서 대화형 채팅 앱을 사용하려면 이 빠른 시작을 완료하세요.

대화상자 열기

<ph type="x-smartling-placeholder">
</ph> 다양한 위젯이 표시된 대화상자
그림 1: 연락처 정보를 수집하는 대화상자

이 섹션에서는 다음을 실행하여 응답하고 대화상자를 설정하는 방법을 설명합니다.

  1. 사용자 상호작용에서 대화상자 요청을 트리거합니다.
  2. 대화상자를 반환하고 열어 요청을 처리합니다.
  3. 사용자가 정보를 제출하면 다른 대화상자를 반환할 수 있습니다.

대화상자 요청 트리거

채팅 앱은 사용자에게 응답하기 위한 대화상자만 열 수 있습니다. 메시지의 버튼 클릭과 같은 상호작용을 예로 들 수 있습니다.

대화로 사용자에게 응답하려면 채팅 앱이 다음을 충족해야 합니다. 다음과 같이 대화상자 요청을 트리거하는 상호작용을 빌드합니다.

  • 슬래시 명령어에 응답합니다. 슬래시 명령어에서 요청을 트리거하려면 명령어를 구성할 때 대화상자 열기 체크박스를 선택해야 합니다.
  • Google 디스플레이 네트워크에서 message, 참고: 카드 또는 메시지 하단에 표시되어 있습니다. 요청을 보내는 경우 버튼의 onClick interactionOPEN_DIALOG로 설정하여 작업을 실행합니다.
  • 채팅 앱 홈페이지의 버튼 클릭에 응답합니다. 홈페이지에서 대화상자를 여는 방법을 알아보려면 다음을 참고하세요. Google Chat 앱의 홈페이지 만들기
를 통해 개인정보처리방침을 정의할 수 있습니다. <ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">대화상자를 트리거하는 버튼</ph>
그림 2: 채팅 앱에서 사용자에게 /addContact 슬래시 명령어를 사용하라는 메시지를 표시합니다.
이 메시지에는 사용자가 클릭하여 명령어를 트리거할 수 있는 버튼도 포함됩니다.

다음 JSON은 버튼에서 대화상자 요청을 트리거하는 방법을 보여줍니다. 있습니다. 대화상자를 열려면 button.interaction 드림 필드가 OPEN_DIALOG로 설정됩니다.

{
  "buttonList": { "buttons": [{
    "text": "BUTTON_TEXT",
    "onClick": { "action": {
      "function": "FUNCTION_NAME",
      "interaction": "OPEN_DIALOG"
    }}
  }]}
}

여기서 BUTTON_TEXT는 버튼에 표시되는 텍스트입니다. FUNCTION_NAME는 초기 파일을 열기 위해 실행되는 함수입니다. 대화상자

초기 대화상자 열기

사용자가 대화상자 요청을 트리거하면 채팅 앱에서 은 상호작용 이벤트를 수신하며, 이는 event 입력란에 Chat API 상호작용이 대화상자 요청을 트리거하면 이벤트의 dialogEventType 필드가 REQUEST_DIALOG로 설정됩니다.

대화상자를 열려면 채팅 앱에서 반환한 후 actionResponse 드림 typeDIALOG로 설정된 객체 Message 객체를 지정합니다. 대화상자의 콘텐츠를 지정하려면 다음을 포함합니다. 객체:

  • actionResponse 객체로 표시되며 typeDIALOG로 설정되어 있습니다.
  • dialogAction 객체. body 필드에는 다음을 위한 사용자 인터페이스 (UI) 요소가 포함됩니다. (하나 이상의 값 포함) 위젯 총 sections개 사용자로부터 정보를 수집하려면 양식 입력 위젯과 버튼 위젯입니다. 양식 입력 설계에 관한 자세한 내용은 다음을 참고하세요. 사용자 정보 수집 및 처리

다음 JSON은 채팅 앱이 반환되는 방식을 보여줍니다. 대화상자가 열립니다.

{ "actionResponse": {
  "type": "DIALOG",
  "dialogAction": { "dialog": { "body": { "sections": [{
    "widgets": [{
      WIDGETS,
      { "buttonList": { "buttons": [{
        "text": "BUTTON_TEXT",
        "onClick": {
          "action": {"function": "FUNCTION_NAME"}
        }
      }]}}
    }]
  }]}}}
}}

여기서 BUTTON_TEXT는 버튼에 표시되는 텍스트입니다 (예: Next 또는 Submit), WIDGETS는 하나 이상을 나타냄 양식 입력 위젯 FUNCTION_NAME는 사용자가 버튼을 클릭할 때 실행되는 함수입니다.

대화상자 제출 처리

사용자가 대화상자를 제출하는 버튼을 클릭하면 채팅 앱 수신 CARD_CLICKED 상호작용 이벤트에서 dialogEventTypeSUBMIT_DIALOG입니다.

채팅 앱은 다음과 같이 상호작용 이벤트를 처리해야 합니다. 다음 중 하나를 실행합니다.

선택사항: 다른 대화상자 반환

사용자가 초기 대화상자를 제출하면 채팅 앱에서 다음 작업을 할 수 있습니다. 사용자가 추가 정보를 검토할 수 있도록 하나 이상의 추가 대화상자를 반환 다단계 양식을 작성하거나 양식 콘텐츠를 동적으로 채울 수 없습니다.

사용자가 초기 대화상자에서 입력하는 데이터를 로드하려면 매개변수를 다음 대화상자를 여는 버튼에 추가하거나 원본 CARD_CLICKED 상호작용 이벤트 자세한 내용은 다른 카드로 데이터 이전하기

이 예에서 채팅 앱은 제출하기 전에 두 번째 대화상자를 반환합니다. 입력 데이터를 로드하려면 채팅 앱이 CARD_CLICKED 상호작용 이벤트를 전달 다음 대화상자를 여는 함수의 매개변수로 사용합니다.

Node.js

// Respond to button clicks on attached cards
if (event.type === "CARD_CLICKED") {

  // Open the first dialog.
  if (event.common.invokedFunction === "openDialog") {
    openDialog(event);
  }

  // Open the second dialog.
  if (event.common.invokedFunction === "openNextDialog") {
    openNextDialog(event);
  }
}

/**
* Opens and starts a dialog that lets users add details about a contact.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openDialog(event) {
  res.json({ "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      { "buttonList": { "buttons": [{
        "text": "Next",
        "onClick": { "action": {
          "function": "openNextDialog"
        }}
      }]}}
    ]}]}}}
  }});
};

/**
* Opens a second dialog that lets users add more contact details.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openNextDialog(event) {
  res.json({ "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      {
        "horizontalAlignment": "END",
        "buttonList": { "buttons": [{
          "text": "Submit",
          "onClick": { "action": {
            "function": "submitDialog"
          }}
        }]}
      }
    ]}]}}}
  }});
}

Python

from typing import Any, Mapping

import flask
import functions_framework

@functions_framework.http
def main(req: flask.Request) -> Mapping[str, Any]:
  """Responds to a MESSAGE event in Google Chat that includes the /createContact
     slash command by opening a dialog.

  Args:
      req (flask.Request): the event object from Chat API.

  Returns:
      Mapping[str, Any]: open a Dialog in response to a card's button click.
  """

  if req.method == 'GET':
    return 'Sorry, this function must be called from a Google Chat.'

  request = req.get_json(silent=True)

  if request.get('type') == 'CARD_CLICKED':
    if invoked_function := request.get('common', dict()).get('invokedFunction'):
      if invoked_function == 'open_dialog':
        return open_dialog(request)

      elif invoked_function == 'open_next_dialog':
        return open_dialog(request)

def open_dialog(request: Mapping[str, Any]) -> Mapping[str, Any]:
  """Opens a dialog in Google Chat.

  Args:
      request (Mapping[str, Any]): the event object from Chat API.

  Returns:
      Mapping[str, Any]: open a Dialog in response to a card's button click.
  """
  return { "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      { "buttonList": { "buttons": [{
        "text": "Next",
        "onClick": { "action": {
          "function": "open_next_dialog"
        }}
      }]}}
    ]}]}}}
  }}

def open_next_dialog(request: Mapping[str, Any]) -> Mapping[str, Any]:
  """Opens a second dialog that lets users add more contact details.

  Args:
      request (Mapping[str, Any]): the event object from Chat API.

  Returns:
      Mapping[str, Any]: open a Dialog in response to a card's button click.
  """
  return { "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      {
        "horizontalAlignment": "END",
        "buttonList": { "buttons": [{
          "text": "Submit",
          "onClick": { "action": {
            "function": "submit_dialog"
          }}
        }]}
      }
    ]}]}}}
  }}

Apps Script

이 예시에서는 카드 JSON과 함께 사용합니다. 또한 Apps Script 카드 서비스.

/**
* Responds to a CARD_CLICKED event in Google Chat.
*
* @param {Object} event the event object from Google Chat
*/
function onCardClick(event) {

  // When a user clicks a card, the Chat app checks to see which function to run.
  if (event.common.invokedFunction === "openDialog") {
    return openDialog(event);
  }

  if (event.common.invokedFunction === "openNextDialog") {
    return openNextDialog(event);
  }
}

/**
* Opens and starts a dialog that lets users add details about a contact.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openDialog(event) {
  return { "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      { "buttonList": { "buttons": [{
        "text": "Next",
        "onClick": { "action": {
          "function": "openNextDialog"
        }}
      }]}}
    ]}]}}}
  }};
}

/**
* Opens a second dialog that lets users add more contact details.
*
* @param {object} event the event object from Google Chat.
*
* @return {object} open a dialog.
*/
function openNextDialog(event) {
  return { "actionResponse": {
    "type": "DIALOG",
    "dialogAction": { "dialog": { "body": { "sections": [{ "widgets": [
      WIDGETS,
      {
        "horizontalAlignment": "END",
        "buttonList": { "buttons": [{
          "text": "Submit",
          "onClick": { "action": {
            "function": "submitDialog"
          }}
        }]}
      }
    ]}]}}}
  }};
}

여기서 WIDGETS는 하나 이상을 나타냅니다. 양식 입력 위젯입니다.

대화상자 닫기

사용자가 대화상자의 버튼을 클릭하면 채팅 앱이 다음 정보를 참조하세요.

다음 섹션에서는 사용자가 입력하는 데이터의 유효성을 검사하고 대화상자를 닫습니다.

사용자 입력 데이터 유효성 검사 및 대화상자 닫기

사용자가 입력하는 데이터를 처리하기 위해 Chat 앱은 는 event.common.formInputs 드림 객체를 지정합니다. 입력 위젯에서 값을 가져오는 방법에 관한 자세한 내용은 다음을 참고하세요. 사용자 정보 수집 및 처리

사용자가 필수 입력란을 생략하거나 잘못된 값을 입력하면 채팅 앱은 ActionResponse 드림 ("actionStatus": "ERROR MESSAGE" 포함)

다음 예에서는 사용자가 textInput 위젯과 같은 문자열 (stringInputs)을 허용합니다. 이 항목이 없는 경우 채팅 앱이 오류를 반환합니다. 있는 경우 채팅 앱이 대화상자 제출을 확인하고 는 대화상자를 닫습니다.

Node.js

/**
* Checks for a form input error, the absence of
* a "name" value, and returns an error if absent.
* Otherwise, confirms successful receipt of a dialog.
*
* Confirms successful receipt of a dialog.
*
* @param {Object} event the event object from Chat API.
*
* @return {Object} open a Dialog in Google Chat.
*/
function submitDialog(event) {

  // Checks to make sure the user entered a value
  // in a dialog. If no value detected, returns
  // an error message. Any "actionStatus" value other than "OK"
  // gets returned as an error.
  if (event.common.formInputs.WIDGET_NAME.stringInputs.value[0] === "") {
    res.json({
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "ERROR_MESSAGE"
        }
      }
    });

    // Otherwise the Chat app indicates that it received
    // form data from the dialog. An "actionStatus" of "OK" is
    // interpreted as code 200, and the dialog closes.
  } else {
    res.json({
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "OK"
        }
      }
    });
  }
}

Python

def receive_dialog(event: Mapping[str, Any]) -> Mapping[str, Any]:
  """Checks for a form input error, the absence of a "name" value, and returns
     an error if absent. Otherwise, confirms successful receipt of a dialog.

  Args:
      event (Mapping[str, Any]): the event object from Chat API.

  Returns:
      Mapping[str, Any]: the response.
  """

  if common := event.get('common'):
    if form_inputs := common.get('formInputs'):
      if contact_name := form_inputs.get('WIDGET_NAME'):
        if string_inputs := contact_name.get('stringInputs'):
          if name := string_inputs.get('value')[0]:
            return {
              'actionResponse': {
                'type': 'DIALOG',
                'dialogAction': {
                  'actionStatus': 'OK'
                }
              }
            }
          else:
            return {
              'actionResponse': {
                'type': 'DIALOG',
                'dialogAction': {
                  'actionStatus': 'ERROR_MESSAGE'
                }
              }
            }

Apps Script

이 예시에서는 카드 JSON과 함께 사용합니다. 또한 Apps Script 카드 서비스.

/**
* Checks for a form input error, the absence of
* a "name" value, and returns an error if absent.
* Otherwise, confirms successful receipt of a dialog.
*
* Confirms successful receipt of a dialog.
*
* @param {Object} event the event object from Chat API.
*
* @return {object} open a Dialog in Google Chat.
*/
function submitDialog(event) {

  // Checks to make sure the user entered a value
  // in a dialog. If no value detected, returns
  // an error message. Any "actionStatus" value other than "OK"
  // gets returned as an error.
  if (event.common.formInputs.WIDGET_NAME[""].stringInputs.value[0] === "") {
    return {
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "ERROR_MESSAGE"
        }
      }
    };

    // Otherwise the Chat app indicates that it received
    // form data from the dialog. An "actionStatus" of "OK" is
    // interpreted as code 200, and the dialog closes.
  } else {
    return {
      "actionResponse": {
        "type": "DIALOG",
        "dialogAction": {
          "actionStatus": "OK"
        }
      }
    };
  }
}

이 예에서 WIDGET_NAMEname 위젯 (예: contactName)을 포함하고 ERROR_MESSAGE는 오류 메시지의 내용 (예: Don't forget to name your contact) 위젯의 입력 데이터 처리에 대한 자세한 내용은 다음을 참조하세요. 대화형 위젯에서 데이터 수신

선택사항: 확인 메시지 보내기

대화상자를 닫으면 새 메시지를 보내거나 있습니다.

새 메시지를 보내려면 ActionResponse 드림 객체(typeNEW_MESSAGE로 설정됨) 예를 들어 대화상자를 닫으려면 문자 메시지를 보내면 다음을 반환합니다.

  {
    "actionResponse": {
      "type": "NEW_MESSAGE",
    },
    "text": "Your information has been submitted."
  }

메시지를 업데이트하려면 다음을 포함하는 actionResponse 객체를 반환합니다. 메시지를 업데이트하고 type를 다음 중 하나로 설정합니다.

문제 해결

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

채팅 UI에 오류 메시지가 표시되지 않을 수도 있지만 오류 해결에 도움이 되는 오류 메시지 및 로그 데이터를 사용할 수 있음 채팅 앱의 오류 로깅이 사용 설정된 경우 보는 데 도움이 필요한 경우 오류를 수정하는 방법에 대한 자세한 내용은 Google Chat 오류 문제 해결하기