إنشاء مربّعات حوار تفاعلية

توضّح هذه الصفحة كيف يمكن لتطبيق Google Chat فتح مربّعات حوار لعرض واجهات المستخدمين والردّ على المستخدمين.

مربّعات الحوار هي واجهات مستندة إلى البطاقات ومفتوحة في نوافذ، تظهر من مساحة أو رسالة في Chat. ولا يظهر مربّع الحوار ومحتواه إلا للمستخدم الذي فتحه.

يمكن لتطبيقات المحادثات استخدام مربّعات الحوار لطلب المعلومات وجمعها من مستخدمي Chat، بما في ذلك النماذج المتعدّدة الخطوات. لمزيد من التفاصيل حول إنشاء حقول إدخال النماذج، يُرجى الاطّلاع على جمع المعلومات من المستخدمين ومعالجتها.

المتطلبات الأساسية

HTTP

إضافة Google Workspace توسّع نطاق Google Chat. لإنشاء واحد، أكمل البدء السريع في HTTP.

برمجة التطبيقات

إضافة Google Workspace توسّع نطاق Google Chat. لإنشاء تطبيق، أكمِل دليل البدء السريع في Apps Script.

فتح مربّع حوار

مربّع حوار يعرض مجموعة متنوعة من التطبيقات المصغّرة المختلفة
الشكل 1: تطبيق Chat يفتح مربع حوار لجمع معلومات الاتصال.

يوضّح هذا القسم كيفية الردّ على مربّع حوار وإعداده من خلال اتّباع الخطوات التالية:

  1. تفعيل طلب مربّع الحوار من خلال تفاعل المستخدم
  2. التعامل مع الطلب من خلال الرجوع إلى مربّع حوار وفتحه
  3. بعد أن يرسل المستخدمون المعلومات، عالِج عملية الإرسال من خلال إغلاق مربّع الحوار أو عرض مربّع حوار آخر.

تشغيل طلب مربّع حوار

لا يمكن لتطبيق Chat فتح مربّعات حوار إلا للرد على تفاعل المستخدم، مثل أمر أو نقرة على زر من رسالة في بطاقة.

للردّ على المستخدمين باستخدام مربّع حوار، يجب أن ينشئ تطبيق Chat تفاعلاً يؤدي إلى تشغيل طلب مربّع الحوار، مثل ما يلي:

  • الردّ على طلب لتفعيل الطلب من أمر، يجب وضع علامة في مربّع الاختيار يفتح مربّع حوار عند إعداد الأمر.
  • الرد على نقرة زر في رسالة، إما كجزء من بطاقة أو في أسفل الرسالة لتفعيل الطلب من زر في رسالة، عليك ضبط إجراء الزر onClick من خلال ضبط interaction على OPEN_DIALOG.
زر يؤدي إلى ظهور مربّع حوار
الشكل 2: يرسل تطبيق في Chat رسالة تطلب من المستخدمين استخدام الأمر /addContact.
تتضمّن الرسالة أيضًا زرًا يمكن للمستخدمين النقر عليه لتنفيذ الأمر.

يوضّح نموذج الرمز التالي كيفية بدء طلب مربع حوار من زر في رسالة بطاقة. لفتح مربّع الحوار، اضبط الحقل onClick.action.interaction للزّر على OPEN_DIALOG:

Node.js

node/chat/contact-form-app/index.js
{ buttonList: { buttons: [{
  text: "ADD CONTACT",
  onClick: { action: {
    function: FUNCTION_URL,
    interaction: "OPEN_DIALOG",
    parameters: [
      { key: "actionName", value: "openInitialDialog" }
    ]
  }}
}]}}

استبدِل FUNCTION_URL بنقطة نهاية HTTP التي تعالج نقرات الأزرار.

Python

python/chat/contact-form-app/main.py
{ 'buttonList': { 'buttons': [{
  'text': "ADD CONTACT",
  'onClick': { 'action': {
    'function': FUNCTION_URL,
    'interaction': "OPEN_DIALOG",
    'parameters': [
      { 'key': "actionName", 'value': "openInitialDialog" }
    ]
  }}
}]}}

استبدِل FUNCTION_URL بنقطة نهاية HTTP التي تعالج نقرات الأزرار.

Java

java/chat/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(FUNCTION_URL)
    .setInteraction("OPEN_DIALOG")
    .setParameters(List.of(
      new GoogleAppsCardV1ActionParameter().setKey("actionName").setValue("openInitialDialog"))))))))));

استبدِل FUNCTION_URL بنقطة نهاية HTTP التي تعالج نقرات الأزرار.

