ผู้ใช้สามารถอัปเดตหรือลบกิจกรรมใน 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. } }