جمع المعلومات من مستخدمي Google Chat ومعالجتها

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

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

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

  • اضبط الإعدادات. على سبيل المثال، للسماح للمستخدمين بتخصيص إعدادات الإشعارات أو ضبط تطبيق Chat وإضافته إلى مساحة واحدة أو أكثر.
  • إنشاء معلومات أو تعديلها في تطبيقات Google Workspace الأخرى على سبيل المثال، يمكنك السماح للمستخدمين بإنشاء حدث في "تقويم Google".
  • السماح للمستخدمين بالوصول إلى الموارد وتعديلها في تطبيقات أو خدمات ويب أخرى على سبيل المثال، يمكن أن يساعد تطبيق Chat المستخدمين في تعديل حالة طلب دعم مباشرةً من مساحة في Chat.

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

HTTP

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

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

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

إنشاء نماذج باستخدام البطاقات

لجمع المعلومات، تصمّم تطبيقات Chat النماذج ومدخلاتها، وتنشئها في بطاقات. لعرض البطاقات للمستخدمين، يمكن لتطبيقات Chat استخدام واجهات Chat التالية:

  • رسائل المحادثة التي تحتوي على بطاقة واحدة أو أكثر
  • مربّعات الحوار، وهي بطاقات يتم فتحها في نافذة جديدة من الرسائل وصفحات البداية

يمكن لتطبيقات الدردشة إنشاء البطاقات باستخدام التطبيقات المصغّرة التالية:

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

    • إدخالات نصية (textInput) لنص حر أو مقترح
    • مدخلات التحديد (selectionInput) هي عناصر واجهة مستخدم قابلة للتحديد، مثل مربّعات الاختيار وأزرار الاختيار والقوائم المنسدلة. يمكن أيضًا أن تملأ أدوات إدخال الاختيار العناصر وتقترحها من بيانات Google Workspace (مثل مساحة في Chat) أو مصدر بيانات ديناميكي. لمزيد من التفاصيل، يُرجى الاطّلاع على القسم التالي إضافة قائمة اختيار متعدّد.

    • أدوات اختيار التاريخ والوقت (dateTimePicker) لإدخالات التاريخ والوقت

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

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

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

إضافة قائمة اختيار متعدّد

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

يمكنك ملء عناصر قائمة اختيار متعدّد من مصادر البيانات التالية:

  • بيانات Google Workspace، والتي تشمل المستخدمين أو مساحات Chat التي يكون المستخدم عضوًا فيها لا تعرض القائمة سوى العناصر من مؤسسة Google Workspace نفسها.
  • مصادر البيانات الخارجية، مثل قاعدة بيانات ارتباطية على سبيل المثال، يمكنك استخدام قوائم اختيار متعدّد لمساعدة المستخدم في الاختيار من قائمة بعملاء محتملين من نظام إدارة علاقات العملاء (CRM).

ملء العناصر من مصدر بيانات Google Workspace

لاستخدام مصادر بيانات Google Workspace، حدِّد الحقل platformDataSource في أداة SelectionInput. على عكس أنواع إدخال التحديد الأخرى، يمكنك حذف عناصر SelectionItem، لأنّ عناصر التحديد هذه يتم الحصول عليها بشكل ديناميكي من Google Workspace.

يعرض الرمز التالي قائمة اختيار متعدد لمستخدمي Google Workspace. لملء المستخدمين، يضبط إدخال التحديد commonDataSource على USER:

JSON

{
  "selectionInput": {
    "name": "contacts",
    "type": "MULTI_SELECT",
    "label": "Selected contacts",
    "multiSelectMaxSelectedItems": 5,
    "multiSelectMinQueryLength": 1,
    "platformDataSource": {
      "commonDataSource": "USER"
    }
  }
}

يعرض الرمز التالي قائمة اختيار متعدّد لمساحات Chat. لتعبئة المسافات، يحدّد إدخال التحديد الحقل hostAppDataSource. تضبط قائمة الاختيار المتعدد أيضًا defaultToCurrentSpace على true، ما يجعل مساحة العمل الحالية هي الخيار التلقائي في القائمة:

JSON

{
  "selectionInput": {
    "name": "spaces",
    "type": "MULTI_SELECT",
    "label": "Selected contacts",
    "multiSelectMaxSelectedItems": 3,
    "multiSelectMinQueryLength": 1,
    "platformDataSource": {
      "hostAppDataSource": {
        "chatDataSource": {
          "spaceDataSource": {
            "defaultToCurrentSpace": true
          }
        }
      }
    }
  }
}

ملء العناصر من مصدر بيانات خارجي

يمكن لقوائم الاختيار المتعدد أيضًا ملء العناصر من مصدر بيانات خارجي أو تابع لجهة خارجية. لاستخدام مصدر بيانات خارجي، عليك تحديد حقل externalDataSource في أداة SelectionInput التي تحتوي على الدالة التي تستعلم عن العناصر وتعرضها من مصدر البيانات.

لتقليل الطلبات إلى مصدر بيانات خارجي، يمكنك تضمين العناصر المقترَحة التي تظهر في قائمة الاختيار المتعدد قبل أن يكتب المستخدمون في القائمة. على سبيل المثال، يمكنك ملء جهات الاتصال التي تم البحث عنها مؤخرًا للمستخدم. لملء العناصر المقترَحة من مصدر بيانات خارجي، حدِّد عناصر ثابتة SelectionItem.

تعرض التعليمة البرمجية التالية قائمة اختيار متعدّد تستعلم عن العناصر وتملأها من مصدر بيانات خارجي:

JSON

{
  "selectionInput": {
    "name": "contacts",
    "type": "MULTI_SELECT",
    "label": "Selected contacts",
    "multiSelectMaxSelectedItems": 3,
    "multiSelectMinQueryLength": 1,
    "externalDataSource": { "function": "FUNCTION" },
    // Suggested items loaded by default.
    // The list is static here but it could be dynamic.
    "items": [FUNCTION]
  }
}

استبدِل FUNCTION بعنوان URL الخاص بـ HTTP أو باسم دالة Apps Script التي تستعلم عن قاعدة البيانات الخارجية. للاطّلاع على مثال كامل يوضّح كيفية عرض العناصر المقترَحة، راجِع القسم اقتراح عناصر متعدّدة الاختيار.

تلقّي بيانات من التطبيقات المصغّرة التفاعلية

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

يمكنك استرداد القيم من العنصر commonEventObject.formInputs.WIDGET_NAME، حيث WIDGET_NAME هو حقل name الذي حدّدته للأداة. يتم عرض القيم كنوع بيانات محدّد للأداة.

يعرض ما يلي جزءًا من عنصر حدث أدخل فيه المستخدم قيمًا لكل أداة:

{
  "commonEventObject": { "formInputs": {
    "contactName": { "stringInputs": {
      "value": ["Kai 0"]
    }},
    "contactBirthdate": { "dateInput": {
      "msSinceEpoch": 1000425600000
    }},
    "contactType": { "stringInputs": {
      "value": ["Personal"]
    }}
  }}
}

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

تطبيق مصغَّر لإدخال النموذج نوع بيانات الإدخال قيمة الإدخال من عنصر الحدث مثال على القيمة
textInput stringInputs event.commonEventObject.formInputs.contactName.stringInputs.value[0] Kai O
selectionInput stringInputs للحصول على القيمة الأولى أو القيمة الوحيدة، event.commonEventObject.formInputs.contactType.stringInputs.value[0] Personal
dateTimePicker الذي يقبل التواريخ فقط dateInput event.commonEventObject.formInputs.contactBirthdate.dateInput.msSinceEpoch. 1000425600000

بعد أن يتلقّى تطبيق Chat البيانات، يمكنه إجراء أيّ ممّا يلي:

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