برمجة التطبيقات

يرسل هذا المثال رسالة بطاقة من خلال عرض JSON الخاص بالبطاقة. يمكنك أيضًا استخدام خدمة البطاقات في Apps Script.

apps-script/chat/contact-form-app/Code.gs
{ buttonList: { buttons: [{
  text: "ADD CONTACT",
  onClick: { action: {
    function: "openInitialDialog",
    interaction: "OPEN_DIALOG"
  }}
}]}}

فتح مربّع الحوار الأوّلي

عندما يفعّل المستخدم طلب مربّع حوار، يتلقّى تطبيق Chat كائن حدث يتضمّن حمولة تحدّد كائن dialogEventType على أنّه REQUEST_DIALOG.

لفتح مربّع حوار، يمكن لتطبيق Chat الردّ على الطلب من خلال عرض عنصر RenderActions مع pushCard التنقّل لعرض بطاقة. يجب أن تحتوي البطاقة على أي عناصر من واجهة المستخدم، بما في ذلك عنصر واحد أو أكثر من sections[]. لجمع المعلومات من المستخدمين، يمكنك تحديد عناصر واجهة مستخدم لإدخال النماذج وعنصر واجهة مستخدم للزر. لمزيد من المعلومات حول تصميم حقول إدخال النماذج، يُرجى الاطّلاع على جمع المعلومات ومعالجتها من المستخدمين.

يوضّح نموذج الرمز البرمجي التالي كيف يعرض تطبيق Chat ردًا يفتح مربع حوار:

Node.js

node/chat/contact-form-app/index.js
/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @return {Object} open the dialog.
 */
function openInitialDialog() {
  return { action: { navigations: [{ pushCard: { sections: [{ widgets: [
    { textInput: {
      name: "contactName",
      label: "First and last name",
      type: "SINGLE_LINE"
    }},
    { dateTimePicker: {
      name: "contactBirthdate",
      label: "Birthdate",
      type: "DATE_ONLY"
    }},
    { selectionInput: {
      name: "contactType",
      label: "Contact type",
      type: "RADIO_BUTTON",
      items: [
        { text: "Work", value: "Work", selected: false },
        { text: "Personal", value: "Personal", selected: false }
      ]
    }},
    { buttonList: { buttons: [{
      text: "NEXT",
      onClick: { action: {
        function: FUNCTION_URL,
        parameters: [
          { key: "actionName", value: "openConfirmationDialog" }
        ]
      }}
    }]}}
  ]}]}}]}};
}

استبدِل FUNCTION_URL بنقطة نهاية HTTP التي تعالج نقرات الأزرار.

Python

python/chat/contact-form-app/main.py
def open_initial_dialog() -> Mapping[str, Any]:
  """Opens the initial step of the dialog that lets users add contact details.

  Returns:
    Mapping[str, Any]: open the dialog.
  """
  return { 'action': { 'navigations': [{ 'pushCard': { 'sections': [{ 'widgets': [
    { 'textInput': {
      'name': "contactName",
      'label': "First and last name",
      'type': "SINGLE_LINE"
    }},
    { 'dateTimePicker': {
      'name': "contactBirthdate",
      'label': "Birthdate",
      'type': "DATE_ONLY"
    }},
    { 'selectionInput': {
      'name': "contactType",
      'label': "Contact type",
      'type': "RADIO_BUTTON",
      'items': [
        { 'text': "Work", 'value': "Work", 'selected': False },
        { 'text': "Personal", 'value': "Personal", 'selected': False }
      ]
    }},
    { 'buttonList': { 'buttons': [{
      'text': "NEXT",
      'onClick': { 'action': {
        'function': FUNCTION_URL,
        'parameters': [
          { 'key': "actionName", 'value': "openConfirmationDialog" }
        ]
      }}
    }]}}
  ]}]}}]}}

استبدِل FUNCTION_URL بنقطة نهاية HTTP التي تعالج نقرات الأزرار.

Java

java/chat/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.
 *
 * @return {Object} open the dialog.
 */
