Google Calendar API V3:如何将重复事件复制到其他日历?
解决Google Calendar API复制重复事件的问题
嘿,我刚好踩过这个坑!你遇到的问题核心在于:当你设置singleEvents: true调用Events.list时,API返回的是重复事件的单个实例,而不是完整的重复事件系列,而且recurringEventId是API自动生成的只读属性,确实没法手动赋值给新创建的事件。咱们换个思路就能解决:
核心解决方案
不要先拆分重复事件为单个实例,而是直接复制完整的重复事件系列(母事件)到目标日历,这样目标日历会自动根据原有的recurrence规则生成整个重复事件系列,而不是零散的单个事件。如果需要限制在指定日期范围内,复制后再清理超出范围的实例即可。
修改后的代码
function DuplicateCalendars() { var calendarIdFrom = 'xxxxxxxxxxxxx@group.calendar.google.com'; var calendarIdTo = 'yyyyyyyyyyyyyy@group.calendar.google.com'; // 日期范围:2017-08-31 到 2018-08-31 var start = new Date("2017-08-31T00:01:00Z"); var end = new Date("2018-08-31T00:00:00Z"); // 关键:去掉singleEvents: true,获取完整的重复事件系列 var optionalArgs = { timeMin: start.toISOString(), timeMax: end.toISOString(), showDeleted: false, maxResults: 5, orderBy: 'startTime' }; var response = Calendar.Events.list(calendarIdFrom, optionalArgs); var events = response.items; if (events.length > 0) { for (var i = 0; i < events.length; i++) { var event = events[i]; // 只复制必要的属性,排除只读属性(比如id、recurringEventId、updated等) var newCalendarEvent = { "summary": event.summary, "description": event.description, "location": event.location, "colorId": event.colorId, "start": event.start, "end": event.end, "endTimeUnspecified": event.endTimeUnspecified, "reminders": event.reminders, "attachments": event.attachments, "recurrence": event.recurrence // 这是重复事件的核心规则,必须保留 }; // 插入完整的重复事件系列到目标日历 var insertedEvent = Calendar.Events.insert(newCalendarEvent, calendarIdTo, { supportsAttachments: true }); // 可选:如果需要只保留指定日期范围内的重复实例,删除超出范围的 cleanUpRecurringEventsOutsideRange(insertedEvent.id, calendarIdTo, start, end); } } else { Logger.log('No upcoming events found.'); } } // 辅助函数:删除重复事件系列中超出指定范围的实例 function cleanUpRecurringEventsOutsideRange(eventId, calendarId, start, end) { var instances = Calendar.Events.instances(calendarId, eventId); for (var j = 0; j < instances.items.length; j++) { var instance = instances.items[j]; var instanceStart = new Date(instance.start.dateTime || instance.start.date); // 如果实例的开始时间不在指定范围内,删除它 if (instanceStart < start || instanceStart > end) { Calendar.Events.remove(calendarId, instance.id); } } }
关键说明
- 去掉
singleEvents: true:这样API返回的是重复事件的母事件,包含完整的recurrence规则(比如RRULE),复制后目标日历会自动生成整个重复系列。 - 排除只读属性:不要复制
id、recurringEventId、created、updated这些API自动管理的只读属性,否则会导致插入失败。 - 可选的范围清理:如果不需要整个重复系列,只需要指定日期内的实例,调用
cleanUpRecurringEventsOutsideRange函数删除超出范围的实例即可。
替代思路(如果只想复制范围内的实例)
如果不想复制整个系列,而是直接创建一个只包含指定日期内实例的新重复事件,你需要手动解析源事件的recurrence规则,修改它的时间范围后再插入。但这个方法需要处理RRULE的语法(比如添加UNTIL或COUNT参数),复杂度较高,适合对RRULE熟悉的场景。
内容的提问来源于stack exchange,提问作者Riccardo
相关产品推荐
相关产品推荐