اقتراح عناصر متعددة الاختيار

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

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

  1. تعامَل مع عنصر حدث يتلقّاه تطبيق Chat عندما يكتب المستخدمون في القائمة.
  2. من عنصر الحدث، احصل على القيمة التي يكتبها المستخدم، والتي يتم تمثيلها في الحقل event.commonEventObject.parameters["autocomplete_widget_query"].
  3. استعلم عن مصدر البيانات باستخدام قيمة إدخال المستخدم للحصول على SelectionItems واحد أو أكثر لاقتراحه على المستخدم.
  4. يمكنك عرض العناصر المقترَحة من خلال عرض RenderActions الخاص بالإجراء مع الكائن modifyCard.

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

Node.js

/**
 * Google Cloud Function that responds to events sent from a
 * Google Chat space.
 *
 * @param {Object} req Request sent from Google Chat space
 * @param {Object} res Response to send back
 */
exports.selectionInput = function selectionInput(req, res) {
  if (req.method === 'GET' || !req.body.chat) {
    return res.send('Hello! This function is meant to be used ' +
        'in a Google Chat Space.');
  }
  // Stores the Google Chat event
  const chatEvent = req.body.chat;

  // Handle user interaction with multiselect.
  if(chatEvent.widgetUpdatedPayload) {
    return res.send(queryContacts(req.body));
  }
  // Replies with a card that contains the multiselect menu.
  return res.send({ hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    cardsV2: [{
      cardId: "contactSelector",
      card: { sections:[{ widgets: [{
        selectionInput: {
          name: "contacts",
          type: "MULTI_SELECT",
          label: "Selected contacts",
          multiSelectMaxSelectedItems: 3,
          multiSelectMinQueryLength: 1,
          externalDataSource: { function: "FUNCTION_URL" },
          // Suggested items loaded by default.
          // The list is static here but it could be dynamic.
          items: [getSuggestedContact("3")]
        }
      }]}]}
    }]
  }}}}});
};

/**
* Get contact suggestions based on text typed by users.
*
* @param {Object} event the event object that contains the user's query
* @return {Object} suggestions
*/
function queryContacts(event) {
  const query = event.commonEventObject.parameters["autocomplete_widget_query"];
  return { action: { modifyOperations: [{ updateWidget: { selectionInputWidgetSuggestions: { suggestions: [
    // The list is static here but it could be dynamic.
    getSuggestedContact("1"), getSuggestedContact("2"), getSuggestedContact("3"), getSuggestedContact("4"), getSuggestedContact("5")
  // Only return items based on the query from the user.
  ].filter(e => !query || e.text.includes(query)) }}}]}};
}

/**
 * Generate a suggested contact given an ID.
 *
 * @param {String} id The ID of the contact to return.
 * @return {Object} The contact formatted as a selection item in the menu.
 */
function getSuggestedContact(id) {
  return {
    value: id,
    startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    text: "Contact " + id
  };
}

استبدِل FUNCTION_URL بنقطة نهاية HTTP التي تجري طلب بحث في مصدر البيانات الخارجي.

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

/**
* Responds to a Message trigger in Google Chat.
*
* @param {Object} event the event object from Google Chat
* @return {Object} Response from the Chat app.
*/
function onMessage(event) {
  // Replies with a card that contains the multiselect menu.
  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    cardsV2: [{
      cardId: "contactSelector",
      card: { sections:[{ widgets: [{
        selectionInput: {
          name: "contacts",
          type: "MULTI_SELECT",
          label: "Selected contacts",
          multiSelectMaxSelectedItems: 3,
          multiSelectMinQueryLength: 1,
          externalDataSource: { function: "queryContacts" },
          // Suggested items loaded by default.
          // The list is static here but it could be dynamic.
          items: [getSuggestedContact("3")]
        }
      }]}]}
    }]
  }}}}};
}

/**
* Get contact suggestions based on text typed by users.
*
* @param {Object} event the event object that contains the user's query
* @return {Object} suggestions
*/
function queryContacts(event) {
  const query = event.commonEventObject.parameters["autocomplete_widget_query"];
  return { action: { modifyOperations: [{ updateWidget: { selectionInputWidgetSuggestions: { suggestions: [
    // The list is static here but it could be dynamic.
    getSuggestedContact("1"), getSuggestedContact("2"), getSuggestedContact("3"), getSuggestedContact("4"), getSuggestedContact("5")
  // Only return items based on the query from the user.
  ].filter(e => !query || e.text.includes(query)) }}}]}};
}