GenericJson openInitialDialog() {
  GoogleAppsCardV1Card cardV2 = new GoogleAppsCardV1Card()
    .setSections(List.of(new GoogleAppsCardV1Section().setWidgets(List.of(
      new GoogleAppsCardV1Widget().setTextInput(new GoogleAppsCardV1TextInput()
        .setName("contactName")
        .setLabel("First and last name")
        .setType("SINGLE_LINE")),
      new GoogleAppsCardV1Widget().setDateTimePicker(new GoogleAppsCardV1DateTimePicker()
        .setName("contactBirthdate")
        .setLabel("Birthdate")
        .setType("DATE_ONLY")),
      new GoogleAppsCardV1Widget().setSelectionInput(new GoogleAppsCardV1SelectionInput()
        .setName("contactType")
        .setLabel("Contact type")
        .setType("RADIO_BUTTON")
        .setItems(List.of(
          new GoogleAppsCardV1SelectionItem()
            .setText("Work")
            .setValue("Work")
            .setSelected(false),
          new GoogleAppsCardV1SelectionItem()
            .setText("Personal")
            .setValue("Personal")
            .setSelected(false)))),
      new GoogleAppsCardV1Widget().setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(
        new GoogleAppsCardV1Button()
          .setText("NEXT")
          .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
            .setFunction(FUNCTION_URL)
            .setParameters(List.of(
              new GoogleAppsCardV1ActionParameter().setKey("actionName").setValue("openConfirmationDialog"))))))))))));
  return new GenericJson() {{
    put("action", new GenericJson() {{
      put("navigations", List.of(new GenericJson() {{
        put("pushCard", cardV2);
      }}));
    }});
  }};
}

استبدِل FUNCTION_URL بنقطة نهاية HTTP التي تعالج نقرات الأزرار.

برمجة التطبيقات

يرسل هذا المثال رسالة بطاقة من خلال عرض JSON الخاص بالبطاقة. يمكنك أيضًا استخدام خدمة البطاقات في Apps Script.

apps-script/chat/contact-form-app/Code.gs
/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @param {Object} event The event object from the Google Workspace add-on.
 * @return {Object} open the dialog.
 */
function openInitialDialog(event) {
  return { action: { navigations: [{ pushCard: { sections: [{ widgets: [
    { textInput: {
      name: "contactName",
      label: "First and last name",
      type: "SINGLE_LINE"
    }},
    { dateTimePicker: {
      name: "contactBirthdate",
      label: "Birthdate",
      type: "DATE_ONLY"
    }},
    { selectionInput: {
      name: "contactType",
      label: "Contact type",
      type: "RADIO_BUTTON",
      items: [
        { text: "Work", value: "Work", selected: false },
        { text: "Personal", value: "Personal", selected: false }
      ]
    }},
    { buttonList: { buttons: [{
      text: "NEXT",
      onClick: { action: { function : "openConfirmationDialog" }}
    }]}}
  ]}]}}]}};
}

التعامل مع إرسال مربّع الحوار

عندما ينقر المستخدمون على زرّ يرسل مربّع حوار، يتلقّى تطبيق Chat عنصر حدث يتضمّن عنصر ButtonClickedPayload. في الحمولة، تم ضبط dialogEventType على SUBMIT_DIALOG. لمعرفة كيفية جمع المعلومات ومعالجتها في مربّع الحوار، يُرجى الاطّلاع على جمع المعلومات ومعالجتها من مستخدمي Google Chat.

يجب أن يستجيب تطبيق Chat لعنصر الحدث من خلال تنفيذ أحد الإجراءات التالية:

اختياري: عرض مربّع حوار آخر

بعد أن يرسل المستخدمون مربّع الحوار الأوّلي، يمكن لتطبيقات Chat عرض مربّع حوار إضافي أو أكثر لمساعدة المستخدمين في مراجعة المعلومات قبل إرسالها أو إكمال النماذج المتعدّدة الخطوات أو ملء محتوى النموذج بشكل ديناميكي.

لمعالجة البيانات التي يدخلها المستخدمون، يعالج تطبيق Chat البيانات في عنصر commonEventObject.formInputs الخاص بالحدث. لمزيد من المعلومات حول استرداد القيم من أدوات الإدخال، يُرجى الاطّلاع على جمع المعلومات من المستخدمين ومعالجتها.

لتتبُّع أي بيانات يُدخلها المستخدمون من مربّع الحوار الأوّلي، عليك إضافة مَعلمات إلى الزر الذي يفتح مربّع الحوار التالي. لمعرفة التفاصيل، يُرجى الاطّلاع على نقل البيانات إلى بطاقة أخرى.

في هذا المثال، يفتح تطبيق Chat مربّع حوار أوليًا يؤدي إلى مربّع حوار ثانٍ للتأكيد قبل الإرسال:

Node.js

node/chat/contact-form-app/index.js
/**
 * Responds to a message in Google Chat.
 *
 * @return {Object} response that handles dialogs.
 */
