您在脚本项目清单中定义的每个会议解决方案都有一个关联的 onCreateFunction
。每当用户尝试在活动中选择该会议解决方案时,该插件都会调用此函数来创建会议。
您必须实现插件清单中所述的每个 onCreateFunction
。一般来说,这些函数必须执行以下操作:
- 检索第三方会议系统可能需要用来创建会议的任何 Google 日历活动信息,例如活动 ID 或参加者名单。
- 连接到第三方会议服务,然后使用 Google 日历活动信息在该服务中创建新的会议。
- 如果会议创建请求因某种原因而失败,请使用错误信息构建并返回包含
ConferenceError
的ConferenceData
对象。否则,请完成以下步骤。- 初始化会议同步。
- 使用第三方会议服务返回的信息构建并返回新的
ConferenceData
对象。
检索事件信息
若要创建第三方会议,您需要提供与相应 Google 日历活动相关的特定信息。所需的确切活动信息因第三方会议系统而异,但通常包括活动开始时间、结束时间、摘要、参加者名单和 ID。
调用时,系统会向您定义的每个 onCreateFunction
传递一个包含日历 ID 和活动 ID 的参数。您可以使用这些 ID 通过 Google 日历高级服务检索完整的活动信息。
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
入口点。这些限制与 Calendar API 事件中针对相应 conferenceData
字段所述的限制相同,但其中并非所有 API 事件字段都适用于 Apps Script。
处理错误
在某些情况下,由于第三方会议系统返回错误,因此无法完成会议创建。在这些情况下,您的插件应通过构建并返回包含 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; }