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