إنشاء مكالمات فيديو تابعة لجهات خارجية

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

يجب تنفيذ كل onCreateFunction موصوف في بيان الإضافة. بشكل عام، يجب أن تؤدي هذه الدوال ما يلي:

  1. استرداد أي معلومات عن أحداث "تقويم Google"، مثل معرّف الحدث أو قائمة الضيوف، التي قد يحتاجها نظام المؤتمرات التابع لجهة خارجية من أجل إنشاء المؤتمر
  2. اربط حسابك بخدمة المؤتمرات التابعة لجهة خارجية وأنشئ مؤتمرًا جديدًا باستخدام معلومات حدث "تقويم Google".
  3. إذا تعذّر إنشاء المكالمة الجماعية لسبب ما، استخدِم معلومات الخطأ لإنشاء وعرض كائن ConferenceData يحتوي على ConferenceError. بخلاف ذلك، أكمِل الخطوات التالية.
    1. ابدأ مزامنة المؤتمر.
    2. استخدِم المعلومات التي تعرضها خدمة المؤتمرات التابعة لجهة خارجية لإنشاء وعرض عنصر ConferenceData جديد.

استرداد معلومات الحدث

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

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

من المحتمل أن يضيف "تقويم Google" تفاصيل مكالمة فيديو إلى حدث قبل إنشائه. في مثل هذه الحالات، يمرِّر "تقويم Google" onCreateFunction صالحًا eventId، ولكن قد تؤدي الطلبات اللاحقة إلى Calendar.Events.get() إلى ظهور ردّ يتضمّن خطأ يشير إلى أنّ الحدث غير متوفّر. في هذه الحالات، من الأفضل إنشاء مكالمة الفيديو الخارجية باستخدام بيانات عنصر نائب، وسيتم استبدال هذه البيانات في المرة التالية التي تتم فيها مزامنة الحدث.

إنشاء مكالمة جماعية مع جهة خارجية

بعد أن يسترد onCreateFunction بيانات الحدث اللازمة، يجب أن يتصل بنظام المؤتمرات التابع لجهة خارجية لإنشاء المؤتمر. ويتم ذلك عادةً من خلال تقديم طلبات إلى واجهة برمجة التطبيقات التي يتيحها نظام المؤتمرات التابع لجهة خارجية. راجِع وثائق حلول المؤتمرات التابعة لجهات خارجية لتحديد طلبات واجهة برمجة التطبيقات التي يمكنك استخدامها لإنشاء مؤتمرات.

في "برمجة التطبيقات"، أسهل طريقة للتعامل مع طلبات واجهة برمجة التطبيقات الخارجية هي استخدام مكتبات OAuth2 لبرمجة التطبيقات أو OAuth1 لبرمجة التطبيقات المفتوحة المصدر. يمكنك أيضًا الاتصال بواجهات برمجة التطبيقات الخارجية باستخدام خدمة UrlFetch، ولكن يتطلّب ذلك التعامل مع تفاصيل التفويض بشكل صريح.

بعد طلب إنشاء مؤتمر، قد تحتاج إلى تقديم طلبات إضافية لاسترداد تفاصيل المؤتمر الجديد.

بدء مزامنة المؤتمرات

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

راجِع مقالة مزامنة التغييرات في "تقويم Google" لمعرفة تفاصيل حول إعداد المزامنة بعد إنشاء مكالمة الفيديو.

إنشاء ردّ على بيانات المؤتمر

باستخدام معلومات الاجتماع التي تعرضها الخدمة الخارجية، يجب أن ينشئ onCreateFunction عنصر ConferenceData ثم يعرضه. يوضّح قسم بيانات الاجتماع محتوى هذا العنصر. يستخدم "تقويم Google" هذه المعلومات لتوجيه المستخدمين إلى المؤتمر عند بدئه.

عند إنشاء ConferenceData، يُرجى العِلم أنّ هناك بعض القيود على أطوال الحقول وتنسيقات معرّفات الموارد المنتظمة لنقاط الدخول والمجموعات المسموح بها من نقاط الدخول. على سبيل المثال، يمكن أن يكون هناك نقطة دخول VIDEO واحدة كحد أقصى في ConferenceData واحد. تتشابه هذه القيود مع القيود الموضّحة في حدث واجهة برمجة تطبيقات "تقويم Google" لحقل conferenceData ذي الصلة، مع العلم أنّه لا تتوفّر في Apps Script جميع حقول أحداث واجهة برمجة التطبيقات الموضّحة هناك.

معالجة الأخطاء

في بعض الحالات، لا يمكن إكمال إنشاء المؤتمر بسبب حدوث خطأ في نظام المؤتمرات التابع لجهة خارجية. في هذه الحالات، يجب أن تتعامل الإضافة مع حالة الخطأ بشكل فعّال من خلال إنشاء كائن ConferenceData يتضمّن تفاصيل ConferenceError وعرضه، ليتمكّن "تقويم Google" من اتّخاذ الإجراء المناسب.

عند إنشاء عنصر ConferenceData للإبلاغ عن خطأ، ليس عليك تضمين أي مكوّنات ConferenceData باستثناء العنصر ConferenceError. يمكن أن يتضمّن ConferenceErrors ConferenceErrorType ورسالة خطأ، وفي حال حدوث مشاكل في المصادقة، يتضمّن عنوان URL يتيح للمستخدمين تسجيل الدخول إلى نظام مكالمات الفيديو التابع لجهة خارجية.

مثال

يوضّح المثال التالي onCreateFunction (يُرجى العِلم أنّ اسم الدالة يمكن أن يكون أي شيء، ولكن عليك تحديدها في بيان مشروع الإضافة).