function handleMessage() {
  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    text: "To add a contact, use the `ADD CONTACT` button below.",
    accessoryWidgets: [
      { buttonList: { buttons: [{
        text: "ADD CONTACT",
        onClick: { action: {
          function: FUNCTION_URL,
          interaction: "OPEN_DIALOG",
          parameters: [
            { key: "actionName", value: "openInitialDialog" }
          ]
        }}
      }]}}
    ]
  }}}}};
}

/**
 * Responds to a button clicked in Google Chat.
 *
 * @param {Object} event The event object from the Google Workspace add-on.
 * @return {Object} response depending on the button clicked.
 */
function handleButtonClicked(event) {
  // Initial dialog form page
  if (event.commonEventObject.parameters.actionName === "openInitialDialog") {
    return openInitialDialog();
  // Confirmation dialog form page
  } else if (event.commonEventObject.parameters.actionName === "openConfirmationDialog") {
    return openConfirmationDialog(event);
  // Submission dialog form page
  } else if (event.commonEventObject.parameters.actionName === "submitDialog") {
    return submitDialog(event);
  }
}

/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @return {Object} open the dialog.
 */
function openInitialDialog() {
  return { action: { navigations: [{ pushCard: { sections: [{ widgets: [
    { textInput: {
      name: "contactName",
      label: "First and last name",
      type: "SINGLE_LINE"
    }},
    { dateTimePicker: {
      name: "contactBirthdate",
      label: "Birthdate",
      type: "DATE_ONLY"
    }},
    { selectionInput: {
      name: "contactType",
      label: "Contact type",
      type: "RADIO_BUTTON",
      items: [
        { text: "Work", value: "Work", selected: false },
        { text: "Personal", value: "Personal", selected: false }
      ]
    }},
    { buttonList: { buttons: [{
      text: "NEXT",
      onClick: { action: {
        function: FUNCTION_URL,
        parameters: [
          { key: "actionName", value: "openConfirmationDialog" }
        ]
      }}
    }]}}
  ]}]}}]}};
}

/**
 * Opens the second step of the dialog that lets users confirm details.
 *
 * @param {Object} event The event object from the Google Workspace add-on.
 * @return {Object} update the dialog.
 */
function openConfirmationDialog(event) {
  // Retrieve the form input values
  const name = event.commonEventObject.formInputs["contactName"].stringInputs.value[0];
  const birthdate = event.commonEventObject.formInputs["contactBirthdate"].dateInput.msSinceEpoch;
  const type = event.commonEventObject.formInputs["contactType"].stringInputs.value[0];
  // Display the input values for confirmation
  return { action: { navigations: [{ pushCard: { sections: [{ widgets: [
    { textParagraph: { text: "Confirm contact information and submit:" }},
    { textParagraph: { text: "<b>Name:</b> " + name }},
    { textParagraph: { text: "<b>Birthday:</b> " + new Date(birthdate) }},
    { textParagraph: { text: "<b>Type:</b> " + type }},
    { buttonList: { buttons: [{
      text: "SUBMIT",
      onClick: { action: {
        function: FUNCTION_URL,
        parameters: [
          { key: "actionName", value: "submitDialog" },
          // Pass input values as parameters for last dialog step (submission)
          { key: "contactName", value: name },
          { key: "contactBirthdate", value: birthdate },
          { key: "contactType", value: type }
        ]
      }}
    }]}}
  ]}]}}]}};
}

استبدِل FUNCTION_URL بنقطة نهاية HTTP التي تعالج نقرات الأزرار.

Python

python/chat/contact-form-app/main.py
def handle_message() -> Mapping[str, Any]:
  """Responds to a message in Google Chat.

  Returns:
    Mapping[str, Any]: the response that handles dialogs.
  """
  return { 'hostAppDataAction': { 'chatDataAction': { 'createMessageAction': { 'message': {
    'text': "To add a contact, use the `ADD CONTACT` button below.",
    'accessoryWidgets': [
      { 'buttonList': { 'buttons': [{
        'text': "ADD CONTACT",
        'onClick': { 'action': {
          'function': FUNCTION_URL,
          'interaction': "OPEN_DIALOG",
          'parameters': [
            { 'key': "actionName", 'value': "openInitialDialog" }
          ]
        }}
      }]}}
    ]
  }}}}}


