Calendar API to modify the following events only using Google Apps Script - google-apps-script

I have events those repeat for every Monday starting from Feb 8, 2021. I want to modify the upcoming 28th Feb 2021 so that all future events will be repated every Wednesday. Note that the event must be updated will ALL FOLLOWING EVENTS (preserving the eventID)
var resource = Calendar.Events.get(calendar.getId(), eventId);
if (resource) {
resource.start.date = Utilities.formatDate(new Date("28-02-2021"), Session.getScriptTimeZone(), "yyyy-MM-dd");
resource.end.date = Utilities.formatDate(new Date("28-02-2021"), Session.getScriptTimeZone(), "yyyy-MM-dd");
var result = Calendar.Events.patch(resource, calendar.getId(), eventId)
}
This code will update all the recurring events including the past ones. But I need only the following events to be updated.

Based on the official document for Recurring Events, preserving the eventId is not possible since you need to create a new event based on your preferred modification and update the old recurring event and change its UNTIL parameter to end the series.
Modifying all following instances
In order to change all the instances of a recurring event on or after a given (target) instance, you must make two separate API requests. These requests split the original recurring event into two: the original one which retains the instances without the change and the new recurring event having instances where the change is applied:
Call events.update() to trim the original recurring event of the instances to be updated. Do this by setting the UNTIL component of the RRULE to point before the start time of the first target instance. Alternatively, you can set the COUNT component instead of UNTIL.
Call events.insert() to create a new recurring event with all the same data as the original, except for the change you are attempting to make. The new recurring event must have the start time of the target instance.
(UPDATE)
Sample Code:
function updateRecurr() {
var calendarId = 'c_9cdqeqqluk7vsessartfxxxxx';
var eventId = '17a97q639vmtkoghcxxxxx';
//Update eventseries, change "until" parameter in rrule to Feb. 27, 2020
var event = {
recurrence:[
"RRULE:FREQ=WEEKLY;WKST=SU;UNTIL=20210227;BYDAY=MO"
]
}
updatedEvent = Calendar.Events.patch(event,calendarId,eventId);
Logger.log(updatedEvent);
//Create new event having the same important info with different start time and rrule
var newEvent = {
summary: updatedEvent.summary,
description: updatedEvent.description,
start:{
date: Utilities.formatDate(new Date("March 3, 2021"), Session.getScriptTimeZone(), "yyyy-MM-dd")
},
end:{
date: Utilities.formatDate(new Date("March 3, 2021"), Session.getScriptTimeZone(), "yyyy-MM-dd")
},
recurrence:[
"RRULE:FREQ=WEEKLY;WKST=SU;UNTIL=20210331;BYDAY=WE"
]
}
var newEventSeries = Calendar.Events.insert(newEvent,calendarId);
Logger.log(newEventSeries);
}
OUTPUT:
Before:
After:
Note:
In the newly created event series, you will notice that I set the start date to "March 3, 2021", the reason behind this is because If I set that to "February 28, 2021" an event will also be created on that particular date. But in real life, when I created an event using Google Calendar and set the start date to "February 28, 2021" with event series of weekly occurrence every Wednesday. The actual start date set in the event was "March 3, 2021".
Just copy all other important event details if there is any, in your previous event series. In the example provided I just configured the event title and the description.

Related

Modify a Google Calendar recurrence in Apps Script

I'm trying to create a script that, given a date, will change the end date of all my recurrent events this week to that date. Unfortunately, I can't find a way to update a recurrence info.
First, I iterate all events in the week. Then, thanks to the API, I can get the recurrence info of every event:
var eventId = event.getId().split("#")[0];
var eventFromAPI = Calendar.Events.get(ID_CALENDARIO_MENUS, eventId);
var cadenaRecurrencia = eventFromAPI["recurrence"];
witch then I use to create a new recurrence to overwrite the existing one in the event.
var recurrencia = CalendarApp.newRecurrence().addWeeklyRule().onlyOnWeekdays(arrayWeekdays).until(fecha);
But when I try to set the new recurrence, it asks me for a start date that should be the original, and I can't seem to retrieve that data:
var serie = calendario_menus.getEventSeriesById(eventoId);
serie.setRecurrence(recurrencia, date);
Is there a way to access an event's recurrence, modify it so it changes for all the events that use the recurrence and update it?
Thanks for your help.

