-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathcode.gs
More file actions
149 lines (114 loc) · 4.34 KB
/
Copy pathcode.gs
File metadata and controls
149 lines (114 loc) · 4.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
const targetCalendarId = null;
const targetCalendar = CalendarApp.getOwnedCalendarById(targetCalendarId);
const reminderOffset = 1 * 24 * 60; // 1 days * 24 hours * 60 minutes. Set it to null to avoid adding remainders
if (! targetCalendar ) {
//Target calendar not found. List all calendars with their ids and exit
const calendars = CalendarApp.getAllCalendars()
calendars.forEach ( calendar => Logger.log (`Calendar Name: ${calendar.getName()} -- id: ${calendar.getId()}`))
throw `Calendar with id '${targetCalendarId}' not found. Please set the targetCalendar variable to one of the previous list`;
}
// Entry point
function main() {
const contacts = getContactsWithBirthdays();
for (contact of contacts) {
try {
updateOrCreateBirthDayEvent(contact);
} catch (e) {
Logger.log(`❌ Error processing contact "${contact?.getFullName()||'unknown'}": ${e}`);
}
}
Logger.log (`Processed ${contacts.length} contacts with birthday`);
}
class Contact {
constructor (fullName, birthday = null) {
this.fullName = fullName;
this.birthday = birthday;
}
getFullName () {
return this.fullName
}
getBirthday () {
return this.birthday
}
}
function getContactsWithBirthdays() {
let nextPageToken = '';
const result = [];
while (nextPageToken !== null) {
const people = People.People.Connections.list('people/me', {
personFields: 'names,birthdays',
pageToken: nextPageToken,
});
for (person of people.connections) {
if (!person.names || !person.names[0]) continue;
const displayName = person.names[0].displayName;
const birthday = person?.birthdays ? person.birthdays[0].date : null;
if (birthday === null) continue;
result.push( new Contact (displayName, birthday) );
}
nextPageToken = people?.nextPageToken || null;
}
result.sort( (a,b) => a.getFullName().localeCompare(b.getFullName()))
return result;
}
function updateOrCreateBirthDayEvent(contact) {
const contactName = contact.getFullName();
const birthdayField = contact.getBirthday();
const nextBirthday = calculateNextBirthday(birthdayField);
const pattern = "'s birthday"
const suffix = ( !! birthdayField.getYear()) ?
`${pattern} (${nextBirthday.getFullYear() - birthdayField.getYear()})` :
pattern;
const title = contactName + suffix;
const birthdayEvent = findBirthdayEvent(targetCalendar, contactName, nextBirthday, pattern);
if (birthdayEvent) {
if (birthdayEvent.getTitle() == title && birthdayEvent.isAllDayEvent()) {
Logger.log(`Skipped event: ${title}`);
return;
}
// Update the existing event
birthdayEvent.setTitle(title);
birthdayEvent.setAllDayDate(new Date(nextBirthday.getFullYear(), nextBirthday.getMonth(), nextBirthday.getDate()));
if (reminderOffset !== null) {
var reminders = birthdayEvent.getPopupReminders();
if (!reminders.includes(reminderOffset)) {
birthdayEvent.addPopupReminder(reminderOffset);
}
}
Logger.log(`Updated event: ${title}`);
} else {
// Create new event
var startTime = new Date(nextBirthday.getFullYear(), nextBirthday.getMonth(), nextBirthday.getDate());
var allDayEvent = targetCalendar.createAllDayEvent(title, startTime);
if (reminderOffset !== null) {
allDayEvent.addPopupReminder(reminderOffset);
}
Logger.log(`Created new event: ${title}`);
}
}
function findBirthdayEvent(calendar, contactName, nextBirthday, pattern) {
const startDate = new Date(nextBirthday.getFullYear(), nextBirthday.getMonth(), nextBirthday.getDate());
var endDate = new Date(startDate);
endDate.setDate(startDate.getDate() + 1);
var events = calendar.getEvents(startDate, endDate);
var searchPattern = contactName + pattern;
for (var i = 0; i < events.length; i++) {
var eventTitle = events[i].getTitle();
if (eventTitle.includes(searchPattern)) {
return events[i];
}
}
return null;
}
function calculateNextBirthday(birthdayField) {
const day = birthdayField.getDay();
const month = birthdayField.getMonth() -1;
var today = new Date();
var nextBirthdayYear = today.getFullYear();
var thisYearsBirthday = new Date(today.getFullYear(), month, day);
if (today >= thisYearsBirthday) {
nextBirthdayYear++;
}
var nextBirthDay = new Date(nextBirthdayYear, month, day);
return nextBirthDay;
}