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

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

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

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

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

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

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

Node.js

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

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

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

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

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

لتقليل الطلبات إلى مصدر بيانات خارجي، يمكنك تضمين عناصر مقترَحة تظهر في قائمة الاختيار المتعدّد قبل أن يكتب المستخدمون في القائمة. على سبيل المثال، يمكنك تعبئة جهات الاتصال التي تم البحث عنها مؤخرًا للمستخدم. لتعبئة العناصر المقترَحة من مصدر بيانات خارجي، حدِّد عناصر static 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. تعالج عنصر حدث، والذي receivesتلقّاه تطبيق 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 interactive event.
* @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 عرض بطاقة أولية تطلب سبب الموعد، ثم preenchimentoبطاقة أخرى تقدّم الأوقات المتاحة استنادًا إلى نوع الموعد.

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

{
  "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 وحلّها.