ผู้ใช้สามารถอัปเดตหรือลบกิจกรรมใน Google ปฏิทินได้อย่างอิสระ หากผู้ใช้อัปเดตกิจกรรมหลังจากที่สร้างการประชุมแล้ว ส่วนเสริมอาจต้องตอบสนองต่อการเปลี่ยนแปลงดังกล่าวโดยอัปเดตข้อมูลการประชุม หากระบบการประชุมของบุคคลที่สามต้องการติดตามข้อมูลกิจกรรม การไม่อัปเดตการประชุมตามการเปลี่ยนแปลงกิจกรรมอาจทำให้การประชุมใช้งานไม่ได้และทำให้ผู้ใช้ได้รับประสบการณ์ที่ไม่ดี
กระบวนการอัปเดตข้อมูลการประชุมตามการเปลี่ยนแปลงของกิจกรรมใน Google ปฏิทินเรียกว่าการซิงค์ คุณสามารถซิงค์การเปลี่ยนแปลงกิจกรรมด้วยการสร้างทริกเกอร์ที่ติดตั้งได้ของ Apps Script ที่จะเริ่มทำงานเมื่อกิจกรรมมีการเปลี่ยนแปลงในปฏิทินที่ระบุ ขออภัยที่ทริกเกอร์ไม่ได้รายงาน ว่าเหตุการณ์ใดเปลี่ยนแปลง และคุณไม่สามารถจำกัดให้มีเฉพาะเหตุการณ์ที่มีการประชุม ที่สร้างขึ้นเท่านั้นได้ แต่คุณต้องขอรายการการเปลี่ยนแปลงทั้งหมดที่ทำกับปฏิทินนับตั้งแต่การซิงค์ครั้งล่าสุด กรองรายการกิจกรรม และอัปเดตตามนั้น
ขั้นตอนการซิงค์ทั่วไปมีดังนี้
- ครั้งแรกที่ผู้ใช้สร้างการประชุม ขั้นตอนการซิงค์จะเริ่มต้น
- เมื่อใดก็ตามที่ผู้ใช้สร้าง อัปเดต หรือลบกิจกรรมในปฏิทิน เงื่อนไขเริ่มต้นจะเรียกใช้ฟังก์ชันทริกเกอร์ในโปรเจ็กต์ส่วนเสริม
- ฟังก์ชันทริกเกอร์จะตรวจสอบชุดการเปลี่ยนแปลงของเหตุการณ์ตั้งแต่การซิงค์ครั้งล่าสุด และกำหนดว่าต้องมีการอัปเดตการประชุมของบุคคลที่สามที่เกี่ยวข้องหรือไม่
- เราจะทำการอัปเดตที่จำเป็นในการประชุมดังกล่าวโดยการสร้างคำขอ API ของบุคคลที่สาม
- ระบบจะจัดเก็บโทเค็นการซิงค์ใหม่ไว้เพื่อให้การเรียกใช้ทริกเกอร์ถัดไปทำได้เพียงตรวจสอบการเปลี่ยนแปลงล่าสุดในปฏิทินเท่านั้น
เริ่มต้นการซิงค์
เมื่อส่วนเสริมสร้างการประชุมในระบบของบุคคลที่สามเรียบร้อยแล้ว ควรสร้างทริกเกอร์ที่ติดตั้งได้ซึ่งตอบสนองต่อการเปลี่ยนแปลงกิจกรรมในปฏิทินนี้ หากยังไม่มีทริกเกอร์ดังกล่าว
หลังจากสร้างทริกเกอร์แล้ว การสร้างข้อมูลควรเสร็จสมบูรณ์ด้วยการสร้างโทเค็นการซิงค์เริ่มต้น ซึ่งทำได้ด้วยการเรียกใช้ฟังก์ชันทริกเกอร์โดยตรง
สร้างทริกเกอร์ปฏิทิน
หากต้องการซิงค์ ส่วนเสริมจะต้องตรวจจับเมื่อกิจกรรมในปฏิทินที่มีการประชุมที่แนบอยู่มีการเปลี่ยนแปลง ซึ่งทำได้ด้วยการสร้างEventUpdated
ทริกเกอร์ที่ติดตั้งได้ ส่วนเสริมของคุณต้องใช้ทริกเกอร์เพียงรายการเดียวสําหรับปฏิทินแต่ละรายการ และสามารถสร้างทริกเกอร์แบบเป็นโปรแกรมได้
เวลาที่เหมาะในการสร้างทริกเกอร์คือเมื่อผู้ใช้สร้างการประชุมครั้งแรก เนื่องจากเป็นช่วงที่ผู้ใช้เริ่มใช้ส่วนเสริม หลังจากสร้างการประชุมและยืนยันว่าไม่มีข้อผิดพลาดแล้ว ส่วนเสริมควรตรวจสอบว่ามีทริกเกอร์สำหรับผู้ใช้รายนี้หรือไม่ หากไม่มี ให้สร้าง
ใช้ฟังก์ชันทริกเกอร์การซิงค์
ฟังก์ชันทริกเกอร์จะทำงานเมื่อ Apps Script ตรวจพบเงื่อนไขที่ทำให้ทริกเกอร์เริ่มทำงาน
EventUpdated
ทริกเกอร์ปฏิทินจะทํางานเมื่อผู้ใช้สร้าง แก้ไข หรือลบกิจกรรมในปฏิทินที่ระบุ
คุณต้องติดตั้งใช้งานฟังก์ชันทริกเกอร์ที่ส่วนเสริมใช้ ฟังก์ชันทริกเกอร์นี้ควรทําสิ่งต่อไปนี้
- เรียกใช้
Calendar.Events.list()
บริการขั้นสูงของปฏิทินโดยใช้syncToken
เพื่อเรียกข้อมูลรายการเหตุการณ์ที่มีการเปลี่ยนแปลงตั้งแต่การซิงค์ครั้งล่าสุด การใช้โทเค็นการซิงค์จะช่วยลดจํานวนเหตุการณ์ที่ส่วนเสริมต้องตรวจสอบเมื่อฟังก์ชันทริกเกอร์ทำงานโดยไม่มีโทเค็นการซิงค์ที่ถูกต้อง ระบบจะกลับไปใช้การซิงค์แบบเต็ม การซิงค์แบบเต็มจะพยายามดึงข้อมูลเหตุการณ์ทั้งหมดภายในกรอบเวลาที่กำหนดเพื่อสร้างโทเค็นการซิงค์ใหม่ที่ถูกต้อง
- ระบบจะตรวจสอบเหตุการณ์ที่แก้ไขแต่ละรายการเพื่อดูว่ามีการประชุมของบุคคลที่สามที่เกี่ยวข้องหรือไม่
- หากกิจกรรมมีการประชุม ระบบจะตรวจสอบเพื่อหาสิ่งที่เปลี่ยนแปลง ทั้งนี้ขึ้นอยู่กับการเปลี่ยนแปลงของคุณ อาจจำเป็นต้องปรับเปลี่ยนการประชุมที่เกี่ยวข้อง ตัวอย่างเช่น หากกิจกรรมถูกลบ ส่วนเสริมก็ควรจะลบการประชุมนั้นด้วย
- การเปลี่ยนแปลงที่จำเป็นในการประชุมจะดำเนินการโดยการเรียก API ไปยังระบบของบุคคลที่สาม
- หลังจากทําการเปลี่ยนแปลงที่จําเป็นทั้งหมดแล้ว ให้จัดเก็บ
nextSyncToken
ที่แสดงผลโดยเมธอดCalendar.Events.list()
โทเค็นการซิงค์นี้จะอยู่ในหน้าสุดท้ายของผลลัพธ์ที่การเรียกใช้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. } }