def handle_button_clicked(event: Mapping[str, Any]) -> Mapping[str, Any]:
  """Responds to a button clicked in Google Chat.

  Args:
    Mapping[str, Any] event: the event object from the Google Workspace add-on

  Returns:
    Mapping[str, Any]: the response depending on the button clicked.
  """
  # Initial dialog form page
  if "openInitialDialog" == event['commonEventObject']['parameters']['actionName']:
    return open_initial_dialog()
  # Confirmation dialog form page
  elif "openConfirmationDialog" == event['commonEventObject']['parameters']['actionName'] :
    return open_confirmation_dialog(event)
  # Submission dialog form page
  elif "submitDialog" == event['commonEventObject']['parameters']['actionName']:
    return submit_dialog(event)


def open_initial_dialog() -> Mapping[str, Any]:
  """Opens the initial step of the dialog that lets users add contact details.

  Returns:
    Mapping[str, Any]: open the dialog.
  """
  return { 'action': { 'navigations': [{ 'pushCard': { 'sections': [{ 'widgets': [
    { 'textInput': {
      'name': "contactName",
      'label': "First and last name",
      'type': "SINGLE_LINE"
    }},
    { 'dateTimePicker': {
      'name': "contactBirthdate",
      'label': "Birthdate",
      'type': "DATE_ONLY"
    }},
    { 'selectionInput': {
      'name': "contactType",
      'label': "Contact type",
      'type': "RADIO_BUTTON",
      'items': [
        { 'text': "Work", 'value': "Work", 'selected': False },
        { 'text': "Personal", 'value': "Personal", 'selected': False }
      ]
    }},
    { 'buttonList': { 'buttons': [{
      'text': "NEXT",
      'onClick': { 'action': {
        'function': FUNCTION_URL,
        'parameters': [
          { 'key': "actionName", 'value': "openConfirmationDialog" }
        ]
      }}
    }]}}
  ]}]}}]}}


def open_confirmation_dialog(event: Mapping[str, Any]) -> Mapping[str, Any]:
  """Opens the second step of the dialog that lets users confirm details.

  Args:
    Mapping[str, Any] event: the event object from the Google Workspace add-on

  Returns:
    Mapping[str, Any]: update the dialog.
  """
  name = event.get('commonEventObject').get('formInputs')["contactName"].get('stringInputs').get('value')[0]
  birthdateEpoch = event.get('commonEventObject').get('formInputs')["contactBirthdate"].get('dateInput').get('msSinceEpoch')
  birthdate = datetime.fromtimestamp(int(birthdateEpoch) / 1000.0).strftime("%Y-%m-%d")
  type = event.get('commonEventObject').get('formInputs')["contactType"].get('stringInputs').get('value')[0]
  # Display the input values for confirmation
  return { 'action': { 'navigations': [{ 'pushCard': { 'sections': [{ 'widgets': [
    { 'textParagraph': { 'text': "Confirm contact information and submit:" }},
    { 'textParagraph': { 'text': "<b>Name:</b> " + name }},
    { 'textParagraph': { 'text': "<b>Birthday:</b> " + birthdate }},
    { 'textParagraph': { 'text': "<b>Type:</b> " + type }},
    { 'buttonList': { 'buttons': [{
      'text': "SUBMIT",
      'onClick': { 'action': {
        'function': FUNCTION_URL,
        'parameters': [
          { 'key': "actionName", 'value': "submitDialog" },
          # Pass input values as parameters for last dialog step (submission)
          { 'key': "contactName", 'value': name },
          { 'key': "contactBirthdate", 'value': birthdate },
          { 'key': "contactType", 'value': type }
        ]
      }}
    }]}}
  ]}]}}]}}

استبدِل FUNCTION_URL بنقطة نهاية HTTP التي تعالج نقرات الأزرار.

Java

java/chat/contact-form-app/src/main/java/com/google/chat/contact/App.java
/**
 * Responds to a message in Google Chat.
 *
 * @return response that handles dialogs.
 */
GenericJson handleMessage() {
  Message message = new Message()
    .setText("To add a contact, use the `ADD CONTACT` button below.")
    .setAccessoryWidgets(List.of(new AccessoryWidget()
      .setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(new GoogleAppsCardV1Button()
        .setText("ADD CONTACT")
        .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
          .setFunction(FUNCTION_URL)
          .setInteraction("OPEN_DIALOG")
          .setParameters(List.of(
            new GoogleAppsCardV1ActionParameter().setKey("actionName").setValue("openInitialDialog"))))))))));
  return new GenericJson() {{
    put("hostAppDataAction", new GenericJson() {{
      put("chatDataAction", new GenericJson() {{
        put("createMessageAction", new GenericJson() {{
          put("message", message);
        }});
      }});
    }});
  }};
}