/**
* Generate a suggested contact given an ID.
*
* @param {String} id The ID of the contact to return.
* @return {Object} The contact formatted as a selection item in the menu.
*/
function getSuggestedContact(id) {
  return {
    value: id,
    startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    text: "Contact " + id
  };
}

نقل البيانات إلى بطاقة أخرى

بعد أن يرسل المستخدم معلومات من بطاقة، قد تحتاج إلى عرض بطاقات إضافية لتنفيذ أي مما يلي:

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

لنقل إدخال البيانات من البطاقة الأولية، يمكنك إنشاء أداة button باستخدام actionParameters التي تحتوي على name للأداة والقيمة التي يدخلها المستخدم، كما هو موضّح في المثال التالي:

Node.js

{
  "buttonList": { "buttons": [{
    "text": "Submit",
    "onClick": { "action": {
      "function": "FUNCTION_URL", // Must be an `https` endpoint.
      "parameters": [
        {
          "key": "WIDGET_NAME",
          "value": "USER_INPUT_VALUE"
        },
        // Can specify multiple parameters
      ]
    }}
  }]}
}

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

{
  "buttonList": { "buttons": [{
    "text": "Submit",
    "onClick": { "action": {
      "function": "submitForm",
      "parameters": [
        {
          "key": "WIDGET_NAME",
          "value": "USER_INPUT_VALUE"
        },
        // Can specify multiple parameters
      ]
    }}
  }]}
}

حيث WIDGET_NAME هو name للأداة وUSER_INPUT_VALUE هو ما يدخله المستخدم. على سبيل المثال، بالنسبة إلى حقل إدخال نصي يجمع اسم شخص، يكون اسم الأداة contactName وتكون قيمة المثال Kai O.

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

الردّ على نموذج تم إرساله

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

في المثال التالي، يرسل تطبيق Chat رسالة نصية لتأكيد استلامه بنجاح نموذجًا تم إرساله من رسالة بطاقة.

Node.js

/**
 * Google Cloud Function that handles all Google Workspace Add On events for
 * the contact manager app.
 *
 * @param {Object} req Request sent from Google Chat space
 * @param {Object} res Response to send back
 */
exports.contactManager = function contactManager(req, res) {
  const chatEvent = req.body.chat;
  const chatMessage = chatEvent.messagePayload.message;

  // Handle message payloads in the event object
  if(chatEvent.messagePayload) {
    return res.send(handleMessage(chatMessage, chatEvent.user));
  // Handle button clicks on the card
  } else if(chatEvent.buttonClickedPayload) {
    switch(req.body.commonEventObject.parameters.actionName) {
        case "openDialog":
            return res.send(openDialog());
        case "openNextCard":
            return res.send(openNextCard(req.body));
        case "submitForm":
            return res.send(submitForm(req.body));
    }
  }
};

/**
 * Submits information from a dialog or card message.
 *
 * @param {Object} event the interactive event with form inputs.
 * @return {Object} a message response that posts a private message.
 */
function submitForm(event) {
  const chatUser = event.chat.user;
  const contactName = event.commonEventObject.parameters["contactName"];

  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    privateMessageViewer: chatUser,
    text: "✅ " + contactName + " has been added to your contacts."
  }}}}};
}

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

/**
 * Sends private text message that confirms submission.
 *
 * @param {Object} event the interactive event with form inputs.
 * @return {Object} a message response that posts a private message.
 */
function submitForm(event) {
  const chatUser = event.chat.user;
  const contactName = event.commonEventObject.parameters["contactName"];

  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    privateMessageViewer: chatUser,
    text: "✅ " + contactName + " has been added to your contacts."
  }}}}};
}

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

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

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

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