创建第三方会议

< - < - - - - - - - - - - - -

您在脚本项目清单中定义的每个会议解决方案都有一个关联的 onCreateFunction。每当用户尝试选择该会议解决方案作为活动时,该插件都会调用此函数,以创建一个会议。

您必须实现插件清单中所述的每个 onCreateFunction。通常,这些函数必须执行以下操作:

  1. 检索第三方会议系统创建会议可能需要的任何 Google 日历活动信息,例如活动 ID 或参加者列表。
  2. 连接到第三方会议服务,并使用 Google 日历活动信息在其中创建新会议。
  3. 如果会议创建请求因某种原因失败,请使用错误信息构建并返回一个包含 ConferenceErrorConferenceData 对象。否则,请完成后续步骤。
    1. 初始化会议同步功能。
    2. 使用第三方会议服务返回的信息构建并返回新的 ConferenceData 对象。

检索活动信息

如需创建第三方会议,需要有关相应 Google 日历活动的某些信息。所需的确切活动信息因不同的第三方会议系统而异,但通常包括活动开始时间、结束时间、摘要、参加者列表和 ID。

调用时,系统会为您定义的每个 onCreateFunction 传递一个包含日历和活动 ID 的参数。借助 Google 日历高级服务,您可以使用这些 ID 检索完整的活动信息。

Google 日历可以在活动存在之前向其添加会议详细信息。在这种情况下,Google 日历会向 onCreateFunction 传递有效的 eventId,但对 Calendar.Events.get() 的后续调用可能会导致错误响应,表明事件不存在。在这些情况下,最好使用占位数据创建第三方会议;当事件下次同步时,这些数据会被替换。

创建第三方会议

onCreateFunction 检索到必要的活动数据后,必须连接到第三方会议系统才能创建会议。通常情况下,这通过发出第三方会议系统支持的 API 请求来实现。请查看第三方会议解决方案的文档,以确定您可以使用哪些 API 请求来创建会议。

在 Apps 脚本中,处理发出外部 API 请求的最简单方法是使用适用于 Apps 脚本的 OAuth2适用于 Apps 脚本的 OAuth1 开源库。您还可以使用 UrlFetch 服务连接到外部 API,但这需要您明确处理授权详情。

请求创建会议后,您可能需要发出其他请求以检索新的会议详细信息。

初始化会议同步功能

插件在第三方系统上成功创建会议后,应该执行几个步骤来启用同步,以便在会议中反映对 Google 日历活动的更改。

如需详细了解如何在创建会议后设置同步,请参阅同步日历更改

构建会议数据响应

然后,onCreateFunction 必须使用第三方服务返回的会议信息构建并返回一个 ConferenceData 对象;会议数据部分介绍了此对象的内容。Google 日历会使用这些信息,在会议开始后将用户定向到会议。

构建 ConferenceData 对象时,请注意,字段长度、入口点 URI 格式和允许的入口点组合存在一些限制。例如,一个 ConferenceData 中最多只能有一个 VIDEO 入口点。这些限制与 Google 日历 API 事件中相应 conferenceData 字段所述的限制完全相同,但并非所有描述的 API 事件字段在 Apps 脚本中都可用。

处理错误

在某些情况下,由于第三方会议系统返回的错误,会议创建无法完成。在这些情况下,您的插件应构建并返回包含 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;
}