เปิดกล่องโต้ตอบแบบอินเทอร์แอกทีฟ

หน้านี้จะอธิบายวิธีที่แอป Chat เปิดกล่องโต้ตอบเพื่อตอบกลับผู้ใช้

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

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

ข้อกำหนดเบื้องต้น

Node.js

แอป Google Chat ที่เปิดใช้ฟีเจอร์แบบอินเทอร์แอกทีฟ หากต้องการสร้างแอป Chat แบบอินเทอร์แอกทีฟโดยใช้บริการ HTTP ให้ทําตามการเริ่มต้นใช้งานอย่างรวดเร็วนี้

Python

แอป Google Chat ที่เปิดใช้ฟีเจอร์แบบอินเทอร์แอกทีฟ หากต้องการสร้างแอป Chat แบบอินเทอร์แอกทีฟโดยใช้บริการ HTTP ให้ทําตามการเริ่มต้นใช้งานอย่างรวดเร็วนี้

Java

แอป Google Chat ที่เปิดใช้ฟีเจอร์แบบอินเทอร์แอกทีฟ หากต้องการสร้างแอป Chat แบบอินเทอร์แอกทีฟโดยใช้บริการ HTTP ให้ทําตามการเริ่มต้นใช้งานอย่างรวดเร็วนี้

Apps Script

แอป Google Chat ที่เปิดใช้ฟีเจอร์แบบอินเทอร์แอกทีฟ หากต้องการสร้างแอป Chat แบบอินเทอร์แอกทีฟใน Apps Script ให้ทำตามการเริ่มต้นใช้งานอย่างรวดเร็วนี้

เปิดกล่องโต้ตอบ

กล่องโต้ตอบที่มีวิดเจ็ตต่างๆ
รูปที่ 1: ตัวอย่างแอป Chat ที่เปิดกล่องโต้ตอบเพื่อรวบรวมข้อมูลติดต่อ

ส่วนนี้จะอธิบายวิธีตอบกลับและตั้งค่ากล่องโต้ตอบโดยทําดังนี้

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

ทริกเกอร์คําขอกล่องโต้ตอบ

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

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

  • ตอบกลับคำสั่งเครื่องหมายทับ หากต้องการทริกเกอร์คําขอจากคําสั่งเครื่องหมายทับ คุณต้องเลือกช่องทําเครื่องหมายเปิดกล่องโต้ตอบเมื่อกําหนดค่าคําสั่ง
  • ตอบสนองต่อการคลิกปุ่มในข้อความ ไม่ว่าจะเป็นส่วนหนึ่งของการ์ดหรือที่ด้านล่างของข้อความ หากต้องการทริกเกอร์คำขอจากปุ่มในข้อความ ให้กำหนดค่าการดำเนินการ onClick ของปุ่มโดยตั้งค่า interaction เป็น OPEN_DIALOG
  • ตอบสนองต่อการคลิกปุ่มในหน้าแรกของแอป Chat ดูข้อมูลเกี่ยวกับการเปิดกล่องโต้ตอบจากหน้าแรกได้ที่หัวข้อสร้างหน้าแรกสำหรับแอป Google Chat
ปุ่มที่เรียกให้กล่องโต้ตอบแสดงขึ้น
รูปที่ 2: แอป Chat ส่งข้อความแจ้งให้ผู้ใช้ใช้คำสั่ง /addContact ทับเครื่องหมายทับ
ข้อความยังมีปุ่มที่ผู้ใช้คลิกเพื่อเรียกใช้คําสั่งได้ด้วย

ตัวอย่างโค้ดต่อไปนี้แสดงวิธีเรียกใช้คําขอกล่องโต้ตอบจากปุ่มในข้อความการ์ด หากต้องการเปิดกล่องโต้ตอบ ให้ตั้งค่าช่องbutton.interactionเป็น OPEN_DIALOG

Node.js

node/contact-form-app/index.js
buttonList: { buttons: [{
  text: "Add Contact",
  onClick: { action: {
    function: "openInitialDialog",
    interaction: "OPEN_DIALOG"
  }}
}]}

Python

python/contact-form-app/main.py
'buttonList': { 'buttons': [{
  'text': "Add Contact",
  'onClick': { 'action': {
    'function': "openInitialDialog",
    'interaction': "OPEN_DIALOG"
  }}
}]}

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
.setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(new GoogleAppsCardV1Button()
  .setText("Add Contact")
  .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
    .setFunction("openInitialDialog")
    .setInteraction("OPEN_DIALOG"))))))));

