I'm trying to update the recurrence rule on an event in an Apps Script application, similar to changing the end date of the recurrence in the UI and clicking "all events".
I load the first event in the series and run Calendar.Events.patch
with the new recurrence rule. The original event has a recurrence rule of 10 occurrences, weekly on Friday. I get no errors, but the returned event is unchanged.
I tried doing the same thing in the API explorer by manually copying my recurrence rule and got the same result — the returned object in the API explorer showed it ran successfully, but didn't actually update the event (the old recurrence rule was still there, instead of the new one). Why is it not failing if it's not accepting the changes?
My only change in the API explorer other than the event and calendar ID:
{
"recurrence": [
"RRULE:FREQ=WEEKLY;WKST=MO;UNTIL=20220921T102754Z;BYDAY=FR"
]
}
The goal is to have a script that removes bookings from a room resource outside a predefined booking window. The built-in AppsScript methods for RRULEs don't have a clean way to change only the RRULE without getting/setting a lot of other data about the event. We want to be able to set the end date as closely as possible to the end of the window while still following the other set rules for the RRULE.
function cleanRoom() {
resourceId = "id@resource.calendar.google.com" // this is a test room
let bulkevents = JSON.parse(Calendar.Events.list("id2@resource.calendar.google.com"));
let allevents = bulkevents.items.filter(function (e) {
return e.recurrence != undefined // return all events with a recurrance rule
});
console.log('All events with recurrances:\n\n');
// we want to look at instances of recurring events and filter down to instances more than X days in the future
for (const x of allevents) {
const startDT = new Date(x.start.dateTime); // ex. 2022-07-28T07:45:00-05:00
const title = x.summary;
// load instances — instances are what shows up on your calendar when you schedule a recurring event. instances are tied to their originator.
console.log(title);
const instances = Calendar.Events.instances(resourceId,x.id);
for (const i of instances.items) {
// from the list of instances for an event, find any with an instance after the booking window
// don't forget to make sure the booking window is correct in config.js
if (luxon.DateTime.fromISO(i.start.dateTime) > luxon.DateTime.now().plus({ weeks: bookingWindow })) {
// get the original calendar event so we can edit the end date
let offendingEvent = Calendar.Events.get(resourceId,i.recurringEventId);
let rrule = offendingEvent.recurrence[0];
console.log(rrule);
// get last valid date in format
let correctUntilDate = luxon.DateTime.now().plus({ weeks: bookingWindow });
// we need to modify the original event / all events
if (rrule.includes("COUNT")) {
let regrule = /COUNT=\d\d/;
let new_rrule = rrule.replace(regrule,'UNTIL='+correctUntilDate.set({seconds: 0}).toFormat("yyyyMMdd'T'HHmmss'Z'"));
console.log(i);
console.log(new_rrule);
const calPatch = {
recurrence: [new_rrule],
end: {
dateTime: i.end.dateTime,
timeZone: i.end.timeZone
},
start: {
dateTime: i.start.dateTime,
timeZone: i.start.timeZone
}
};
const result = Calendar.Events.update(calPatch,resourceId,offendingEvent.id);
console.log(result);
break;
}
break; // we don't need to scan every instance of every event; once it's fixed we're done, moving on to the next
}
}
}
}