使用者可以自由更新或刪除自己的 Google 日曆活動。如果使用者 而是在建立會議後更新活動。此外,外掛程式可能需要 更新會議資料來回應異動內容。如果您的 第三方會議系統需要定期追蹤事件資料 無法在活動變更時更新會議 會導致使用者體驗不佳,並導致使用者體驗不佳。
將會議資料與 Google 日曆活動變更保持同步的程序稱為「同步」。您可以建立 Apps Script 可安裝的觸發事件,在指定日曆中的活動發生變更時觸發,藉此同步處理活動變更。不過,觸發條件並未 回報哪些活動發生變更,且無法將報告限制為僅限含有 您建立的會議。您必須改為要求清單,列出自上次同步處理後,對日曆所做的所有變更,然後篩選事件清單,並據此更新。
一般同步程序如下:
- 使用者第一次建立會議時,系統會初始化同步處理程序。
- 每當使用者建立、更新或刪除他們的日曆活動 觸發條件會在外掛程式專案中執行觸發條件函式。
- 觸發事件函式會檢查自上次同步處理以來的事件變更集合,並判斷是否需要更新相關的第三方會議。
- 如需更新會議,請透過第三方 API 要求。
- 系統會儲存新的同步權杖,以便下次觸發事件執行時,只需檢查日曆的最新變更。
初始化同步處理作業
一旦外掛程式成功在第三方系統中建立會議 即會建立一個可安裝的觸發條件 會回應 活動變更 (如果觸發條件不存在)。
建立觸發事件後,系統應會建立初始同步權杖,完成初始化程序。方法是直接執行觸發事件函式。
建立日曆觸發條件
如要同步處理,您的外掛程式必須偵測附加會議的 Google 日曆活動是否有變更。這可透過建立 EventUpdated
可安裝的觸發條件來達成。你的加購內容
每個日曆只需要一個觸發條件,可以透過程式建立。
建立觸發條件的好時機,就是使用者第一次發起會議時。 因為使用者開始使用外掛程式更新後 建立會議 並確認沒有任何錯誤,您的外掛程式應該檢查 觸發條件存在,而非建立該名使用者。
實作同步處理觸發條件函式
當 Apps Script 偵測到造成這種情況的條件時,就會執行觸發條件函式
要觸發的觸發條件
EventUpdated
日曆觸發條件
會在使用者於指定事件建立、修改或刪除事件時觸發
日曆。
您必須實作外掛程式使用的觸發事件函式。這項觸發條件函式 應執行以下操作:
- 使用
syncToken
發出日曆進階服務Calendar.Events.list()
呼叫,擷取自上次同步處理後變更的事件清單。使用同步權杖可減少外掛程式的事件數量 皆須檢查。在沒有有效的同步權杖的情況下執行觸發函式時,觸發條件就會傳回 切換成完整同步處理。完整同步作業只會在規定的時間範圍內嘗試擷取所有事件,以產生新的有效同步權杖。
- 系統會檢查每個修改過的事件,以判斷是否具有相關 以及第三方會議通訊
- 如果活動有會議,我們會檢查變更內容。 視變更內容而定,修改關聯會議時可能會 不一定。舉例來說,如果活動已刪除,外掛程式應 這個會議可能也會刪除
- 如需變更會議,請向第三方系統發出 API 呼叫。
- 完成所有必要變更後,請儲存
Calendar.Events.list()
方法傳回的nextSyncToken
。這個同步處理權杖出現在上次 頁。Calendar.Events.list()
呼叫傳回的結果頁面。
更新 Google 日曆活動
在某些情況下,你可能想在執行 Google 日曆活動時更新活動資訊。
同步處理作業。如果您選擇這麼做,請使用適當的 Google 日曆進階服務要求更新活動。請務必使用
條件式更新
,且標頭為 If-Match
標頭。這可避免您的變更意外發生
使用者在其他用戶端中同時進行的變更覆寫。
範例
以下範例說明如何設定日曆活動和相關會議的同步處理作業。
/** * Initializes syncing of conference data by creating a sync trigger and * sync token if either does not exist yet. * * @param {String} calendarId The ID of the Google Calendar. */ function initializeSyncing(calendarId) { // Create a syncing trigger if it doesn't exist yet. createSyncTrigger(calendarId); // Perform an event sync to create the initial sync token. syncEvents({'calendarId': calendarId}); } /** * Creates a sync trigger if it does not exist yet. * * @param {String} calendarId The ID of the Google Calendar. */ function createSyncTrigger(calendarId) { // Check to see if the trigger already exists; if does, return. var allTriggers = ScriptApp.getProjectTriggers(); for (var i = 0; i < allTriggers.length; i++) { var trigger = allTriggers[i]; if (trigger.getTriggerSourceId() == calendarId) { return; } } // Trigger does not exist, so create it. The trigger calls the // 'syncEvents()' trigger function when it fires. var trigger = ScriptApp.newTrigger('syncEvents') .forUserCalendar(calendarId) .onEventUpdated() .create(); } /** * Sync events for the given calendar; this is the syncing trigger * function. If a sync token already exists, this retrieves all events * that have been modified since the last sync, then checks each to see * if an associated conference needs to be updated and makes any required * changes. If the sync token does not exist or is invalid, this * retrieves future events modified in the last 24 hours instead. In * either case, a new sync token is created and stored. * * @param {Object} e If called by a event updated trigger, this object * contains the Google Calendar ID, authorization mode, and * calling trigger ID. Only the calendar ID is actually used here, * however. */ function syncEvents(e) { var calendarId = e.calendarId; var properties = PropertiesService.getUserProperties(); var syncToken = properties.getProperty('syncToken'); var options; if (syncToken) { // There's an existing sync token, so configure the following event // retrieval request to only get events that have been modified // since the last sync. options = { syncToken: syncToken }; } else { // No sync token, so configure to do a 'full' sync instead. In this // example only recently updated events are retrieved in a full sync. // A larger time window can be examined during a full sync, but this // slows down the script execution. Consider the trade-offs while // designing your add-on. var now = new Date(); var yesterday = new Date(); yesterday.setDate(now.getDate() - 1); options = { timeMin: now.toISOString(), // Events that start after now... updatedMin: yesterday.toISOString(), // ...and were modified recently maxResults: 50, // Max. number of results per page of responses orderBy: 'updated' } } // Examine the list of updated events since last sync (or all events // modified after yesterday if the sync token is missing or invalid), and // update any associated conferences as required. var events; var pageToken; do { try { options.pageToken = pageToken; events = Calendar.Events.list(calendarId, options); } catch (err) { // Check to see if the sync token was invalidated by the server; // if so, perform a full sync instead. if (err.message === "Sync token is no longer valid, a full sync is required.") { properties.deleteProperty('syncToken'); syncEvents(e); return; } else { throw new Error(err.message); } } // Read through the list of returned events looking for conferences // to update. if (events.items && events.items.length > 0) { for (var i = 0; i < events.items.length; i++) { var calEvent = events.items[i]; // Check to see if there is a record of this event has a // conference that needs updating. if (eventHasConference(calEvent)) { updateConference(calEvent, calEvent.conferenceData.conferenceId); } } } pageToken = events.nextPageToken; } while (pageToken); // Record the new sync token. if (events.nextSyncToken) { properties.setProperty('syncToken', events.nextSyncToken); } } /** * Returns true if the specified event has an associated conference * of the type managed by this add-on; retuns false otherwise. * * @param {Object} calEvent The Google Calendar event object, as defined by * the Calendar API. * @return {boolean} */ function eventHasConference(calEvent) { var name = calEvent.conferenceData.conferenceSolution.name || null; // This version checks if the conference data solution name matches the // one of the solution names used by the add-on. Alternatively you could // check the solution's entry point URIs or other solution-specific // information. if (name) { if (name === "My Web Conference" || name === "My Recorded Web Conference") { return true; } } return false; } /** * Update a conference based on new Google Calendar event information. * The exact implementation of this function is highly dependant on the * details of the third-party conferencing system, so only a rough outline * is shown here. * * @param {Object} calEvent The Google Calendar event object, as defined by * the Calendar API. * @param {String} conferenceId The ID used to identify the conference on * the third-party conferencing system. */ function updateConference(calEvent, conferenceId) { // Check edge case: the event was cancelled if (calEvent.status === 'cancelled' || eventHasConference(calEvent)) { // Use the third-party API to delete the conference too. } else { // Extract any necessary information from the event object, then // make the appropriate third-party API requests to update the // conference with that information. } }