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

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

กล่องโต้ตอบคืออินเทอร์เฟซแบบหน้าต่างและแบบการ์ด ซึ่งเปิดจากพื้นที่ใน 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. ทริกเกอร์คำขอ Dialog จากการโต้ตอบของผู้ใช้
  2. จัดการคำขอโดยส่งคืนและเปิดกล่องโต้ตอบ
  3. หลังจากที่ผู้ใช้ส่งข้อมูลแล้ว ให้ประมวลผลการส่งโดยปิดกล่องโต้ตอบหรือแสดงกล่องโต้ตอบอื่น

ทริกเกอร์คำขอ Dialog

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

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

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

ตัวอย่างโค้ดต่อไปนี้แสดงวิธีทริกเกอร์คำขอ Dialog จากปุ่มใน ข้อความการ์ด หากต้องการเปิดกล่องโต้ตอบ ให้ตั้งค่าฟิลด์ 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

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

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

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

เมื่อผู้ใช้ทริกเกอร์คำขอ 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

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

หากต้องการประมวลผลข้อมูลที่ผู้ใช้ป้อน แอป Chat จะใช้ออบเจ็กต์ 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

ตัวอย่างนี้จะส่งข้อความการ์ดโดยการส่งคืน 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 หาก การดำเนินการไม่ล้มเหลว dialogAction.actionStatus ควรเป็น OK ดังตัวอย่างต่อไปนี้

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

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
      }}
    }
  }

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))));
}

Apps Script

ตัวอย่างนี้จะส่งข้อความการ์ดโดยการส่งคืน 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
      }}
    }
  };
}

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

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

แอป 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.
const errorMessage = "Don't forget to name your new contact!";
if (!contactName && event.dialogEventType === "SUBMIT_DIALOG") {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { actionStatus: {
      statusCode: "INVALID_ARGUMENT",
      userFacingMessage: 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.
error_message = "Don't forget to name your new contact!"
if contact_name == "" and "SUBMIT_DIALOG" == event.get('dialogEventType'):
  return { 'actionResponse': {
    'type': "DIALOG",
    'dialogAction': { 'actionStatus': {
      'statusCode': "INVALID_ARGUMENT",
      'userFacingMessage': 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.
String errorMessage = "Don't forget to name your new contact!";
if (contactName.isEmpty() && 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))));
}

Apps Script

ตัวอย่างนี้จะส่งข้อความการ์ดโดยการส่งคืน 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.
const errorMessage = "Don't forget to name your new contact!";
if (!contactName && event.dialogEventType === "SUBMIT_DIALOG") {
  return { actionResponse: {
    type: "DIALOG",
    dialogAction: { actionStatus: {
      statusCode: "INVALID_ARGUMENT",
      userFacingMessage: errorMessage
    }}
  }};
}

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

ไม่บังคับ: ส่งข้อความแชทเพื่อยืนยัน

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

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

Node.js

node/contact-form-app/index.js
return {
  actionResponse: { type: "NEW_MESSAGE" },
  privateMessageViewer: event.user,
  text: confirmationMessage
};

Python

python/contact-form-app/main.py
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
return new Message()
  .setActionResponse(new ActionResponse().setType("NEW_MESSAGE"))
  .setPrivateMessageViewer(new User().setName(event.at("/user/name").asText()))
  .setText(confirmationMessage);

Apps Script

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

apps-script/contact-form-app/main.gs
return {
  actionResponse: { type: "NEW_MESSAGE" },
  privateMessageViewer: event.user,
  text: confirmationMessage
};

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

แก้ปัญหา

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

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