Apps Script

ตัวอย่างนี้จะส่งข้อความการ์ดโดยการส่งคืน card JSON นอกจากนี้ คุณยังใช้บริการการ์ด Apps Script ได้ด้วย

apps-script/contact-form-app/main.gs
buttonList: { buttons: [{
  text: "Add Contact",
  onClick: { action: {
    function: "openInitialDialog",
    interaction: "OPEN_DIALOG"
  }}
}]}

เปิดกล่องโต้ตอบเริ่มต้น

เมื่อผู้ใช้เรียกคําขอกล่องโต้ตอบ แอป Chat ของคุณจะได้รับเหตุการณ์การโต้ตอบ ซึ่งแสดงเป็นประเภท event ใน Chat API หากการโต้ตอบทริกเกอร์คําขอกล่องโต้ตอบ ระบบจะตั้งค่าช่อง dialogEventType ของเหตุการณ์เป็น REQUEST_DIALOG

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

  • ออบเจ็กต์ actionResponse ที่มีการตั้งค่า type เป็น DIALOG
  • ออบเจ็กต์ dialogAction ช่อง body มีองค์ประกอบอินเทอร์เฟซผู้ใช้ (UI) เพื่อแสดงในการ์ด รวมถึงวิดเจ็ต sections อย่างน้อย 1 รายการ หากต้องการรวบรวมข้อมูลจากผู้ใช้ คุณสามารถระบุวิดเจ็ตการป้อนข้อมูลแบบฟอร์มและวิดเจ็ตปุ่ม ดูข้อมูลเพิ่มเติมเกี่ยวกับการออกแบบอินพุตแบบฟอร์มได้ที่รวบรวมและประมวลผลข้อมูลจากผู้ใช้

ตัวอย่างโค้ดต่อไปนี้แสดงวิธีที่แอป Chat แสดงการตอบกลับที่เปิดกล่องโต้ตอบ

Node.js

node/contact-form-app/index.js
/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @return {Object} a message with an action response to open a dialog.
 */
function openInitialDialog() {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { dialog: { body: { sections: [{
      header: "Add new contact",
      widgets: CONTACT_FORM_WIDGETS.concat([{
        buttonList: { buttons: [{
          text: "Review and submit",
          onClick: { action: { function: "openConfirmation" }}
        }]}
      }])
    }]}}}
  }};
}

Python

python/contact-form-app/main.py
def open_initial_dialog() -> dict:
  """Opens the initial step of the dialog that lets users add contact details."""
  return { 'actionResponse': {
    'type': "DIALOG",
    'dialogAction': { 'dialog': { 'body': { 'sections': [{
      'header': "Add new contact",
      'widgets': CONTACT_FORM_WIDGETS + [{
        'buttonList': { 'buttons': [{
          'text': "Review and submit",
          'onClick': { 'action': { 'function': "openConfirmation" }}
        }]}
      }]
    }]}}}
  }}

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
// Opens the initial step of the dialog that lets users add contact details.
Message openInitialDialog() {
  return new Message().setActionResponse(new ActionResponse()
    .setType("DIALOG")
    .setDialogAction(new DialogAction().setDialog(new Dialog().setBody(new GoogleAppsCardV1Card()
      .setSections(List.of(new GoogleAppsCardV1Section()
        .setHeader("Add new contact")
        .setWidgets(Stream.concat(
          CONTACT_FORM_WIDGETS.stream(),
          List.of(new GoogleAppsCardV1Widget()
            .setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(new GoogleAppsCardV1Button()
            .setText("Review and submit")
            .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
              .setFunction("openConfirmation"))))))).stream()).collect(Collectors.toList()))))))));
}

Apps Script

ตัวอย่างนี้จะส่งข้อความการ์ดโดยแสดงcard JSON นอกจากนี้ คุณยังใช้บริการการ์ด Apps Script ได้ด้วย

apps-script/contact-form-app/main.gs
/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @return {Object} a message with an action response to open a dialog.
 */
function openInitialDialog() {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { dialog: { body: { sections: [{
      header: "Add new contact",
      widgets: CONTACT_FORM_WIDGETS.concat([{
        buttonList: { buttons: [{
          text: "Review and submit",
          onClick: { action: { function: "openConfirmation" }}
        }]}
      }])
    }]}}}
  }};
}

