1

In addition to this question I'd like to ask how to efficiently retrieve only the first events of all recurring (all day) events. To call the function findFirstEvent() for each single event seems not to be reasonable. So my approach would be to filter the array of all events.

var cal=CalendarApp.getCalendarById("Calendar Id");
var startTime=new Date(1850,0,1);
var endTime=new Date();
var events=cal.getEvents(startTime, endTime);
var firstEvents=events.filter(onlyFirstEvents);

function onlyFirstEvents() {
    ...
}

What I actually need in the end is an array with the event titles as keys and Date objects as values.

Ben
  • 1,550
  • 1
  • 16
  • 24

1 Answers1

2
  • You want to retrieve all recurring events and all day events from a Google calendar.
  • Especially, You want to retrieve the date object of the start event of the recurring event.
  • You want to achieve this using Google Apps Script.

If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.

Modification points:

  • In this case, the methods of isRecurringEvent() and isAllDayEvent() are used.
  • getEvents() returns the events with the descending order. Using this, the result you expect is retrieved.

When above points are reflected to your script, it becomes as follows.

Modified script:

From:
var firstEvents=events.filter(onlyFirstEvents);
To:
var firstEvents = events.reduce(function(ar, e) {
  var id = e.getId();
  if (e.isRecurringEvent() && e.isAllDayEvent() && !ar.some(function(f) {return f.eventId == id})) {
    ar.push({eventTitle: e.getTitle(), eventId: id, startDate: e.getAllDayStartDate(), endDate: e.getAllDayEndDate()});
  }
  return ar;
}, []);

Result:

When above script is run, the following value is returned.

[
  {
    "eventTitle": "###",
    "eventId": "###",
    "startDate": ### date object ###,
    "endDate": ### date object ###
  },
,
,

]

References:

If I misunderstood your question and this was not the direction you want, I apologize.

Added:

  • So you would for loop through the result array firstEvents to get the desired array with the event titles as keys and Date objects as values?

From this, I cannot understand whether you want an array or an object. So I would like to propose 2 patterns. In this case, I thought that firstEvents of the current script can be used.

Pattern 1:

In this pattern, an array, which includes that the event titles and the start date object are the key and value, respectively, is returned. Please modify as follows.

Script:
var firstEvents = events.reduce(function(ar, e) {
  var id = e.getId();
  if (e.isRecurringEvent() && e.isAllDayEvent() && !ar.some(function(f) {return f.eventId == id})) {
    ar.push({eventTitle: e.getTitle(), eventId: id, startDate: e.getAllDayStartDate(), endDate: e.getAllDayEndDate()});
  }
  return ar;
}, []);
firstEvents = firstEvents.map(function(e) {
  var obj = {};
  obj[e.eventTitle] = e.startDate;
  return obj;
});

Pattern 2:

In this pattern, an object, which includes that the event titles and the start date object are the key and value, respectively, is returned.

Script:
var firstEvents = events.reduce(function(ar, e) {
  var id = e.getId();
  if (e.isRecurringEvent() && e.isAllDayEvent() && !ar.some(function(f) {return f.eventId == id})) {
    ar.push({eventTitle: e.getTitle(), eventId: id, startDate: e.getAllDayStartDate(), endDate: e.getAllDayEndDate()});
  }
  return ar;
}, []);
firstEvents = firstEvents.reduce(function(obj, e) {
  obj[e.eventTitle] = e.eventTitle in obj ? obj[e.eventTitle].concat(e.startDate) : [e.startDate];
  return obj;
}, {});
Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • Your answer is exemplary neat. Thank you very much! Doesn't `getEvents()` return the events in ascending order? So you would `for` loop through the result array `firstEvents` to get the desired array with the event titles as keys and `Date` objects as values? – Ben Mar 11 '20 at 18:06
  • 1
    @Ben Thank you for replying and pointing out my English. I thought that I might have misunderstood "ascending" and "descending". I had wanted to say that the 1st index of the array retrieved by `getEvents()` is oldest event. I deeply apologize for my poor English skill. About `the desired array with the event titles as keys and Date objects as values`, I updated my answer. Could you please confirm it? If that was not the direction you want, I apologize again. – Tanaike Mar 11 '20 at 22:57
  • 1
    Actually I wasn't referring to your English but to the well-arranged form of your answer as well as to your politeness. But anyway, your English is probably much better than mine. With the first event beeing the oldest, I would refer to the order as ascending, but that could be a matter of opinion. Pattern 1 is just fine. Thank you very much! By the way, there is no need to apologize at all. :) – Ben Mar 12 '20 at 17:41
  • 1
    @Ben Thank you for replying. I'm glad your issue was resolved. Also I could study from your question. Thank you, too. – Tanaike Mar 12 '20 at 22:27
  • It seems as if `firstEvents` holds not only the first events of event series but also the respectively (currently) last ones!? – Ben Mar 16 '20 at 18:22
  • @Ben Thank you for replying. Unfortunately, I cannot understand about your replying. This is due to my poor English skill. I deeply apologize for this. I would like to study more and try to understand about it. – Tanaike Mar 16 '20 at 22:09
  • It was my fault. I'm sorry! – Ben Mar 17 '20 at 15:53