@vineethnkrishnan/google-workspace-mcp 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/build/common/types.d.ts +77 -0
  2. package/build/common/types.js +3 -0
  3. package/build/common/types.js.map +1 -0
  4. package/build/common/utils.d.ts +38 -0
  5. package/build/common/utils.js +165 -0
  6. package/build/common/utils.js.map +1 -0
  7. package/build/index.d.ts +2 -0
  8. package/build/index.js +111 -0
  9. package/build/index.js.map +1 -0
  10. package/build/services/auth.service.d.ts +6 -0
  11. package/build/services/auth.service.js +20 -0
  12. package/build/services/auth.service.js.map +1 -0
  13. package/build/services/calendar.service.d.ts +10 -0
  14. package/build/services/calendar.service.js +81 -0
  15. package/build/services/calendar.service.js.map +1 -0
  16. package/build/services/drive.service.d.ts +10 -0
  17. package/build/services/drive.service.js +67 -0
  18. package/build/services/drive.service.js.map +1 -0
  19. package/build/services/gmail.service.d.ts +10 -0
  20. package/build/services/gmail.service.js +87 -0
  21. package/build/services/gmail.service.js.map +1 -0
  22. package/build/services/sheets.service.d.ts +10 -0
  23. package/build/services/sheets.service.js +83 -0
  24. package/build/services/sheets.service.js.map +1 -0
  25. package/build/tools/calendar.tools.d.ts +31 -0
  26. package/build/tools/calendar.tools.js +62 -0
  27. package/build/tools/calendar.tools.js.map +1 -0
  28. package/build/tools/drive.tools.d.ts +31 -0
  29. package/build/tools/drive.tools.js +60 -0
  30. package/build/tools/drive.tools.js.map +1 -0
  31. package/build/tools/gmail.tools.d.ts +31 -0
  32. package/build/tools/gmail.tools.js +60 -0
  33. package/build/tools/gmail.tools.js.map +1 -0
  34. package/build/tools/sheets.tools.d.ts +30 -0
  35. package/build/tools/sheets.tools.js +46 -0
  36. package/build/tools/sheets.tools.js.map +1 -0
  37. package/package.json +47 -0