จัดการการส่งกล่องโต้ตอบ

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

แอป Chat ของคุณต้องจัดการเหตุการณ์การโต้ตอบโดยทําอย่างใดอย่างหนึ่งต่อไปนี้

ไม่บังคับ: แสดงกล่องโต้ตอบอื่น

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

แอปแชทจะใช้ออบเจ็กต์ event.common.formInputs เพื่อประมวลผลข้อมูลที่ผู้ใช้ป้อน ดูข้อมูลเพิ่มเติมเกี่ยวกับการดึงค่าจากวิดเจ็ตอินพุตได้ที่หัวข้อรวบรวมและประมวลผลข้อมูลจากผู้ใช้

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

ในตัวอย่างนี้ แอป Chat จะเปิดกล่องโต้ตอบแรกซึ่งนําไปยังกล่องโต้ตอบที่ 2 เพื่อการยืนยันก่อนส่ง

Node.js

node/contact-form-app/index.js
/**
 * Responds to CARD_CLICKED interaction events in Google Chat.
 *
 * @param {Object} event the CARD_CLICKED interaction event from Google Chat.
 * @return {Object} message responses specific to the dialog handling.
 */
function onCardClick(event) {
  // Initial dialog form page
  if (event.common.invokedFunction === "openInitialDialog") {
    return openInitialDialog();
  // Confirmation dialog form page
  } else if (event.common.invokedFunction === "openConfirmation") {
    return openConfirmation(event);
  // Submission dialog form page
  } else if (event.common.invokedFunction === "submitForm") {
    return submitForm(event);
  }
}

/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @return {Object} a message with an action response to open a dialog.
 */
function openInitialDialog() {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { dialog: { body: { sections: [{
      header: "Add new contact",
      widgets: CONTACT_FORM_WIDGETS.concat([{
        buttonList: { buttons: [{
          text: "Review and submit",
          onClick: { action: { function: "openConfirmation" }}
        }]}
      }])
    }]}}}
  }};
}

/**
 * Returns the second step as a dialog or card message that lets users confirm details.
 *
 * @param {Object} event the interactive event with form inputs.
 * @return {Object} returns a dialog or private card message.
 */
function openConfirmation(event) {
  const name = fetchFormValue(event, "contactName") ?? "";
  const birthdate = fetchFormValue(event, "contactBirthdate") ?? "";
  const type = fetchFormValue(event, "contactType") ?? "";
  const cardConfirmation = {
    header: "Your contact",
    widgets: [{
      textParagraph: { text: "Confirm contact information and submit:" }}, {
      textParagraph: { text: "<b>Name:</b> " + name }}, {
      textParagraph: {
        text: "<b>Birthday:</b> " + convertMillisToDateString(birthdate)
      }}, {
      textParagraph: { text: "<b>Type:</b> " + type }}, {
      buttonList: { buttons: [{
        text: "Submit",
        onClick: { action: {
          function: "submitForm",
          parameters: [{
            key: "contactName", value: name }, {
            key: "contactBirthdate", value: birthdate }, {
            key: "contactType", value: type
          }]
        }}
      }]}
    }]
  };

  // Returns a dialog with contact information that the user input.
  if (event.isDialogEvent) {
    return { action_response: {
      type: "DIALOG",
      dialogAction: { dialog: { body: { sections: [ cardConfirmation ]}}}
    }};
  }

  // Updates existing card message with contact information that the user input.
  return {
    actionResponse: { type: "UPDATE_MESSAGE" },
    privateMessageViewer: event.user,
    cardsV2: [{
      card: { sections: [cardConfirmation]}
    }]
  }
}

Python

python/contact-form-app/main.py
def on_card_click(event: dict) -> dict:
  """Responds to CARD_CLICKED interaction events in Google Chat."""
  # Initial dialog form page
  if "openInitialDialog" == event.get('common').get('invokedFunction'):
    return open_initial_dialog()
  # Confirmation dialog form page
  elif "openConfirmation" == event.get('common').get('invokedFunction'):
    return open_confirmation(event)
  # Submission dialog form page
  elif "submitForm" == event.get('common').get('invokedFunction'):
    return submit_form(event)


