-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgoogleCalendar.ts
More file actions
111 lines (94 loc) · 2.75 KB
/
Copy pathgoogleCalendar.ts
File metadata and controls
111 lines (94 loc) · 2.75 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
import { google, calendar_v3 } from "googleapis";
import { OAuth2Client } from "google-auth-library";
import { GoogleCalendarSettings } from "./settings";
export interface CalendarEvent {
id: string;
title: string;
start: Date;
end: Date;
location?: string;
description?: string;
isAllDay: boolean;
}
export class GoogleCalendarAPI {
private oauth2Client: OAuth2Client;
private calendar: calendar_v3.Calendar;
constructor(
private settings: GoogleCalendarSettings,
private saveSettings: () => Promise<void>
) {
this.oauth2Client = new google.auth.OAuth2(
settings.clientId,
settings.clientSecret,
"http://localhost:8080/callback"
);
this.oauth2Client.setCredentials({
access_token: settings.accessToken,
refresh_token: settings.refreshToken,
expiry_date: settings.tokenExpiry,
});
// Set up automatic token refresh
this.oauth2Client.on("tokens", async (tokens) => {
if (tokens.access_token) {
this.settings.accessToken = tokens.access_token;
}
if (tokens.refresh_token) {
this.settings.refreshToken = tokens.refresh_token;
}
if (tokens.expiry_date) {
this.settings.tokenExpiry = tokens.expiry_date;
}
await this.saveSettings();
});
this.calendar = google.calendar({ version: "v3", auth: this.oauth2Client });
}
async getEventsForDate(date: Date): Promise<CalendarEvent[]> {
const startOfDay = new Date(date);
startOfDay.setHours(0, 0, 0, 0);
const endOfDay = new Date(date);
endOfDay.setHours(23, 59, 59, 999);
return this.getEventsForRange(startOfDay, endOfDay);
}
async getEventsForRange(startDate: Date, endDate: Date): Promise<CalendarEvent[]> {
try {
const response = await this.calendar.events.list({
calendarId: "primary",
timeMin: startDate.toISOString(),
timeMax: endDate.toISOString(),
singleEvents: true,
orderBy: "startTime",
});
const events = response.data.items || [];
return events.map((event) => this.parseEvent(event));
} catch (error) {
console.error("Error fetching calendar events:", error);
throw new Error("Failed to fetch calendar events. Please re-authenticate.");
}
}
private parseEvent(event: calendar_v3.Schema$Event): CalendarEvent {
const isAllDay = !event.start?.dateTime;
const start = isAllDay
? new Date(event.start!.date!)
: new Date(event.start!.dateTime!);
const end = isAllDay
? new Date(event.end!.date!)
: new Date(event.end!.dateTime!);
return {
id: event.id!,
title: event.summary || "(No title)",
start,
end,
location: event.location || undefined,
description: event.description || undefined,
isAllDay,
};
}
async testConnection(): Promise<boolean> {
try {
await this.calendar.calendarList.list();
return true;
} catch (error) {
return false;
}
}
}