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

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

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

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

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

Node.js

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

Python

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

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

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

فتح مربع حوار

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

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

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

تنفيذ طلب مربّع حوار

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

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

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

يعرض ملف JSON التالي كيفية تشغيل طلب مربّع حوار من زر في رسالة البطاقة. لفتح مربع الحوار، سيتم button.interaction على OPEN_DIALOG:

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

حيث BUTTON_TEXT هو النص الذي يظهر في الزر وFUNCTION_NAME هي الدالة التي تعمل لفتح الدالة .

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

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

لفتح مربّع حوار، يمكن لتطبيق Chat الردّ على عن طريق إرجاع actionResponse مع ضبط type على DIALOG Message الخاص بك. لتحديد محتوى مربّع الحوار، يمكنك تضمين ما يلي: الكائنات:

  • إنّ actionResponse مع ضبط type على DIALOG.
  • dialogAction الخاص بك. يحتوي الحقل body على عناصر واجهة المستخدم (UI) العرض في البطاقة، بما في ذلك معلومة واحدة أو أكثر sections من الأدوات. لجمع معلومات من المستخدمين، يمكنك تحديد أدوات إدخال النماذج الزر المصغّر. لمعرفة المزيد من المعلومات عن تصميم إدخالات النماذج، اطّلِع على جمع المعلومات من المستخدمين ومعالجتها:

يعرض ملف JSON التالي كيفية عرض تطبيق Chat. رد يفتح مربع حوار:

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

حيث BUTTON_TEXT هو النص الذي يظهر في الزر (مثل Next أو Submit)، تمثِّل WIDGETS سمة واحدة أو أكثر أدوات إدخال النماذج FUNCTION_NAME هي الدالة التي تعمل عندما ينقر المستخدمون على زر.

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

عندما ينقر المستخدمون على زر لإرسال مربع حوار، يحصل تطبيق Chat على تفاعل CARD_CLICKED الحدث الذي يظهر فيه dialogEventType SUBMIT_DIALOG.

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

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

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

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

في هذا المثال، يفتح تطبيق Chat مربّع حوار يعرض مربع حوار ثانٍ قبل الإرسال. لتحميل بيانات الإدخال، سيتم يجتاز تطبيق Chat حدث التفاعل "CARD_CLICKED" كمعلمة للدالة التي تفتح مربع الحوار التالي:

Node.js

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

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

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

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

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

Python

from typing import Any, Mapping

import flask
import functions_framework

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

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

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

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

  request = req.get_json(silent=True)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

تمثّل هذه السمة WIDGETS عنصرًا واحدًا أو أكثر. أدوات إدخال النماذج.

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

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

توضح الأقسام التالية كيفية التحقق من صحة البيانات التي يُدخلها المستخدمون لإغلاق مربع الحوار.

التحقّق من صحة البيانات التي أدخلها المستخدم وإغلاق مربّع الحوار

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

إذا حذف المستخدم حقلاً مطلوبًا أو أدخل قيمًا غير صحيحة، سيتم يمكن أن يردّ تطبيق Chat برسالة خطأ من خلال عرض ActionResponse التي تحتوي على "actionStatus": "ERROR MESSAGE".

يتحقق المثال التالي من إدخال المستخدم لقيمة لأداة تقبل السلاسل (stringInputs)، مثل تطبيق textInput المصغّر. في حالة عدم وجوده، فإن حدث خطأ في تطبيق Chat. في حال وجودها، إقرار تطبيق Chat بإرسال مربّعات الحوار يغلق مربع الحوار:

Node.js

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

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

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

Python

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

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

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

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

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

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

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

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

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

في هذا المثال، يمثل WIDGET_NAME الحقل name في (مثل contactName) وتمثل ERROR_MESSAGE محتوى رسالة الخطأ (مثل Don't forget to name your contact). للحصول على تفاصيل حول معالجة بيانات الإدخال من الأدوات، راجع تلقي البيانات من التطبيقات المصغّرة التفاعلية:

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

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

لإرسال رسالة جديدة، يمكنك إرجاع ActionResponse مع ضبط type على NEW_MESSAGE. على سبيل المثال، لإغلاق مربع الحوار وأرسل رسالة نصية، أرجع ما يلي:

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

لتعديل رسالة، يمكنك إرجاع عنصر actionResponse يحتوي على تم تحديث الرسالة وضبط type على أي مما يلي:

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

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

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