def open_initial_dialog() -> dict:
  """Opens the initial step of the dialog that lets users add contact details."""
  return { 'actionResponse': {
    'type': "DIALOG",
    'dialogAction': { 'dialog': { 'body': { 'sections': [{
      'header': "Add new contact",
      'widgets': CONTACT_FORM_WIDGETS + [{
        'buttonList': { 'buttons': [{
          'text': "Review and submit",
          'onClick': { 'action': { 'function': "openConfirmation" }}
        }]}
      }]
    }]}}}
  }}


def open_confirmation(event: dict) -> dict:
  """Returns the second step as a dialog or card message that lets users confirm details."""
  name = fetch_form_value(event, "contactName") or ""
  birthdate = fetch_form_value(event, "contactBirthdate") or ""
  type = fetch_form_value(event, "contactType") or ""
  card_confirmation = {
    'header': "Your contact",
    'widgets': [{
      'textParagraph': { 'text': "Confirm contact information and submit:" }}, {
      'textParagraph': { 'text': "<b>Name:</b> " + name }}, {
      'textParagraph': {
        'text': "<b>Birthday:</b> " + convert_millis_to_date_string(birthdate)
      }}, {
      'textParagraph': { 'text': "<b>Type:</b> " + type }}, {
      'buttonList': { 'buttons': [{
        'text': "Submit",
        'onClick': { 'action': {
          'function': "submitForm",
          'parameters': [{
            'key': "contactName", 'value': name }, {
            'key': "contactBirthdate", 'value': birthdate }, {
            'key': "contactType", 'value': type
          }]
        }}
      }]}
    }]
  }

  # Returns a dialog with contact information that the user input.
  if event.get('isDialogEvent'): 
    return { 'action_response': {
      'type': "DIALOG",
      'dialogAction': { 'dialog': { 'body': { 'sections': [card_confirmation] }}}
    }}

  # Updates existing card message with contact information that the user input.
  return {
    'actionResponse': { 'type': "UPDATE_MESSAGE" },
    'privateMessageViewer': event.get('user'),
    'cardsV2': [{
      'card': { 'sections': [card_confirmation] }
    }]
  }

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
// Responds to CARD_CLICKED interaction events in Google Chat.
Message onCardClick(JsonNode event) {
  String invokedFunction = event.at("/common/invokedFunction").asText();
  // Initial dialog form page
  if ("openInitialDialog".equals(invokedFunction)) {
    return openInitialDialog();
  // Confirmation dialog form page
  } else if ("openConfirmation".equals(invokedFunction)) {
    return openConfirmation(event);
  // Submission dialog form page
  } else if ("submitForm".equals(invokedFunction)) {
    return submitForm(event);
  }
  return null; 
}

// Opens the initial step of the dialog that lets users add contact details.
Message openInitialDialog() {
  return new Message().setActionResponse(new ActionResponse()
    .setType("DIALOG")
    .setDialogAction(new DialogAction().setDialog(new Dialog().setBody(new GoogleAppsCardV1Card()
      .setSections(List.of(new GoogleAppsCardV1Section()
        .setHeader("Add new contact")
        .setWidgets(Stream.concat(
          CONTACT_FORM_WIDGETS.stream(),
          List.of(new GoogleAppsCardV1Widget()
            .setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(new GoogleAppsCardV1Button()
            .setText("Review and submit")
            .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
              .setFunction("openConfirmation"))))))).stream()).collect(Collectors.toList()))))))));
}