Google Calendar event from sheets script ends a day early

I have a sheets file that creates a calendar event when a button is clicked. The calendar event is based off of a user entered due date, and script created start date, a entered location, and an entered description all pulled from certain cells in the spreadsheet. The problem is that when I go to the calendar the event ends a day before the due date (or beginning of the day of the due date) and I want it to show for the entire due date. For example if I enter a due date of july 17th into the spreadsheet, when I create the calendar event it only runs through the 16th. Is there a way to get the events to schedule to the end of the day or an easy way to just offset the end date by one day in the script.
var Description = sheetTemplate.getRange('B12').getValue(); //gets discription from Cell B12
var Location = sheetTemplate.getRange('C5') .getValue(); //gets location of work order from cell C5
var StartDate = sheetTemplate.getRange('C4').getValue(); //Start Date from Cell C4
var DueDate = sheetTemplate.getRange('E5').getValue(); //Gets Due Date From Cell E5
//This portion of the code schedules the WO on the calendar//
var eventCal = CalendarApp.getCalendarById("XXXXX") ;//Get the Maintenance Calendar
var options = { 'location': Location,
'description':Description
} //sets event details
var WOevent = eventCal.createAllDayEvent(WOname,StartDate,DueDate,options);//creates a calendar event
WOevent.setColor('10') // sets the color of the calendar event to green
You have two options
Either you manually add a day to the dueDate
This can be done with new Date(ms):
var DueDate = sheetTemplate.getRange('E5').getValue();
DueDate = new Date(DueDate.getTime() + 24*60*60*1000);
Or you use the method createEvent(title, startTime, endTime, options) instead of createAllDayEvent()
This allows you to specify the end time on the DueDate:
var DueDate = sheetTemplate.getRange('E5').getValue();
DueDate = new Date(DueDate);
DueDate.setHours(23);
DueDate.setMinutes(59);
var WOevent = eventCal.createEvent(WOname,StartDate,DueDate,options);

change Time inside object

