正在建立第三方會議

您在指令碼專案資訊清單中定義的每個會議解決方案都有相關的 onCreateFunction。外掛程式會呼叫這個函式,在每次使用者嘗試選取會議解決方案時建立會議。

您必須實作外掛程式資訊清單中所述的每個 onCreateFunction。一般來說,這些函式必須執行以下操作:

  1. 擷取任何 Google 日曆活動資訊 (例如活動 ID 或與會者名單),第三方視訊會議系統可能需要這些資訊才能建立會議。
  2. 連線至第三方視訊會議服務,並使用 Google 日曆活動資訊建立新的會議。
  3. 如果會議建立要求因某些原因失敗,請使用錯誤資訊建構並傳回包含 ConferenceErrorConferenceData 物件。如果沒有,請完成後續步驟。
    1. 初始化會議同步
    2. 使用第三方會議服務傳回的資訊,建構並傳回新的 ConferenceData 物件。

擷取活動資訊

如要建立第三方會議,您必須提供對應 Google 日曆活動的特定資訊。不同第三方會議系統所需的確切活動資訊不盡相同,但通常包括活動開始時間、結束時間、摘要、與會者名單和 ID。

呼叫時,您定義的每個 onCreateFunction 都會傳遞一個引數,其中包含日曆和事件 ID。您可以使用這些 ID 透過 Google 日曆進階服務擷取完整的活動資訊。

Google 日曆可以在活動存在前,就新增會議詳細資料。在這類情況下,Google 日曆會傳遞有效的 eventIdonCreateFunction,但後續呼叫 Calendar.Events.get() 可能會導致錯誤回應,指出活動不存在。在這些情況下,最適合使用預留位置資料建立第三方會議;這項資料會在下次同步處理時替換。

建立第三方會議

onCreateFunction 擷取必要的事件資料後,必須連線至第三方會議系統才能建立會議。通常,這項操作會透過第三方會議系統支援的 API 要求來完成。請查看第三方視訊會議解決方案的說明文件,判斷您可以使用哪些 API 要求建立會議。

在 Apps Script 中,處理外部 API 要求最簡單的方法,就是使用 Apps Script 適用的 OAuth2Apps Script 適用的 OAuth1 開放原始碼程式庫。您也可以使用 UrlFetch 服務連線至外部 API,但這需要您明確處理授權詳細資料。

要求建立會議後,您可能需要提出其他要求,才能擷取新的會議詳細資料。

初始化會議同步

外掛程式在第三方系統上成功建立會議後,您必須執行幾個步驟才能啟用同步處理功能,讓 Google 日曆活動的變更反映在會議中。

如要進一步瞭解如何在建立會議後設定同步處理作業,請參閱「同步處理日曆變更」。

建立會議資料回應

onCreateFunction 必須使用第三方服務傳回的會議資訊,然後建構並傳回 ConferenceData 物件;會議資料部分會說明這個物件的內容。Google 日曆會使用這項資訊,在會議開始時將使用者導向會議。

建構 ConferenceData 物件時,請注意欄位長度、進入點 URI 格式和允許的進入點組合都有一些限制。舉例來說,單一 ConferenceData 中最多只能有一個 VIDEO 進入點。這些限制與對應 conferenceData 欄位中的 行事曆 API 事件所描述的限制相同,儘管 Apps Script 中並未提供所有 API 事件欄位。

處理錯誤

在某些情況下,第三方會議系統傳回錯誤,因此無法完成會議建立作業。在這些情況下,您的外掛程式應透過建構並傳回包含 ConferenceError 詳細資料的 ConferenceData 物件,穩健地處理錯誤情況,以便 Google 日曆採取相應行動。

建構 ConferenceData 物件以回報錯誤時,除了 ConferenceError 物件外,您不需要加入任何 ConferenceData 元件。ConferenceErrors 可以包含 ConferenceErrorType、錯誤訊息,以及在驗證問題發生時,讓使用者登入第三方會議系統的網址。

範例

以下為 onCreateFunction 的範例 (請注意,函式名稱可以是任何內容,您只需在外掛程式專案資訊清單中定義函式)。

create3rdPartyConference() 函式會聯絡第三方系統來建立會議,getAuthenticationUrl() 函式則會建立第三方系統驗證網址。由於這些程式庫高度依賴第三方系統詳細資料,因此此處並未完全實作。

此處未顯示 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;
}