Skip to content

Commit e262da2

Browse files
committed
Updates time error and adds debug mode
1 parent 2886d14 commit e262da2

File tree

1 file changed

+134
-101
lines changed

1 file changed

+134
-101
lines changed

src/hooks/calendar.ts

Lines changed: 134 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,20 @@ interface TimeProps {
3434
dateTime?: Date;
3535
}
3636

37+
// Set as a date to test the same day function
38+
// a string in the form "YYYY-MM-DD" can be passed to test a specific date
39+
const TEST_DATE = undefined;
40+
3741
// Google maps API URL
38-
const url = `https://www.googleapis.com/calendar/v3/calendars/${config.GOOGLE_CALENDAR_ID}/events?key=${config.GOOGLE_API_KEY}`;
42+
const today = new Date(TEST_DATE ?? new Date().toLocaleDateString());
43+
const nextWeek = new Date(today);
44+
nextWeek.setDate(today.getDate() + 7);
45+
const url = `https://www.googleapis.com/calendar/v3/calendars/${
46+
config.GOOGLE_CALENDAR_ID
47+
}/events?key=${
48+
config.GOOGLE_API_KEY
49+
}&timeMax=${nextWeek.toISOString()}&timeMin=${today.toISOString()}`;
50+
console.log(url);
3951