/**
 * Responds to a button clicked in Google Chat.
 *
 * @param event The event object from the Google Workspace add-on.
 * @return response depending on the button clicked.
 */
GenericJson handleButtonClicked(JsonNode event) {
  String actionName = event.at("/commonEventObject/parameters/actionName").asText();
  // Initial dialog form page
  if ("openInitialDialog".equals(actionName)) {
    return openInitialDialog();
  // Confirmation dialog form page
  } else if ("openConfirmationDialog".equals(actionName)) {
    return openConfirmationDialog(event);
  // Submission dialog form page
  } else if ("submitDialog".equals(actionName)) {
    return submitDialog(event);
  }
  return null; 
}

/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @return {Object} open the dialog.
 */
GenericJson openInitialDialog() {
  GoogleAppsCardV1Card cardV2 = new GoogleAppsCardV1Card()
    .setSections(List.of(new GoogleAppsCardV1Section().setWidgets(List.of(
      new GoogleAppsCardV1Widget().setTextInput(new GoogleAppsCardV1TextInput()
        .setName("contactName")
        .setLabel("First and last name")
        .setType("SINGLE_LINE")),
      new GoogleAppsCardV1Widget().setDateTimePicker(new GoogleAppsCardV1DateTimePicker()
        .setName("contactBirthdate")
        .setLabel("Birthdate")
        .setType("DATE_ONLY")),
      new GoogleAppsCardV1Widget().setSelectionInput(new GoogleAppsCardV1SelectionInput()
        .setName("contactType")
        .setLabel("Contact type")
        .setType("RADIO_BUTTON")
        .setItems(List.of(
          new GoogleAppsCardV1SelectionItem()
            .setText("Work")
            .setValue("Work")
            .setSelected(false),
          new GoogleAppsCardV1SelectionItem()
            .setText("Personal")
            .setValue("Personal")
            .setSelected(false)))),
      new GoogleAppsCardV1Widget().setButtonList(new GoogleAppsCardV1ButtonList().setButtons(List.of(
        new GoogleAppsCardV1Button()
          .setText("NEXT")
          .setOnClick(new GoogleAppsCardV1OnClick().setAction(new GoogleAppsCardV1Action()
            .setFunction(FUNCTION_URL)
            .setParameters(List.of(
              new GoogleAppsCardV1ActionParameter().setKey("actionName").setValue("openConfirmationDialog"))))))))))));
  return new GenericJson() {{
    put("action", new GenericJson() {{
      put("navigations", List.of(new GenericJson() {{
        put("pushCard", cardV2);
      }}));
    }});
  }};
}

/**
 * Opens the second step of the dialog that lets users confirm details.
 *
 * @param event The event object from the Google Workspace add-on.
 * @return update the dialog.
 */
GenericJson openConfirmationDialog(JsonNode event) {
  // Retrieve the form input values
  String name = event.at("/commonEventObject/formInputs/contactName/stringInputs/value").get(0).asText();
  String birthdateEpoch = event.at("/commonEventObject/formInputs/contactBirthdate/dateInput/msSinceEpoch").asText();
  String birthdate = new SimpleDateFormat("MM/dd/yyyy").format(new Date((long)Double.parseDouble(birthdateEpoch)));
  String type = event.at("/commonEventObject/formInputs/contactType/stringInputs/value").get(0).asText();
  // Display the input values for confirmation
  GoogleAppsCardV1Card cardV2 = new GoogleAppsCardV1Card()
    .setSections(List.of(new GoogleAppsCardV1Section().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> " + 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(FUNCTION_URL)
            .setParameters(List.of(
              new GoogleAppsCardV1ActionParameter().setKey("actionName").setValue("submitDialog"),
              // Pass input values as parameters for last dialog step (submission)
              new GoogleAppsCardV1ActionParameter().setKey("contactName").setValue(name),
              new GoogleAppsCardV1ActionParameter().setKey("contactBirthdate").setValue(birthdate),
              new GoogleAppsCardV1ActionParameter().setKey("contactType").setValue(type))))))))))));
  return new GenericJson() {{
    put("action", new GenericJson() {{
      put("navigations", List.of(new GenericJson() {{
        put("pushCard", cardV2);
      }}));
    }});
  }};
}

استبدِل FUNCTION_URL بنقطة نهاية HTTP التي تعالج نقرات الأزرار.

برمجة التطبيقات

يرسل هذا المثال رسالة بطاقة من خلال عرض JSON الخاص بالبطاقة. يمكنك أيضًا استخدام خدمة البطاقات في Apps Script.