@@ -0,0 +1,77 @@
1
+ export interface GoogleWorkspaceConfig {
2
+ accessToken?: string;
3
+ serviceAccountKey?: string;
4
+ delegatedUser?: string;
5
+ clientId?: string;
6
+ clientSecret?: string;
7
+ }
8
+ export interface McpToolResponse {
9
+ content: Array<{
10
+ type: string;
11
+ text: string;
12
+ }>;
13
+ isError?: boolean;
14
+ }
15
+ export interface GmailHeader {
16
+ name: string;
17
+ value: string;
18
+ }
19
+ export interface GmailMessagePart {
20
+ mimeType?: string;
21
+ headers?: GmailHeader[];
22
+ body?: {
23
+ data?: string;
24
+ size?: number;
25
+ };
26
+ parts?: GmailMessagePart[];
27
+ }
28
+ export interface GmailMessage {
29
+ id: string;
30
+ threadId: string;
31
+ snippet?: string;
32
+ payload?: GmailMessagePart;
33
+ labelIds?: string[];
34
+ internalDate?: string;
35
+ }
36
+ export interface CalendarEvent {
37
+ id?: string;
38
+ summary?: string;
39
+ description?: string;
40
+ start?: {
41
+ dateTime?: string;
42
+ date?: string;
43
+ };
44
+ end?: {
45
+ dateTime?: string;
46
+ date?: string;
47
+ };
48
+ location?: string;
49
+ organizer?: {
50
+ email?: string;
51
+ displayName?: string;
52
+ };
53
+ attendees?: Array<{
54
+ email?: string;
55
+ displayName?: string;
56
+ responseStatus?: string;
57
+ }>;
58
+ status?: string;
59
+ htmlLink?: string;
60
+ hangoutLink?: string;
61
+ conferenceData?: unknown;
62
+ kind?: string;
63
+ etag?: string;
64
+ }
65
+ export interface DriveFile {
66
+ id?: string;
67
+ name?: string;
68
+ mimeType?: string;
69
+ modifiedTime?: string;
70
+ size?: string;
71
+ webViewLink?: string;
72
+ owners?: Array<{
73
+ displayName?: string;
74
+ emailAddress?: string;
75
+ }>;
76
+ kind?: string;
77
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/common/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,38 @@
1
+ import { McpToolResponse, GmailMessagePart, GmailHeader, CalendarEvent, DriveFile } from "./types";
2
+ /**
3
+ * Decode Gmail base64url-encoded body content.
4
+ */
5
+ export declare function decodeBase64Url(str: string): string;
6
+ /**
7
+ * Recursively walk MIME parts to find and decode the email body.
8
+ * Prefers text/plain over text/html.
9
+ */
10
+ export declare function extractEmailBody(payload: GmailMessagePart | undefined): string;
11
+ /**
12
+ * Extract key headers (From, To, Subject, Date) from Gmail header array.
13
+ */
14
+ export declare function simplifyEmailHeaders(headers: GmailHeader[] | undefined): Record<string, string>;
15
+ /**
16
+ * Flatten a Calendar event to essential fields.
17
+ */
18
+ export declare function simplifyCalendarEvent(event: CalendarEvent): Record<string, unknown>;
19
+ /**
20
+ * Flatten a Drive file to essential fields.
21
+ */
22
+ export declare function simplifyDriveFile(file: DriveFile): Record<string, unknown>;
23
+ /**
24
+ * Recursively remove Google API metadata keys (kind, etag, nextPageToken).
25
+ */
26
+ export declare function stripGoogleMetadata(obj: unknown, keys?: string[]): unknown;
27
+ /**
28
+ * Compose all Google-specific transformations.
29
+ */
30
+ export declare function transformGoogleResponse(data: unknown): unknown;
31
+ /**
32
+ * Transform data and wrap in MCP tool response format.
33
+ */
34
+ export declare function formatMcpResponse(data: unknown): McpToolResponse;
35
+ /**
36
+ * Wrap an error in the MCP tool error response format.
37
+ */
38
+ export declare function formatMcpError(error: unknown): McpToolResponse;
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.decodeBase64Url = decodeBase64Url;
4
+ exports.extractEmailBody = extractEmailBody;
5
+ exports.simplifyEmailHeaders = simplifyEmailHeaders;
6
+ exports.simplifyCalendarEvent = simplifyCalendarEvent;
7
+ exports.simplifyDriveFile = simplifyDriveFile;
8
+ exports.stripGoogleMetadata = stripGoogleMetadata;
9
+ exports.transformGoogleResponse = transformGoogleResponse;
10
+ exports.formatMcpResponse = formatMcpResponse;
11
+ exports.formatMcpError = formatMcpError;
12
+ const GOOGLE_STRIP_KEYS = ["kind", "etag", "nextPageToken"];
13
+ /**
14
+ * Decode Gmail base64url-encoded body content.
15
+ */
16
+ function decodeBase64Url(str) {
17
+ const base64 = str.replace(/-/g, "+").replace(/_/g, "/");
18
+ const padded = base64 + "=".repeat((4 - (base64.length % 4)) % 4);
19
+ return Buffer.from(padded, "base64").toString("utf-8");
20
+ }
21
+ /**
22
+ * Strip HTML tags from a string, leaving plain text.
23
+ */
24
+ function stripHtmlTags(html) {
25
+ return html
26
+ .replace(/<br\s*\/?>/gi, "\n")
27
+ .replace(/<\/p>/gi, "\n")
28
+ .replace(/<\/div>/gi, "\n")
29
+ .replace(/<[^>]*>/g, "")
30
+ .replace(/&nbsp;/gi, " ")
31
+ .replace(/&amp;/gi, "&")
32
+ .replace(/&lt;/gi, "<")
33
+ .replace(/&gt;/gi, ">")
34
+ .replace(/&quot;/gi, '"')
35
+ .replace(/&#39;/gi, "'")
36
+ .replace(/\n{3,}/g, "\n\n")
37
+ .trim();
38
+ }
39
+ /**
40
+ * Recursively walk MIME parts to find and decode the email body.
41
+ * Prefers text/plain over text/html.
42
+ */
43
+ function extractEmailBody(payload) {
44
+ if (!payload)
45
+ return "";
46
+ // Check for direct body content
47
+ if (payload.body?.data) {
48
+ const decoded = decodeBase64Url(payload.body.data);
49
+ if (payload.mimeType === "text/html") {
50
+ return stripHtmlTags(decoded);
51
+ }
52
+ return decoded;
53
+ }
54
+ // Recursively search parts
55
+ if (payload.parts && payload.parts.length > 0) {
56
+ // Prefer text/plain
57
+ const plainPart = payload.parts.find((p) => p.mimeType === "text/plain");
58
+ if (plainPart) {
59
+ return extractEmailBody(plainPart);
60
+ }
61
+ // Fall back to text/html
62
+ const htmlPart = payload.parts.find((p) => p.mimeType === "text/html");
63
+ if (htmlPart) {
64
+ return extractEmailBody(htmlPart);
65
+ }
66
+ // Recurse into multipart/* parts
67
+ for (const part of payload.parts) {
68
+ if (part.mimeType?.startsWith("multipart/")) {
69
+ const body = extractEmailBody(part);
70
+ if (body)
71
+ return body;
72
+ }
73
+ }
74
+ }
75
+ return "";
76
+ }
77
+ /**
78
+ * Extract key headers (From, To, Subject, Date) from Gmail header array.
79
+ */
80
+ function simplifyEmailHeaders(headers) {
81
+ if (!headers)
82
+ return {};
83
+ const targetHeaders = ["From", "To", "Subject", "Date", "Cc", "Bcc"];
84
+ const result = {};
85
+ for (const header of headers) {
86
+ if (targetHeaders.includes(header.name)) {
87
+ result[header.name.toLowerCase()] = header.value;
88
+ }
89
+ }
90
+ return result;
91
+ }
92
+ /**
93
+ * Flatten a Calendar event to essential fields.
94
+ */
95
+ function simplifyCalendarEvent(event) {
96
+ return {
97
+ id: event.id,
98
+ summary: event.summary ?? "(no title)",
99
+ start: event.start?.dateTime ?? event.start?.date ?? null,
100
+ end: event.end?.dateTime ?? event.end?.date ?? null,
101
+ location: event.location ?? null,
102
+ organizer: event.organizer?.displayName ?? event.organizer?.email ?? null,
103
+ attendees: event.attendees?.map((a) => a.displayName ?? a.email ?? "unknown") ?? [],
104
+ status: event.status ?? null,
105
+ htmlLink: event.htmlLink ?? null,
106
+ };
107
+ }
108
+ /**
109
+ * Flatten a Drive file to essential fields.
110
+ */
111
+ function simplifyDriveFile(file) {
112
+ return {
113
+ id: file.id,
114
+ name: file.name ?? "(untitled)",
115
+ mimeType: file.mimeType ?? null,
116
+ modifiedTime: file.modifiedTime ?? null,
117
+ size: file.size ?? null,
118
+ webViewLink: file.webViewLink ?? null,
119
+ owners: file.owners?.map((o) => o.displayName ?? o.emailAddress ?? "unknown") ?? [],
120
+ };
121
+ }
122
+ /**
123
+ * Recursively remove Google API metadata keys (kind, etag, nextPageToken).
124
+ */
125
+ function stripGoogleMetadata(obj, keys = GOOGLE_STRIP_KEYS) {
126
+ if (obj === null || obj === undefined)
127
+ return obj;
128
+ if (Array.isArray(obj))
129
+ return obj.map((item) => stripGoogleMetadata(item, keys));
130
+ if (typeof obj !== "object")
131
+ return obj;
132
+ const result = {};
133
+ for (const [key, value] of Object.entries(obj)) {
134
+ if (keys.includes(key))
135
+ continue;
136
+ result[key] = stripGoogleMetadata(value, keys);
137
+ }
138
+ return result;
139
+ }
140
+ /**
141
+ * Compose all Google-specific transformations.
142
+ */
143
+ function transformGoogleResponse(data) {
144
+ return stripGoogleMetadata(data);
145
+ }
146
+ /**
147
+ * Transform data and wrap in MCP tool response format.
148
+ */
149
+ function formatMcpResponse(data) {
150
+ const transformed = transformGoogleResponse(data);
151
+ return {
152
+ content: [{ type: "text", text: JSON.stringify(transformed, null, 2) }],
153
+ };
154
+ }
155
+ /**
156
+ * Wrap an error in the MCP tool error response format.
157
+ */
158
+ function formatMcpError(error) {
159
+ const message = error instanceof Error ? error.message : String(error);
160
+ return {
161
+ content: [{ type: "text", text: `Error: ${message}` }],
162
+ isError: true,
163
+ };
164
+ }
165
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/common/utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/build/index.js ADDED
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
5
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
6
+ const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
7
+ const zod_1 = require("zod");
8
+ const auth_service_1 = require("./services/auth.service");
9
+ const gmail_service_1 = require("./services/gmail.service");
10
+ const calendar_service_1 = require("./services/calendar.service");
11
+ const drive_service_1 = require("./services/drive.service");
12
+ const sheets_service_1 = require("./services/sheets.service");
13
+ const gmail_tools_1 = require("./tools/gmail.tools");
14
+ const calendar_tools_1 = require("./tools/calendar.tools");
15
+ const drive_tools_1 = require("./tools/drive.tools");
16
+ const sheets_tools_1 = require("./tools/sheets.tools");
17
+ // Validate required config
18
+ const GOOGLE_ACCESS_TOKEN = process.env.GOOGLE_ACCESS_TOKEN;
19
+ if (!GOOGLE_ACCESS_TOKEN) {
20
+ console.error("GOOGLE_ACCESS_TOKEN environment variable is required. " +
21
+ "Get a token from https://developers.google.com/oauthplayground/");
22
+ process.exit(1);
23
+ }
24
+ // Initialize auth
25
+ const authService = new auth_service_1.GoogleAuthService({
26
+ accessToken: GOOGLE_ACCESS_TOKEN,
27
+ });
28
+ // Initialize services
29
+ const gmailService = new gmail_service_1.GmailService(authService);
30
+ const calendarService = new calendar_service_1.CalendarService(authService);
31
+ const driveService = new drive_service_1.DriveService(authService);
32
+ const sheetsService = new sheets_service_1.SheetsService(authService);
33
+ // Initialize tool classes
34
+ const tools = {
35
+ gmail: new gmail_tools_1.GmailTools(gmailService),
36
+ calendar: new calendar_tools_1.CalendarTools(calendarService),
37
+ drive: new drive_tools_1.DriveTools(driveService),
38
+ sheets: new sheets_tools_1.SheetsTools(sheetsService),
39
+ };
40
+ // Combine all schemas
41
+ const AllToolSchemas = {
42
+ ...gmail_tools_1.GmailToolSchemas,
43
+ ...calendar_tools_1.CalendarToolSchemas,
44
+ ...drive_tools_1.DriveToolSchemas,
45
+ ...sheets_tools_1.SheetsToolSchemas,
46
+ };
47
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
48
+ const { version } = require("../package.json");
49
+ const server = new index_js_1.Server({
50
+ name: "google-workspace-mcp",
51
+ version,
52
+ }, {
53
+ capabilities: {
54
+ tools: {},
55
+ },
56
+ });
57
+ /**
58
+ * Handler for listing available tools.
59
+ */
60
+ server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
61
+ return {
62
+ tools: Object.entries(AllToolSchemas).map(([name, config]) => ({
63
+ name,
64
+ description: config.description,
65
+ inputSchema: zod_1.z.toJSONSchema(config.schema),
66
+ })),
67
+ };
68
+ });
69
+ const toolRegistry = {};
70
+ for (const name of Object.keys(gmail_tools_1.GmailToolSchemas)) {
71
+ toolRegistry[name] = (args) => tools.gmail[name](args);
72
+ }
73
+ for (const name of Object.keys(calendar_tools_1.CalendarToolSchemas)) {
74
+ toolRegistry[name] = (args) => tools.calendar[name](args);
75
+ }
76
+ for (const name of Object.keys(drive_tools_1.DriveToolSchemas)) {
77
+ toolRegistry[name] = (args) => tools.drive[name](args);
78
+ }
79
+ for (const name of Object.keys(sheets_tools_1.SheetsToolSchemas)) {
80
+ toolRegistry[name] = (args) => tools.sheets[name](args);
81
+ }
82
+ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
83
+ try {
84
+ const { name, arguments: args } = request.params;
85
+ const handler = toolRegistry[name];
86
+ if (!handler) {
87
+ throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Tool not found: ${name}`);
88
+ }
89
+ return await handler(args ?? {});
90
+ }
91
+ catch (error) {
92
+ const message = error instanceof Error ? error.message : String(error);
93
+ return {
94
+ content: [{ type: "text", text: `Error: ${message}` }],
95
+ isError: true,
96
+ };
97
+ }
98
+ });
99
+ /**
100
+ * Start the server using Stdio transport.
101
+ */
102
+ async function main() {
103
+ const transport = new stdio_js_1.StdioServerTransport();
104
+ await server.connect(transport);
105
+ console.error("Google Workspace MCP Server running on stdio");
106
+ }
107
+ main().catch((error) => {
108
+ console.error("Server error:", error);
109
+ process.exit(1);
110
+ });
111
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { GoogleWorkspaceConfig } from "../common/types";
2
+ export declare class GoogleAuthService {
3
+ private accessToken;
4
+ constructor(config: GoogleWorkspaceConfig);
5
+ getAccessToken(): Promise<string>;
6
+ }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GoogleAuthService = void 0;
4
+ class GoogleAuthService {
5
+ accessToken;
6
+ constructor(config) {
7
+ if (config.accessToken) {
8
+ this.accessToken = config.accessToken;
9
+ }
10
+ else {
11
+ throw new Error("Google Workspace authentication required. Set GOOGLE_ACCESS_TOKEN environment variable. " +
12
+ "Get a token from https://developers.google.com/oauthplayground/");
13
+ }
14
+ }
15
+ async getAccessToken() {
16
+ return this.accessToken;
17
+ }
18
+ }
19
+ exports.GoogleAuthService = GoogleAuthService;
20
+ //# sourceMappingURL=auth.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.service.js","sourceRoot":"","sources":["../../src/services/auth.service.ts"],"names":[],"mappings":";;;AAEA,MAAa,iBAAiB;IACpB,WAAW,CAAS;IAE5B,YAAY,MAA6B;QACvC,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YACvB,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;QACxC,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CACb,0FAA0F;gBACxF,iEAAiE,CACpE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;CACF;AAjBD,8CAiBC"}
@@ -0,0 +1,10 @@
1
+ import { GoogleAuthService } from "./auth.service";
2
+ export declare class CalendarService {
3
+ private auth;
4
+ private baseUrl;
5
+ constructor(auth: GoogleAuthService);
6
+ private request;
7
+ listCalendars(): Promise<unknown>;
8
+ listEvents(calendarId?: string, timeMin?: string, timeMax?: string, maxResults?: number): Promise<unknown>;
9
+ getEvent(calendarId: string, eventId: string): Promise<unknown>;
10
+ }
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CalendarService = void 0;
4
+ const utils_1 = require("../common/utils");
5
+ class CalendarService {
6
+ auth;
7
+ baseUrl = "https://www.googleapis.com/calendar/v3";
8
+ constructor(auth) {
9
+ this.auth = auth;
10
+ }
11
+ async request(path, params) {
12
+ const token = await this.auth.getAccessToken();
13
+ const url = new URL(`${this.baseUrl}${path}`);
14
+ if (params) {
15
+ for (const [key, value] of Object.entries(params)) {
16
+ if (value !== undefined && value !== null && value !== "") {
17
+ url.searchParams.set(key, String(value));
18
+ }
19
+ }
20
+ }
21
+ const response = await fetch(url.toString(), {
22
+ headers: {
23
+ Authorization: `Bearer ${token}`,
24
+ "Content-Type": "application/json",
25
+ },
26
+ });
27
+ if (!response.ok) {
28
+ const errorBody = await response.text().catch(() => "");
29
+ switch (response.status) {
30
+ case 401:
31
+ throw new Error("Calendar authentication failed. Your access token may be expired.");
32
+ case 403:
33
+ throw new Error("Calendar access denied. Token may lack the calendar.readonly scope.");
34
+ case 404:
35
+ throw new Error("Calendar resource not found. Check the calendar or event ID.");
36
+ case 429:
37
+ throw new Error("Calendar API rate limit exceeded. Try again later.");
38
+ default:
39
+ throw new Error(`Calendar API error (${response.status}): ${errorBody || response.statusText}`);
40
+ }
41
+ }
42
+ return response.json();
43
+ }
44
+ async listCalendars() {
45
+ const data = await this.request("/users/me/calendarList");
46
+ return {
47
+ calendars: (data.items ?? []).map((cal) => ({
48
+ id: cal.id,
49
+ summary: cal.summary,
50
+ description: cal.description ?? null,
51
+ primary: cal.primary ?? false,
52
+ accessRole: cal.accessRole ?? null,
53
+ })),
54
+ };
55
+ }
56
+ async listEvents(calendarId = "primary", timeMin, timeMax, maxResults = 10) {
57
+ const params = {
58
+ maxResults,
59
+ singleEvents: "true",
60
+ orderBy: "startTime",
61
+ };
62
+ if (timeMin)
63
+ params.timeMin = timeMin;
64
+ if (timeMax)
65
+ params.timeMax = timeMax;
66
+ const encodedCalendarId = encodeURIComponent(calendarId);
67
+ const data = await this.request(`/calendars/${encodedCalendarId}/events`, params);
68
+ return {
69
+ calendar: data.summary ?? calendarId,
70
+ events: (data.items ?? []).map(utils_1.simplifyCalendarEvent),
71
+ };
72
+ }
73
+ async getEvent(calendarId, eventId) {
74
+ const encodedCalendarId = encodeURIComponent(calendarId);
75
+ const encodedEventId = encodeURIComponent(eventId);
76
+ const event = await this.request(`/calendars/${encodedCalendarId}/events/${encodedEventId}`);
77
+ return (0, utils_1.simplifyCalendarEvent)(event);
78
+ }
79
+ }
80
+ exports.CalendarService = CalendarService;
81
+ //# sourceMappingURL=calendar.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar.service.js","sourceRoot":"","sources":["../../src/services/calendar.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { GoogleAuthService } from "./auth.service";
2
+ export declare class DriveService {
3
+ private auth;
4
+ private baseUrl;
5
+ constructor(auth: GoogleAuthService);
6
+ private request;
7
+ listFiles(query?: string, maxResults?: number): Promise<unknown>;
8
+ getFile(fileId: string): Promise<unknown>;
9
+ searchFiles(query: string, maxResults?: number): Promise<unknown>;
10
+ }
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DriveService = void 0;
4
+ const utils_1 = require("../common/utils");
5
+ class DriveService {
6
+ auth;
7
+ baseUrl = "https://www.googleapis.com/drive/v3";
8
+ constructor(auth) {
9
+ this.auth = auth;
10
+ }
11
+ async request(path, params) {
12
+ const token = await this.auth.getAccessToken();
13
+ const url = new URL(`${this.baseUrl}${path}`);
14
+ if (params) {
15
+ for (const [key, value] of Object.entries(params)) {
16
+ if (value !== undefined && value !== null && value !== "") {
17
+ url.searchParams.set(key, String(value));
18
+ }
19
+ }
20
+ }
21
+ const response = await fetch(url.toString(), {
22
+ headers: {
23
+ Authorization: `Bearer ${token}`,
24
+ "Content-Type": "application/json",
25
+ },
26
+ });
27
+ if (!response.ok) {
28
+ const errorBody = await response.text().catch(() => "");
29
+ switch (response.status) {
30
+ case 401:
31
+ throw new Error("Drive authentication failed. Your access token may be expired.");
32
+ case 403:
33
+ throw new Error("Drive access denied. Token may lack the drive.readonly scope.");
34
+ case 404:
35
+ throw new Error("Drive resource not found. Check the file ID.");
36
+ case 429:
37
+ throw new Error("Drive API rate limit exceeded. Try again later.");
38
+ default:
39
+ throw new Error(`Drive API error (${response.status}): ${errorBody || response.statusText}`);
40
+ }
41
+ }
42
+ return response.json();
43
+ }
44
+ async listFiles(query, maxResults = 10) {
45
+ const params = {
46
+ pageSize: maxResults,
47
+ fields: "files(id,name,mimeType,modifiedTime,size,webViewLink,owners)",
48
+ };
49
+ if (query)
50
+ params.q = query;
51
+ const data = await this.request("/files", params);
52
+ return {
53
+ files: (data.files ?? []).map(utils_1.simplifyDriveFile),
54
+ };
55
+ }
56
+ async getFile(fileId) {
57
+ const file = await this.request(`/files/${fileId}`, {
58
+ fields: "id,name,mimeType,modifiedTime,size,webViewLink,owners,description,createdTime,parents,shared,permissions",
59
+ });
60
+ return (0, utils_1.simplifyDriveFile)(file);
61
+ }
62
+ async searchFiles(query, maxResults = 10) {
63
+ return this.listFiles(query, maxResults);
64
+ }
65
+ }
66
+ exports.DriveService = DriveService;
67
+ //# sourceMappingURL=drive.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drive.service.js","sourceRoot":"","sources":["../../src/services/drive.service.ts"],"names":[],"mappings":";;;AAEA,2CAAoD;AAEpD,MAAa,YAAY;IAGH;IAFZ,OAAO,GAAG,qCAAqC,CAAC;IAExD,YAAoB,IAAuB;QAAvB,SAAI,GAAJ,IAAI,CAAmB;IAAG,CAAC;IAEvC,KAAK,CAAC,OAAO,CAAI,IAAY,EAAE,MAAwC;QAC7E,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;QAC/C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,CAAC,CAAC;QAE9C,IAAI,MAAM,EAAE,CAAC;YACX,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAClD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;oBAC1D,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;gBAC3C,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;YAC3C,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,KAAK,EAAE;gBAChC,cAAc,EAAE,kBAAkB;aACnC;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YACxD,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC;gBACxB,KAAK,GAAG;oBACN,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;gBACpF,KAAK,GAAG;oBACN,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;gBACnF,KAAK,GAAG;oBACN,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;gBAClE,KAAK,GAAG;oBACN,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;gBACrE;oBACE,MAAM,IAAI,KAAK,CACb,oBAAoB,QAAQ,CAAC,MAAM,MAAM,SAAS,IAAI,QAAQ,CAAC,UAAU,EAAE,CAC5E,CAAC;YACN,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,EAAgB,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,KAAc,EAAE,aAAqB,EAAE;QACrD,MAAM,MAAM,GAAoC;YAC9C,QAAQ,EAAE,UAAU;YACpB,MAAM,EAAE,8DAA8D;SACvE,CAAC;QACF,IAAI,KAAK;YAAE,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC;QAE5B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAE5B,QAAQ,EAAE,MAAM,CAAC,CAAC;QAErB,OAAO;YACL,KAAK,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,yBAAiB,CAAC;SACjD,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAAc;QAC1B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAY,UAAU,MAAM,EAAE,EAAE;YAC7D,MAAM,EACJ,0GAA0G;SAC7G,CAAC,CAAC;QAEH,OAAO,IAAA,yBAAiB,EAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,KAAa,EAAE,aAAqB,EAAE;QACtD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IAC3C,CAAC;CACF;AAzED,oCAyEC"}
@@ -0,0 +1,10 @@
1
+ import { GoogleAuthService } from "./auth.service";
2
+ export declare class GmailService {
3
+ private auth;
4
+ private baseUrl;
5
+ constructor(auth: GoogleAuthService);
6
+ private request;
7
+ listMessages(query?: string, maxResults?: number): Promise<unknown>;
8
+ getMessage(messageId: string): Promise<unknown>;
9
+ searchMessages(query: string, maxResults?: number): Promise<unknown>;
10
+ }