// Returns the second step as a dialog or card message that lets users confirm details.
Message openConfirmation(JsonNode event) {
  String name = fetchFormValue(event, "contactName") != null ?
    fetchFormValue(event, "contactName") : "";
  String birthdate = fetchFormValue(event, "contactBirthdate") != null ?
    fetchFormValue(event, "contactBirthdate") : "";
  String type = fetchFormValue(event, "contactType") != null ?
    fetchFormValue(event, "contactType") : "";
  GoogleAppsCardV1Section cardConfirmationSection = new GoogleAppsCardV1Section()
    .setHeader("Your contact")
    .setWidgets(List.of(
      new GoogleAppsCardV1Widget().setTextParagraph(new GoogleAppsCardV1TextParagraph()
        .setText("Confirm contact information and submit:")),
      new GoogleAppsCardV1Widget().setTextParagraph(new GoogleAppsCardV1TextParagraph()
        .setText("<b>Name:</b> " + name)),
      new GoogleAppsCardV1Widget().setTextParagraph(new GoogleAppsCardV1TextParagraph()
        .setText("<b>Birthday:</b> " + convertMillisToDateString(birthdate))),
      new GoogleAppsCardV1Widget().setTextParagraph(new GoogleAppsCardV1TextParagraph()
        .setText("<b>Type:</b> " + type)),
      new GoogleAppsCardV1Widget().setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(new GoogleAppsCardV1Button()
        .setText("Submit")
        .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
          .setFunction("submitForm")
          .setParameters(List.of(
            new GoogleAppsCardV1ActionParameter().setKey("contactName").setValue(name),
            new GoogleAppsCardV1ActionParameter().setKey("contactBirthdate").setValue(birthdate),
            new GoogleAppsCardV1ActionParameter().setKey("contactType").setValue(type))))))))));

  // Returns a dialog with contact information that the user input.
  if (event.at("/isDialogEvent") != null && event.at("/isDialogEvent").asBoolean()) {
    return new Message().setActionResponse(new ActionResponse()
      .setType("DIALOG")
      .setDialogAction(new DialogAction().setDialog(new Dialog().setBody(new GoogleAppsCardV1Card()
        .setSections(List.of(cardConfirmationSection))))));
  }

  // Updates existing card message with contact information that the user input.
  return new Message()
    .setActionResponse(new ActionResponse()
      .setType("UPDATE_MESSAGE"))
    .setPrivateMessageViewer(new User().setName(event.at("/user/name").asText()))
    .setCardsV2(List.of(new CardWithId().setCard(new GoogleAppsCardV1Card()
      .setSections(List.of(cardConfirmationSection)))));
}

Apps Script

ตัวอย่างนี้จะส่งข้อความการ์ดโดยแสดงcard JSON นอกจากนี้ คุณยังใช้บริการการ์ด Apps Script ได้ด้วย

apps-script/contact-form-app/main.gs
/**
 * Responds to CARD_CLICKED interaction events in Google Chat.
 *
 * @param {Object} event the CARD_CLICKED interaction event from Google Chat.
 * @return {Object} message responses specific to the dialog handling.
 */
function onCardClick(event) {
  // Initial dialog form page
  if (event.common.invokedFunction === "openInitialDialog") {
    return openInitialDialog();
  // Confirmation dialog form page
  } else if (event.common.invokedFunction === "openConfirmation") {
    return openConfirmation(event);
  // Submission dialog form page
  } else if (event.common.invokedFunction === "submitForm") {
    return submitForm(event);
  }
}

/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @return {Object} a message with an action response to open a dialog.
 */
function openInitialDialog() {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { dialog: { body: { sections: [{
      header: "Add new contact",
      widgets: CONTACT_FORM_WIDGETS.concat([{
        buttonList: { buttons: [{
          text: "Review and submit",
          onClick: { action: { function: "openConfirmation" }}
        }]}
      }])
    }]}}}
  }};
}

/**
 * Returns the second step as a dialog or card message that lets users confirm details.
 *
 * @param {Object} event the interactive event with form inputs.
 * @return {Object} returns a dialog or private card message.
 */
function openConfirmation(event) {
  const name = fetchFormValue(event, "contactName") ?? "";
  const birthdate = fetchFormValue(event, "contactBirthdate") ?? "";
  const type = fetchFormValue(event, "contactType") ?? "";
  const cardConfirmation = {
    header: "Your contact",
    widgets: [{
      textParagraph: { text: "Confirm contact information and submit:" }}, {
      textParagraph: { text: "<b>Name:</b> " + name }}, {
      textParagraph: {
        text: "<b>Birthday:</b> " + convertMillisToDateString(birthdate)
      }}, {
      textParagraph: { text: "<b>Type:</b> " + type }}, {
      buttonList: { buttons: [{
        text: "Submit",
        onClick: { action: {
          function: "submitForm",
          parameters: [{
            key: "contactName", value: name }, {
            key: "contactBirthdate", value: birthdate }, {
            key: "contactType", value: type
          }]
        }}
      }]}
    }]
  };

  // Returns a dialog with contact information that the user input.
  if (event.isDialogEvent) {
    return { action_response: {
      type: "DIALOG",
      dialogAction: { dialog: { body: { sections: [ cardConfirmation ]}}}
    }};
  }

  // Updates existing card message with contact information that the user input.
  return {
    actionResponse: { type: "UPDATE_MESSAGE" },
    privateMessageViewer: event.user,
    cardsV2: [{
      card: { sections: [cardConfirmation]}
    }]
  }
}