apps-script/chat/contact-form-app/Code.gs
/**
 * Responds to a message in Google Chat.
 *
 * @param {Object} event The event object from the Google Workspace add-on.
 * @return {Object} response that handles dialogs.
 */
function onMessage(event) {
  // Reply with a message that contains a button to open the initial dialog
  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    text: "To add a contact, use the `ADD CONTACT` button below.",
    accessoryWidgets: [
      { buttonList: { buttons: [{
        text: "ADD CONTACT",
        onClick: { action: {
          function: "openInitialDialog",
          interaction: "OPEN_DIALOG"
        }}
      }]}}
    ]
  }}}}};
}

/**
 * Opens the initial step of the dialog that lets users add contact details.
 *
 * @param {Object} event The event object from the Google Workspace add-on.
 * @return {Object} open the dialog.
 */
function openInitialDialog(event) {
  return { action: { navigations: [{ pushCard: { sections: [{ widgets: [
    { textInput: {
      name: "contactName",
      label: "First and last name",
      type: "SINGLE_LINE"
    }},
    { dateTimePicker: {
      name: "contactBirthdate",
      label: "Birthdate",
      type: "DATE_ONLY"
    }},
    { selectionInput: {
      name: "contactType",
      label: "Contact type",
      type: "RADIO_BUTTON",
      items: [
        { text: "Work", value: "Work", selected: false },
        { text: "Personal", value: "Personal", selected: false }
      ]
    }},
    { buttonList: { buttons: [{
      text: "NEXT",
      onClick: { action: { function : "openConfirmationDialog" }}
    }]}}
  ]}]}}]}};
}

/**
 * Opens the second step of the dialog that lets users confirm details.
 *
 * @param {Object} event The event object from the Google Workspace add-on.
 * @return {Object} update the dialog.
 */
function openConfirmationDialog(event) {
  // Retrieve the form input values
  const name = event.commonEventObject.formInputs["contactName"].stringInputs.value[0];
  const birthdate = event.commonEventObject.formInputs["contactBirthdate"].dateInput.msSinceEpoch;
  const type = event.commonEventObject.formInputs["contactType"].stringInputs.value[0];
  // Display the input values for confirmation
  return { action: { navigations: [{ pushCard: { sections: [{ widgets: [
    { textParagraph: { text: "Confirm contact information and submit:" }},
    { textParagraph: { text: "<b>Name:</b> " + name }},
    { textParagraph: { text: "<b>Birthday:</b> " + new Date(birthdate) }},
    { textParagraph: { text: "<b>Type:</b> " + type }},
    { buttonList: { buttons: [{
      text: "SUBMIT",
      onClick: { action: {
        function: "submitDialog",
        // Pass input values as parameters for last dialog step (submission)
        parameters: [
          { key: "contactName", value: name },
          { key: "contactBirthdate", value: birthdate },
          { key: "contactType", value: type }
        ]
      }}
    }]}}
  ]}]}}]}};
}

إغلاق مربّع الحوار

عندما ينقر المستخدمون على زر إرسال في مربّع حوار، ينفّذ تطبيق الدردشة الإجراء المرتبط به ويقدّم عنصر الحدث مع ضبط buttonClickedPayload على ما يلي:

  • isDialogEvent هي true.
  • dialogEventType هي SUBMIT_DIALOG.

يجب أن يعرض تطبيق Chat عنصر RenderActions مع ضبط EndNavigation على CLOSE_DIALOG.

اختياري: عرض إشعار مؤقت

عند إغلاق مربّع الحوار، يمكنك أيضًا عرض إشعار نصي مؤقت للمستخدم الذي يتفاعل مع التطبيق.

لعرض إشعار، يجب عرض الكائن RenderActions مع ضبط الحقل notification.

يغلق المثال التالي مربّع الحوار مع إشعار نصي:

Node.js

node/chat/contact-form-app/index.js
// Validate the parameters.
if (!event.commonEventObject.parameters["contactName"]) {
  return { action: {
    navigations: [{ endNavigation: { action: "CLOSE_DIALOG"}}],
    notification: { text: "Failure, the contact name was missing!" }
  }};
}

Python

python/chat/contact-form-app/main.py
# Validate the parameters.
if event.get('commonEventObject').get('parameters')["contactName"] == "":
  return { 'action': {
    'navigations': [{ 'endNavigation': { 'action': "CLOSE_DIALOG"}}],
    'notification': { 'text': "Failure, the contact name was missing!" }
  }}

Java

