脚本项目清单中定义的每个会议解决方案都有一个关联的 onCreateFunction。每当用户尝试为活动选择相应会议解决方案时,Google Workspace 加购项都会调用此函数来创建会议。
实现插件清单中描述的每个 onCreateFunction。这些函数必须执行以下操作:
- 检索第三方会议系统创建会议所需的任何 Google 日历活动信息,例如活动 ID 或参与者名单。
- 连接到第三方会议服务,并使用日历活动信息在该服务中创建新会议。
- 如果会议创建请求失败,请使用错误信息构建并返回包含
ConferenceError的ConferenceData对象。否则,请完成后续步骤。 - 初始化会议同步。
- 使用第三方会议服务返回的信息来构建并返回新的
ConferenceData对象。
检索活动信息
如需创建第三方会议,需要提供相应日历活动的相关信息。不同第三方会议系统所需的具体活动信息各不相同,但通常包括活动开始时间、结束时间、摘要、参加者名单和 ID。
调用时,您定义的每个 onCreateFunction 都会传递一个包含日历和活动 ID 的实参。您可以使用这些 ID 通过 Calendar 高级服务检索完整的活动信息。
Google 日历可能会在活动存在之前就向其添加会议详细信息。在这种情况下,日历会向 onCreateFunction 传递有效的 eventId,但对 Calendar.Events.get 的后续调用可能会导致错误,指出相应活动不存在。在这种情况下,请使用占位数据创建第三方会议;下次活动同步时,系统会替换这些数据。
创建第三方会议
onCreateFunction检索到必要的事件数据后,必须连接到第三方会议系统才能创建会议。通常,这是通过发出第三方会议系统支持的 API 请求来实现的。查看第三方会议解决方案的文档,确定可以使用哪些 API 请求来创建会议。
在 Google Apps 脚本中,处理外部 API 请求的最简单方法是使用 OAuth2 for Apps Script 或 OAuth1 for Apps Script 开源库。您还可以使用 UrlFetch 服务连接到外部 API,但这需要您明确处理授权详细信息。
请求创建会议后,您可能需要发出其他请求来检索新会议的详细信息。
初始化会议同步
插件成功在第三方系统中创建会议后,只需执行几个步骤即可启用同步,以便日历活动的更改反映在会议中。
如需详细了解如何在创建会议后设置同步,请参阅同步日历变更。
构建会议数据响应
使用第三方服务返回的会议信息,onCreateFunction 必须构建并返回 ConferenceData 对象;会议数据部分介绍了此对象的内容。Google 日历会使用此信息在会议开始后引导用户加入会议。
构建 ConferenceData 对象时,请注意字段长度、入口点 URI 的格式以及允许的入口点组合。例如,单个 ConferenceData 中最多只能有一个 VIDEO 入口点。这些限制与 Calendar API Event 中针对相应 conferenceData 字段描述的限制相同,不过并非所有 API 事件字段(如该文档中所述)都可在 Apps 脚本中使用。
处理错误
会议创建过程中可能会出现错误。在某些情况下,由于第三方会议系统返回错误,会议创建无法完成。在这些情况下,您的插件应通过构建并返回包含 ConferenceError 详细信息的 ConferenceData 对象来处理错误情况,以便日历采取相应措施。
构建 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;
}