ปิดกล่องโต้ตอบ

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

แอป Chat ควรแสดงผลออบเจ็กต์ ActionResponse โดยตั้งค่า type เป็น DIALOG และ dialogAction

ไม่บังคับ: แสดงการแจ้งเตือน

เมื่อปิดกล่องโต้ตอบ คุณยังแสดงการแจ้งเตือนข้อความได้ด้วย

แอป Chat สามารถตอบกลับด้วยการแจ้งเตือนว่าสำเร็จหรือมีข้อผิดพลาดโดยส่ง ActionResponse ที่มีการตั้งค่า actionStatus

ตัวอย่างต่อไปนี้จะตรวจสอบว่าพารามิเตอร์ถูกต้องและปิดกล่องโต้ตอบด้วยการแจ้งเตือนแบบข้อความโดยขึ้นอยู่กับผลลัพธ์

Node.js

node/contact-form-app/index.js
const contactName = event.common.parameters["contactName"];
// Checks to make sure the user entered a contact name.
// If no name value detected, returns an error message.
if (!contactName) {
  const errorMessage = "Don't forget to name your new contact!";
  if (event.dialogEventType === "SUBMIT_DIALOG") {
    return { actionResponse: {
      type: "DIALOG",
      dialogAction: { actionStatus: {
        statusCode: "INVALID_ARGUMENT",
        userFacingMessage: errorMessage
      }}
    }};
  } else {
    return {
      privateMessageViewer: event.user,
      text: errorMessage
    };
  }
}

Python

python/contact-form-app/main.py
contact_name = event.get('common').get('parameters')["contactName"]
# Checks to make sure the user entered a contact name.
# If no name value detected, returns an error message.
if contact_name == "":
  error_message = "Don't forget to name your new contact!"
  if "SUBMIT_DIALOG" == event.get('dialogEventType'):
    return { 'actionResponse': {
      'type': "DIALOG",
      'dialogAction': { 'actionStatus': {
        'statusCode': "INVALID_ARGUMENT",
        'userFacingMessage': error_message
      }}
    }}
  else:
    return {
      'privateMessageViewer': event.get('user'),
      'text': error_message
    }

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
String contactName = event.at("/common/parameters/contactName").asText();
// Checks to make sure the user entered a contact name.
// If no name value detected, returns an error message.
if (contactName.isEmpty()) {
  String errorMessage = "Don't forget to name your new contact!";
  if (event.at("/dialogEventType") != null && "SUBMIT_DIALOG".equals(event.at("/dialogEventType").asText())) {
    return new Message().setActionResponse(new ActionResponse()
      .setType("DIALOG")
      .setDialogAction(new DialogAction().setActionStatus(new ActionStatus()
        .setStatusCode("INVALID_ARGUMENT")
        .setUserFacingMessage(errorMessage))));
  } else {
    return new Message()
      .setPrivateMessageViewer(new User().setName(event.at("/user/name").asText()))
      .setText(errorMessage);
  }
}

Apps Script

ตัวอย่างนี้จะส่งข้อความการ์ดโดยแสดงcard JSON นอกจากนี้ คุณยังใช้บริการการ์ด Apps Script ได้ด้วย

apps-script/contact-form-app/main.gs
const contactName = event.common.parameters["contactName"];
// Checks to make sure the user entered a contact name.
// If no name value detected, returns an error message.
if (!contactName) {
  const errorMessage = "Don't forget to name your new contact!";
  if (event.dialogEventType === "SUBMIT_DIALOG") {
    return { actionResponse: {
      type: "DIALOG",
      dialogAction: { actionStatus: {
        statusCode: "INVALID_ARGUMENT",
        userFacingMessage: errorMessage
      }}
    }};
  } else {
    return {
      privateMessageViewer: event.user,
      text: errorMessage
    };
  }
}

โปรดดูรายละเอียดเกี่ยวกับการส่งพารามิเตอร์ระหว่างกล่องโต้ตอบที่หัวข้อโอนข้อมูลไปยังการ์ดอื่น

ไม่บังคับ: ส่งข้อความยืนยัน