4052
// Function to fetch all of the events
4153
const fetchEvents = async (url: string) => {
@@ -55,19 +67,32 @@ const fetchEvents = async (url: string) => {
5567
};
5668

5769
// Check if two dates are the same day
58-
function isSameDay(date1: Date, date2: Date): boolean {
59-
return (
60-
date1.getFullYear() === date2.getFullYear() &&
61-
date1.getMonth() === date2.getMonth() &&
62-
date1.getDate() === date2.getDate()
70+
function isSameDay(date1: Date, date2: Date, event?: string): boolean {
71+
// Normalize dates to midnight UTC
72+
const normalizeDate = (date: Date) =>
73+
new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
74+
75+
const d1 = normalizeDate(date1);
76+
d1.setDate(d1.getDate() + 1);
77+
const d2 = normalizeDate(date2);
78+
79+
const result = d1.getTime() === d2.getTime();
80+
81+
console.log(
82+
`Date1: ${d1.toISOString()}`,
83+
`Date2: ${d2.toISOString()}`,
84+
`Event: ${event}`,
85+
`Are the same day? ${result}`
6386
);
87+
88+
return result;
6489
}
6590

66-
// remove html tags from a piece of text
91+
// remove html tags from a piece of text
6792
// as the returned description from gcal api returns with tags
6893
function removeHTMLTags(str: string) {
69-
if (str && typeof(str) === "string") {
70-
return str.replace(/(<([^>]+)>)/ig, "");
94+
if (str && typeof str === "string") {
95+
return str.replace(/(<([^>]+)>)/gi, "");
7196
} else {
7297
throw new TypeError(
7398
"The value passed to removeHTMLTags is not a string!"
@@ -83,7 +108,11 @@ interface DateProps {
83108
}
84109

85110
// Grab the start and end date or time, depending if the event is multi or single day in duration
86-
function getDateProps(date1: Date | string, date2: Date | string) {
111+
function getDateProps(
112+
date1: Date | string,
113+
date2: Date | string,
114+
event?: string
115+
) {
87116
const dateObject: DateProps = {
88117
start: "",
89118
end: "",
@@ -95,17 +124,27 @@ function getDateProps(date1: Date | string, date2: Date | string) {
95124
const newDate = new Date(date1);
96125
newDate.setHours(newDate.getHours() - 4);
97126
const month = (newDate.getMonth() + 1).toString();
98-
const day = (newDate.getDate()).toString();
127+
const day = newDate.getDate().toString();
99128
const year = newDate.getFullYear().toString();
100129

130+
newDate.setDate(newDate.getDate() - 1);
131+
if (event === "Operations Meeting" || event === "Kickstart Meeting") {
132+
newDate.setDate(newDate.getDate() - 7);
133+
}
134+
101135
const newDate2 = new Date(date2);
102136
newDate2.setHours(newDate2.getHours() - 4);
103137
const month2 = (newDate2.getMonth() + 1).toString();
104138
const day2 = newDate2.getDate().toString();
105139
const year2 = newDate2.getFullYear().toString();
106140

141+
console.log(event, newDate, newDate2);
142+
107143
// Set start and end to times, and include the date
108-
if (isSameDay(newDate, newDate2)) {
144+
if (
145+
isSameDay(newDate, newDate2, `${event} SAME DAY CHECK FOR DATE FORMAT`)
146+
) {
147+
console.log("Same day event");
109148
const hours1 = newDate.getHours();
110149
const minutes1 = newDate.getMinutes().toString().padStart(2, "0");
111150
const hours2 = newDate2.getHours();
@@ -134,101 +173,91 @@ async function getValidEvents() {
134173
const data = await fetchEvents(url);
135174

136175
// sets all consts to a new date with the local timezone.
137-
const today = new Date(new Date().toLocaleDateString());
138-
const tomorrow = new Date(new Date().toLocaleDateString());
139-
const nextWeek = new Date(new Date().toLocaleDateString());
176+
const today = new Date(TEST_DATE ?? new Date().toLocaleDateString());
177+
const tomorrow = new Date(today);
178+
const nextWeek = new Date(today);
140179

141180
// offsets tomorrow and nextweek appropriately (you can do this to add days to a date)
142181
tomorrow.setDate(today.getDate() + 1);
143182
nextWeek.setDate(today.getDate() + 7);
144-
183+
145184
const validEvents: Messages[] = [];
146-
// filters out "cancelled" events from the initial data
147-
const allEvents = data.items.filter((event) => event.status !== "cancelled");
185+
// filters out "cancelled" events from the initial data and objects that are recurring, and obj.recurrence is not null
186+
const allEvents = data.items
187+
.filter((event) => event.status !== "cancelled")
188+
.filter((event) => event.recurrence !== null)
189+
// remove elements with the same summary, keeping the greatest date
190+
// this is to prevent duplicate events from being displayed
191+
.reduce(
192+
(
193+
acc: GoogleCalendarDataProps[],
194+
event: GoogleCalendarDataProps
195+
) => {
196+
const existingEvent = acc.find(
197+
(e) => e.summary === event.summary
198+
);
199+
if (existingEvent) {
200+
const existingDate = new Date(
201+
existingEvent.start.dateTime ??
202+
existingEvent.start.date ??
203+
""
204+
);
205+
const currentDate = new Date(
206+
event.start.dateTime ?? event.start.date ?? ""
207+
);
208+
if (currentDate > existingDate) {
209+
acc = acc.filter((e) => e.summary !== event.summary);
210+
acc.push(event);
211+
}
212+
} else {
213+
if (
214+
event.summary === "Operations Meeting" ||
215+
event.summary === "Kickstart Meeting"
216+
) {
217+
const newDate = new Date(
218+
event.start.dateTime ?? event.start.date ?? ""
219+
);
220+
newDate.setDate(newDate.getDate() + 7);
221+
event.start.dateTime = newDate;
222+
}
223+
acc.push(event);
224+
}
225+
return acc;
226+
},
227+
[]
228+
);
229+
230+
// Print all summaries and start dates
231+
allEvents.map((obj: GoogleCalendarDataProps) => {
232+
console.log(obj.summary, obj.start.dateTime);
233+
});
148234

149235
// maps through the filtered events
150236
allEvents.map((obj: GoogleCalendarDataProps) => {
151237
// gets the event date based on two fields from the API
152238
// also sets this to local time zone
153-
const eventDate = new Date(new Date(
154-
obj.start.dateTime ?? obj.start.date ?? "TBA"
155-
).toLocaleDateString());
156-
157-
// checks if this is a recurring event
158-
if (obj.recurrence) {
159-
// parses through the RRULE string provided by the API
160-
// this rule defines recurring events
161-
const rule = RRule.rrulestr(obj.recurrence[0]);
162-
// gets all the occurences based on the RRULE
163-
const occurrences = rule.all();
164-
165-
// goes through each occurrence
166-
occurrences.forEach((occurrence: Date) => {
167-
// gets the local timezone value for the occurrence
168-
occurrence = new Date(occurrence.toLocaleDateString());
169-
// if the object is already in the validEvents array, skip over this one
170-
if (
171-
!validEvents.includes({ ...obj, range: "Today" }) &&
172-
!validEvents.includes({ ...obj, range: "Tomorrow" }) &&
173-
!validEvents.includes({ ...obj, range: "Next Week" })) {
174-
// checks if today's date is the same as the occurrence,
175-
// and if the eventDate is the same day as the occurrence OR
176-
// its a known recurring event
177-
if (
178-
isSameDay(today, occurrence) &&
179-
(isSameDay(eventDate, occurrence) ||
180-
(
181-
obj.summary.includes("Operations Meetings") ||
182-
obj.summary.includes("Kickstart Meeting")
183-
)
184-
)) {
185-
validEvents.push({
186-
...obj,
187-
range: "Today",
188-
});
189-
// same as above except for tomorrow
190-
} else if (
191-
isSameDay(tomorrow, occurrence) &&
192-
isSameDay(eventDate, occurrence)
193-
) {
194-
validEvents.push({
195-
...obj,
196-
range: "Tomorrow",
197-
});
198-
// checks if next weeks date is the same as the occurrence,
199-
// if the eventDate is the same as the occurrence,
200-
// and if a known recurring event is the one we're checking
201-
} else if (
202-
isSameDay(nextWeek, occurrence) &&
203-
!obj.summary.includes("Operations Meetings") &&
204-
!obj.summary.includes("Kickstart Meeting") &&
205-
isSameDay(eventDate, occurrence)
206-
) {
207-
validEvents.push({
208-
...obj,
209-
range: "Next Week",
210-
});
211-
}
212-
}
239+
const eventDate = new Date(
240+
new Date(
241+
obj.start.dateTime ?? obj.start.date ?? "TBA"
242+
).toLocaleDateString()
243+
);
244+
245+
console.log(today, tomorrow, nextWeek);
246+
if (isSameDay(today, eventDate, `${obj.summary} TODAY`)) {
247+
validEvents.push({
248+
...obj,
249+
range: "Today",
250+
});
251+
} else if (isSameDay(tomorrow, eventDate, `${obj.summary} TOMORROW`)) {
252+
validEvents.push({
253+
...obj,
254+
range: "Tomorrow",
255+
});
256+
} else if (isSameDay(nextWeek, eventDate, `${obj.summary} NEXT WEEK`)) {
257+
validEvents.push({
258+
...obj,
259+
range: "Next Week",
213260
});
214-
// if not a recurring event
215-
} else {
216-
if (isSameDay(today, eventDate)) {
217-
validEvents.push({
218-
...obj,
219-
range: "Today",
220-
});
221-
} else if (isSameDay(tomorrow, eventDate)) {
222-
validEvents.push({
223-
...obj,
224-
range: "Tomorrow",
225-
});
226-
} else if (isSameDay(nextWeek, eventDate)) {
227-
validEvents.push({
228-
...obj,
229-
range: "Next Week",
230-
});
231-
}
232261
}
233262
});
234263

@@ -243,7 +272,8 @@ export async function execute() {
243272

244273
try {
245274
// Check events on a schedule
246-
cron.schedule("0 16 * * *", async () => {
275+
cron.schedule("*/5 * * * * *", async () => {
276+
console.log("Checking for events...");
247277
const events = await getValidEvents();
248278

249279
if (events.length === 0) {
@@ -258,7 +288,8 @@ export async function execute() {
258288
const prefix = event.range;
259289
const date = getDateProps(
260290
event.start.dateTime ?? event.start.date ?? "6/9/1969",
261-
event.end.dateTime ?? event.end.date ?? "6/9/1969"
291+
event.end.dateTime ?? event.end.date ?? "6/9/1969",
292+
event.summary
262293
);
263294

264295
// Conditionally render the fields based off the date
@@ -297,9 +328,11 @@ export async function execute() {
297328
name: `${prefix}!`,
298329
iconURL: "https://i.imgur.com/0BR5rSn.png",
299330
})
300-
.setDescription(he.decode(
301-
removeHTMLTags(event.description ?? "TBA") ?? "TBA"
302-
))
331+
.setDescription(
332+
he.decode(
333+
removeHTMLTags(event.description ?? "TBA") ?? "TBA"
334+
)
335+
)
303336
.addFields(fields)
304337

305338
.setFooter({

0 commit comments

Comments
 (0)