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

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

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

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

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

Node.js

تطبيق Google Chat مفعَّل فيه الميزات التفاعلية لإنشاء تطبيق Chat تفاعلي باستخدام خدمة HTTP، أكمِل عملية البدء السريع هذه.

Python

تطبيق Google Chat مفعَّل فيه الميزات التفاعلية لإنشاء تطبيق Chat تفاعلي باستخدام خدمة HTTP، أكمِل عملية البدء السريع هذه.

Java

تطبيق Google Chat مفعَّل فيه الميزات التفاعلية لإنشاء تطبيق Chat تفاعلي باستخدام خدمة HTTP، أكمِل الخطوات الأساسية هذه.

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

تطبيق Google Chat مفعَّل فيه الميزات التفاعلية لإنشاء تطبيق Chat تفاعلي في Apps Script، أكمِل الخطوات الأساسية هذه.

فتح مربع حوار

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

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

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

بدء طلب حوار

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

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

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

يوضّح نموذج الرمز البرمجي التالي كيفية بدء طلب مربّع حوار من زر في رسالة بطاقة. لفتح مربّع الحوار، يتم ضبط الحقل 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"))))))));

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

يُرسِل هذا المثال رسالة بطاقة من خلال عرض ملف 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 على عناصر واجهة المستخدم التي يتم عرضها في البطاقة، بما في ذلك sections تطبيقات مصغّرة واحدة أو أكثر. لجمع المعلومات من المستخدمين، يمكنك تحديد التطبيقات المصغّرة لإدخال النماذج وتطبيق مصغّر لزر. لمزيد من المعلومات عن تصميم عناصر الإدخال في النماذج، يُرجى الاطّلاع على مقالة جمع المعلومات من المستخدمين ومعالجتها.

يوضّح نموذج الرمز البرمجي التالي كيفية عرض تطبيق 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()))))))));
}

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

يُرسِل هذا المثال رسالة بطاقة من خلال عرض ملف JSON للبطاقة. يمكنك أيضًا استخدام خدمة بطاقة "برمجة تطبيقات Google".

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

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

عندما ينقر المستخدمون على زر يُرسِل مربّع حوار، يتلقّى تطبيق Chat حدث تفاعل CARD_CLICKED يكون فيه dialogEventType SUBMIT_DIALOG.

ينبغي أن يتعامل تطبيق Chat مع حدث التفاعل من خلال القيام بأي مما يلي:

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

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

لمعالجة البيانات التي يُدخلها المستخدمون، يستخدم تطبيق Chat العنصر event.common.formInputs . للاطّلاع على مزيد من المعلومات عن استرداد القيم من التطبيقات المصغّرة لإدخال البيانات، يُرجى الاطّلاع على مقالة جمع المعلومات من المستخدمين ومعالجتها.

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

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

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

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

يرسل هذا المثال رسالة بطاقة من خلال عرض بطاقة 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 الإجراء المرتبط به ويقدّم لعنصر الحدث المعلومات التالية:

من المفترض أن يعرِض تطبيق 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);
  }
}

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

يُرسِل هذا المثال رسالة بطاقة من خلال عرض ملف 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);
}

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

يُرسِل هذا المثال رسالة بطاقة من خلال عرض ملف JSON للبطاقة. يمكنك أيضًا استخدام خدمة بطاقة "برمجة تطبيقات Google".

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 رسالة تفيد بأنّ "حدث خطأ". أو "تعذَّرت معالجة طلبك". في بعض الأحيان، لا يعرض واجهة مستخدم Chat أي رسالة خطأ، ولكن ينتج عن تطبيق Chat أو البطاقة نتيجة غير متوقّعة، على سبيل المثال، قد لا تظهر رسالة البطاقة .

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