My code creates an event inside Google Calendar, I need to get the value of start time and add 2 hours to get my end time.
Here's an example of the array my function returns:
[[kljlkjl, Manaf, Tue Jun 25 16:00:00 GMT+03:00 2019]]
This is part of the code that I want to fix:
var data = ss.getRange("A"+activeRow+":G"+activeRow).getValues();
if(cellContent === "Manaf") {
Logger.log(data);
Manaf.createEvent(data[0][0],data[0][2],data[0][2],{description: "First call "+ data[0][0]}) ;
Solution
To increment hours by 2, you can utilize getHours() and setHours() methods of the Date built-in object with the instance written into data variable. As you need to increment hours dynamically, you’ll have to pair these methods like this: dateInstance.setHours(dateInstance.getHours()+2).
Sample
So, your script with this modification will look like this (please, note that I also updated your code to work directly with 1-d Array as your range is always one-row):
var data = ss.getRange("A"+activeRow+":G"+activeRow).getValues()[0];
var start = data[2];
var end = new Date(start); //create new Date to persist start;
end.setHours(start.getHours()+2); //add 2 hours;
if(cellContent === "Manaf") {
Manaf.createEvent(data[0],start,end,{description: "First call "+ data[0]});
}
Useful links
Date built-in object reference;
getHours() method deeplink;
setHours() method deeplink;

Google Apps Script: Calendar Service: Find first event in CalendarEventSeries

I'd like to calculate the age of a person whose birthday exists as event series within my calendar. To do this I need to know the first event within this series and that's the question: how to get the first event of a series from an actual event?
Thanks
Ronny
The other answer doesn't actually answer the initial request, the CalendarApp has no method to get the start date of a recurring event.
You should use the advanced Calendar API (must be enabled manually, see below and follow instructions)
Then use the advanced API to get the information you want, (the auto complete feature works on these methods too so you can easily see what is available)
Test code below, note that event ID is different for the advanced Calendar API, you have to remove the part after '#'.
function createTestEvents() {
var recurrence = CalendarApp.newRecurrence().addWeeklyRule().times(10);
var testEvent = CalendarApp.getDefaultCalendar().createEventSeries('test event serie', new Date('2016/05/10'), new Date(new Date('2016/05/10').getTime()+12*3600000), recurrence);
var id = testEvent.getId();
Logger.log('Event Series ID: ' + id);
viewTestEvent(id)
}
function viewTestEvent(id){
var event= CalendarApp.getDefaultCalendar().getEventSeriesById(id);
var calId = CalendarApp.getDefaultCalendar().getId();
Logger.log('event title = '+event.getTitle());
var AdvanncedId = id.substring(0,id.indexOf('#'));
Logger.log('AdvanncedId = '+AdvanncedId);
var testEvent = Calendar.Events.get(calId, AdvanncedId);
Logger.log('testEvent start = '+ testEvent.start);
return testEvent;
}
function test(){ // a few examples of what you can retrieve...
var event = viewTestEvent('59buf7nq6nr6qo79bh14kmsr6g#google.com');
Logger.log('\n\nstart = '+event.start);
Logger.log('\n\ncreated on = '+event.created);
Logger.log('\n\nend on = '+event.end);
Logger.log('\n\nrecurrence = '+event.recurrence);
}
You need to use the startDate parameter to get the date of the first event in the series (only the day is used; the time is ignored).
var eventSeries = CalendarApp.getDefaultCalendar().createAllDayEventSeries('No Meetings',
new Date('January 2, 2013 03:00:00 PM EST'),
CalendarApp.newRecurrence().addWeeklyRule()
.onlyOnWeekday(CalendarApp.Weekday.WEDNESDAY)
.until(new Date('January 1, 2014')));
Logger.log('Event Series ID: ' + eventSeries.getId());
You can also get the event series with the given ID using getEventSeriesById(iCalId).
If the ID given is for a single CalendarEvent, then a CalendarEventSeries will be returned with a single event in the series. Note that if the event series belongs to a calendar other than the default calendar, this method must be called from that Calendar; calling CalendarApp.getEventSeriesById(id) directly will only return an event series that exists in the default calendar.
Hope this helps!

How to modify a specific instance of an event series

Let's suppose I create a recurring event that starts on Monday at 9 AM and ends at 11 AM, this event repeats every day for 3 days.
Now I want (after I have created the events using recurrence) to change the start time of the event on Tuesday while leaving the other events unchanged, how could I do ?
I can easily get the recurrence rule for this eventSeries using the advanced calendar API, it returns something like
RRULE:FREQ=DAILY;COUNT=3
This rule can be modified at will to change all the events (and I can also update the events using patch but not just for a single event.
I tried the API tryout to get every instance of this eventSeries and I can indeed see every start and end times (*see below) but I didn't find any method to get that using the Calendar API in Google Apps Script.
I didn't find a way to modify a particular instance, i.e. to write back the modified values.
Since I can do this manually in the calendar web UI I guess I should be able to do it using a script but I really don't know how.
The code I use to get the event parameters is fairly simple :
...
for(var n = 1 ; n < data.length ; n++){
if(data[n][9] == ''){continue};
var advancedID = data[n][9].substring(0,data[n][9].indexOf('#'));
Logger.log(advancedID+'\n');
ChangeEventRecurrence(calID,advancedID);
}
}
function ChangeEventRecurrence(calID,advancedID){
var event = Calendar.Events.get(calID, advancedID);
Logger.log(event.recurrence+'\n'+JSON.stringify(event));
// here I should be able to get all the instances of this eventSeries and change them if needed
}
Here is a capture of an instance I get using the API tryout :
With CalendarApp, just specify the date range to look for the single event and loop through the result to then use .setTime() :
var cal = CalendarApp.getCalendarsByName('<YOUR_CAL>')[0];
var events = cal.getEvents(new Date("April 5, 2016 08:00:00 AM"), new Date("April 5, 2016 11:30:00 AM"));
events.forEach( function(e) {
//var e = events[0];
//if ( e.getTitle() === 'Your Title' )
e.setTime(new Date("April 5, 2016 11:00:00 AM"), new Date("April 5, 2016 01:00:00 PM"));
});
I can't tell if your "specific instance" means just a single event or every Tuesday event though, or whether you have a reason to even use the Advanced Calendar API for this case.