تتصل الدالة create3rdPartyConference() بالنظام التابع لجهة خارجية لإنشاء مؤتمر فيه، وتنشئ الدالة getAuthenticationUrl() عنوان URL للمصادقة على النظام التابع لجهة خارجية. لم يتم تنفيذ هذه الإجراءات بالكامل هنا، لأنّها تعتمد بشكل كبير على تفاصيل النظام التابع لجهة خارجية.

لا تظهر الدالة initializeSyncing() هنا، بل تعالج أي عمل أولي مطلوب للمزامنة. راجِع مقالة مزامنة تغييرات التقويم للحصول على التفاصيل.

/**
 *  Creates a conference, then builds and returns a ConferenceData object
 *  with the corresponding conference information. This method is called
 *  when a user selects a conference solution defined by the add-on that
 *  uses this function as its 'onCreateFunction' in the add-on manifest.
 *
 *  @param {Object} arg The default argument passed to a 'onCreateFunction';
 *      it carries information about the Google Calendar event.
 *  @return {ConferenceData}
 */
function createConference(arg) {
  const eventData = arg.eventData;
  const calendarId = eventData.calendarId;
  const eventId = eventData.eventId;

  // Retrieve the Calendar event information using the Calendar
  // Advanced service.
  var calendarEvent;
  try {
    calendarEvent = Calendar.Events.get(calendarId, eventId);
  } catch (err) {
    // The calendar event does not exist just yet; just proceed with the
    // given event ID and allow the event details to sync later.
    console.log(err);
    calendarEvent = {
      id: eventId,
    };
  }

  // Create a conference on the third-party service and return the
  // conference data or errors in a custom JSON object.
  var conferenceInfo = create3rdPartyConference(calendarEvent);

  // Build and return a ConferenceData object, either with conference or
  // error information.
  var dataBuilder = ConferenceDataService.newConferenceDataBuilder();

  if (!conferenceInfo.error) {
    // No error, so build the ConferenceData object from the
    // returned conference info.

    var phoneEntryPoint = ConferenceDataService.newEntryPoint()
        .setEntryPointType(ConferenceDataService.EntryPointType.PHONE)
        .setUri('tel:+' + conferenceInfo.phoneNumber)
        .setPin(conferenceInfo.phonePin);

    var adminEmailParameter = ConferenceDataService.newConferenceParameter()
        .setKey('adminEmail')
        .setValue(conferenceInfo.adminEmail);

    dataBuilder.setConferenceId(conferenceInfo.id)
        .addEntryPoint(phoneEntryPoint)
        .addConferenceParameter(adminEmailParameter)
        .setNotes(conferenceInfo.conferenceLegalNotice);

    if (conferenceInfo.videoUri) {
      var videoEntryPoint = ConferenceDataService.newEntryPoint()
          .setEntryPointType(ConferenceDataService.EntryPointType.VIDEO)
          .setUri(conferenceInfo.videoUri)
          .setPasscode(conferenceInfo.videoPasscode);
      dataBuilder.addEntryPoint(videoEntryPoint);
    }

    // Since the conference creation request succeeded, make sure that
    // syncing has been enabled.
    initializeSyncing(calendarId, eventId, conferenceInfo.id);

  } else if (conferenceInfo.error === 'AUTH') {
    // Authenentication error. Implement a function to build the correct
    // authenication URL for the third-party conferencing system.
    var authenticationUrl = getAuthenticationUrl();
    var error = ConferenceDataService.newConferenceError()
        .setConferenceErrorType(
            ConferenceDataService.ConferenceErrorType.AUTHENTICATION)
        .setAuthenticationUrl(authenticationUrl);
    dataBuilder.setError(error);

  } else {
    // Other error type;
    var error = ConferenceDataService.newConferenceError()
        .setConferenceErrorType(
            ConferenceDataService.ConferenceErrorType.TEMPORARY);
    dataBuilder.setError(error);
  }

  // Don't forget to build the ConferenceData object.
  return dataBuilder.build();
}


/**
 *  Contact the third-party conferencing system to create a conference there,
 *  using the provided calendar event information. Collects and retuns the
 *  conference data returned by the third-party system in a custom JSON object
 *  with the following fields:
 *
 *    data.adminEmail - the conference administrator's email
 *    data.conferenceLegalNotice - the conference legal notice text
 *    data.error - Only present if there was an error during
 *         conference creation. Equal to 'AUTH' if the add-on user needs to
 *         authorize on the third-party system.
 *    data.id - the conference ID
 *    data.phoneNumber - the conference phone entry point phone number
 *    data.phonePin - the conference phone entry point PIN
 *    data.videoPasscode - the conference video entry point passcode
 *    data.videoUri - the conference video entry point URI
 *
 *  The above fields are specific to this example; which conference information
 *  your add-on needs is dependent on the third-party conferencing system
 *  requirements.
 *
 * @param {Object} calendarEvent A Calendar Event resource object returned by
 *     the Google Calendar API.
 * @return {Object}
 */
function create3rdPartyConference(calendarEvent) {
  var data = {};

  // Implementation details dependent on the third-party system API.
  // Typically one or more API calls are made to create the conference and
  // acquire its relevant data, which is then put in to the returned JSON
  // object.

  return data;
}

/**
 *  Return the URL used to authenticate the user with the third-party
 *  conferencing system.
 *
 *  @return {String}
 */
function getAuthenticationUrl() {
  var url;
  // Implementation details dependent on the third-party system.

  return url;
}