เมื่อปิดกล่องโต้ตอบ คุณจะส่งข้อความใหม่หรืออัปเดตข้อความที่มีอยู่ได้ด้วย

หากต้องการส่งข้อความใหม่ ให้แสดงผลออบเจ็กต์ ActionResponse โดยตั้งค่า type เป็น NEW_MESSAGE ตัวอย่างต่อไปนี้จะปิดกล่องโต้ตอบด้วยการแจ้งเตือนข้อความและข้อความยืนยัน

Node.js

node/contact-form-app/index.js
// The Chat app indicates that it received form data from the dialog or card.
// Sends private text message that confirms submission.
const confirmationMessage = "✅ " + contactName + " has been added to your contacts.";
if (event.dialogEventType === "SUBMIT_DIALOG") {
  return {
    actionResponse: {
      type: "DIALOG",
      dialogAction: { actionStatus: {
        statusCode: "OK",
        userFacingMessage: "Success " + contactName
      }}
    }
  }
} else {
  return {
    actionResponse: { type: "NEW_MESSAGE" },
    privateMessageViewer: event.user,
    text: confirmationMessage
  };
}

Python

python/contact-form-app/main.py
# The Chat app indicates that it received form data from the dialog or card.
# Sends private text message that confirms submission.
confirmation_message = "✅ " + contact_name + " has been added to your contacts.";
if "SUBMIT_DIALOG" == event.get('dialogEventType'):
  return {
    'actionResponse': {
      'type': "DIALOG",
      'dialogAction': { 'actionStatus': {
        'statusCode': "OK",
        'userFacingMessage': "Success " + contact_name
      }}
    }
  }
else:
  return {
    'actionResponse': { 'type': "NEW_MESSAGE" },
    'privateMessageViewer': event.get('user'),
    'text': confirmation_message
  }

Java

java/contact-form-app/src/main/java/com/google/chat/contact/App.java
// The Chat app indicates that it received form data from the dialog or card.
// Sends private text message that confirms submission.
String confirmationMessage = "✅ " + contactName + " has been added to your contacts.";
if (event.at("/dialogEventType") != null && "SUBMIT_DIALOG".equals(event.at("/dialogEventType").asText())) {
  return new Message().setActionResponse(new ActionResponse()
    .setType("DIALOG")
    .setDialogAction(new DialogAction().setActionStatus(new ActionStatus()
      .setStatusCode("OK")
      .setUserFacingMessage("Success " + contactName))));
} else {
  return new Message()
    .setActionResponse(new ActionResponse().setType("NEW_MESSAGE"))
    .setPrivateMessageViewer(new User().setName(event.at("/user/name").asText()))
    .setText(confirmationMessage);
}

Apps Script

ตัวอย่างนี้จะส่งข้อความการ์ดโดยแสดงcard JSON นอกจากนี้ คุณยังใช้บริการการ์ด Apps Script ได้ด้วย

apps-script/contact-form-app/main.gs
// The Chat app indicates that it received form data from the dialog or card.
// Sends private text message that confirms submission.
const confirmationMessage = "✅ " + contactName + " has been added to your contacts.";
if (event.dialogEventType === "SUBMIT_DIALOG") {
  return {
    actionResponse: {
      type: "DIALOG",
      dialogAction: { actionStatus: {
        statusCode: "OK",
        userFacingMessage: "Success " + contactName
      }}
    }
  }
} else {
  return {
    actionResponse: { type: "NEW_MESSAGE" },
    privateMessageViewer: event.user,
    text: confirmationMessage
  };
}

หากต้องการอัปเดตข้อความ ให้แสดงผลออบเจ็กต์ actionResponse ที่มีข้อความที่อัปเดตแล้ว และตั้งค่า type เป็นค่าใดค่าหนึ่งต่อไปนี้

แก้ปัญหา

เมื่อแอป Google Chat หรือการ์ดแสดงข้อผิดพลาด อินเทอร์เฟซของ Chat จะแสดงข้อความว่า "เกิดข้อผิดพลาด" หรือ "ดำเนินการตามคำขอของคุณไม่ได้" บางครั้ง UI ของ Chat ไม่แสดงข้อความแสดงข้อผิดพลาด แต่แอป Chat หรือการ์ดให้ผลลัพธ์ที่ไม่คาดคิด เช่น ข้อความการ์ดอาจไม่ปรากฏ

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