java/chat/contact-form-app/src/main/java/com/google/chat/contact/App.java
    // Validate the parameters.
    if (event.at("/commonEventObject/parameters/contactName").asText().isEmpty()) {
      return new GenericJson() {{
        put("action", new GenericJson() {{
          put("navigations", List.of(new GenericJson() {{
            put("endNavigation", new GenericJson() {{
              put("action", "CLOSE_DIALOG");
            }});
          }}));
          put("notification", new GenericJson() {{
            put("text", "Failure, the contact name was missing!");
          }});
        }});
      }};
    }

    return new GenericJson() {{
      put("hostAppDataAction", new GenericJson() {{
        put("chatDataAction", new GenericJson() {{
          put("createMessageAction", new GenericJson() {{
            put("message", new Message()
              .setText( "✅ " + event.at("/commonEventObject/parameters/contactName").asText() +
                        " has been added to your contacts."));
          }});
        }});
      }});
    }};
  }
}

برمجة التطبيقات

يرسل هذا المثال رسالة بطاقة من خلال عرض JSON الخاص بالبطاقة. يمكنك أيضًا استخدام خدمة البطاقات في Apps Script.

apps-script/chat/contact-form-app/Code.gs
// Validate the parameters.
if (!event.commonEventObject.parameters["contactName"]) {
  return { action: {
    navigations: [{ endNavigation: { action: "CLOSE_DIALOG"}}],
    notification: { text: "Failure, the contact name was missing!" }
  }};
}

للحصول على تفاصيل حول تمرير المَعلمات بين مربّعات الحوار، راجِع نقل البيانات إلى بطاقة أخرى.

اختياري: إرسال رسالة تأكيد عبر Chat

عند إغلاق مربّع الحوار، يمكنك أيضًا إرسال رسالة Chat جديدة أو تعديل رسالة حالية.

لإرسال رسالة جديدة، عليك عرض كائن DataActions يحتوي على الحقل CreateMessageAction الذي تم ضبطه باستخدام الرسالة الجديدة. على سبيل المثال، لإغلاق مربّع الحوار وإرسال رسالة نصية، يجب عرض ما يلي:

يغلق المثال التالي مربّع الحوار عن طريق إرسال رسالة جديدة:

Node.js

node/chat/contact-form-app/index.js
return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
  text: "✅ " + event.commonEventObject.parameters["contactName"] + " has been added to your contacts."
}}}}};

Python

python/chat/contact-form-app/main.py
return { 'hostAppDataAction': { 'chatDataAction': { 'createMessageAction': { 'message': {
  'text': "✅ " + event.get('commonEventObject').get('parameters')["contactName"] + " has been added to your contacts."
}}}}}

Java

java/chat/contact-form-app/src/main/java/com/google/chat/contact/App.java
return new GenericJson() {{
  put("hostAppDataAction", new GenericJson() {{
    put("chatDataAction", new GenericJson() {{
      put("createMessageAction", new GenericJson() {{
        put("message", new Message()
          .setText( "✅ " + event.at("/commonEventObject/parameters/contactName").asText() +
                    " has been added to your contacts."));
      }});
    }});
  }});
}};

برمجة التطبيقات

يرسل هذا المثال رسالة بطاقة من خلال عرض JSON الخاص بالبطاقة. يمكنك أيضًا استخدام خدمة البطاقات في Apps Script.

apps-script/chat/contact-form-app/Code.gs
return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
  text: "✅ " + event.commonEventObject.parameters["contactName"] + " has been added to your contacts."
}}}}};

لتعديل رسالة بعد أن يرسل المستخدم مربع حوار، عليك عرض عنصر DataActions يحتوي على أحد الإجراءات التالية:

تحديد المشاكل وحلّها

عندما يعرض تطبيق أو بطاقة في Google Chat خطأً، تعرض واجهة Chat رسالة تفيد بحدوث خطأ. أو "لم نتمكّن من معالجة طلبك". في بعض الأحيان، لا تعرض واجهة مستخدم Chat أي رسالة خطأ، ولكن ينتج تطبيق Chat أو البطاقة نتيجة غير متوقّعة، على سبيل المثال، قد لا تظهر رسالة البطاقة.

على الرغم من أنّه قد لا تظهر رسالة خطأ في واجهة مستخدم Chat، تتوفّر رسائل خطأ وصفية وبيانات سجلّات لمساعدتك في إصلاح الأخطاء عند تفعيل تسجيل الأخطاء لتطبيقات Chat. للحصول على مساعدة في عرض الأخطاء وتصحيحها وتحديد المشاكل فيها، يُرجى الاطّلاع على تحديد مشاكل Google Chat وحلّها.