@rnsk/toolkits 0.0.2 → 0.0.3
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.
- package/README.md +104 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.js +1 -0
- package/dist/core/schema-helpers.d.ts +20 -0
- package/dist/core/schema-helpers.js +157 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/toolkits/github/tools/Actions/list-workflow-jobs.d.ts +1 -1
- package/dist/toolkits/github/tools/Activity/list-notifications.d.ts +1 -1
- package/dist/toolkits/github/tools/Issues/add-issue-labels.d.ts +1 -1
- package/dist/toolkits/github/tools/Issues/list-authenticated-user-issues.d.ts +1 -1
- package/dist/toolkits/github/tools/Issues/list-org-issues.d.ts +1 -1
- package/dist/toolkits/github/tools/Issues/list-user-account-issues.d.ts +1 -1
- package/dist/toolkits/github/tools/Organizations/list-org-repositories.d.ts +1 -1
- package/dist/toolkits/github/tools/Webhooks/create-repo-webhook.d.ts +1 -1
- package/dist/toolkits/gmail/icon.js +14 -14
- package/dist/toolkits/gmail/manifest.js +78 -5
- package/dist/toolkits/gmail/tools/create-draft.d.ts +34 -0
- package/dist/toolkits/gmail/tools/create-draft.js +60 -0
- package/dist/toolkits/gmail/tools/delete-draft.d.ts +23 -0
- package/dist/toolkits/gmail/tools/delete-draft.js +34 -0
- package/dist/toolkits/gmail/tools/get-draft.d.ts +32 -0
- package/dist/toolkits/gmail/tools/get-draft.js +36 -0
- package/dist/toolkits/gmail/tools/get-message.d.ts +12 -12
- package/dist/toolkits/gmail/tools/get-message.js +3 -24
- package/dist/toolkits/gmail/tools/get-thread.d.ts +29 -0
- package/dist/toolkits/gmail/tools/get-thread.js +39 -0
- package/dist/toolkits/gmail/tools/index.d.ts +17 -0
- package/dist/toolkits/gmail/tools/index.js +17 -0
- package/dist/toolkits/gmail/tools/list-drafts.d.ts +28 -0
- package/dist/toolkits/gmail/tools/list-drafts.js +43 -0
- package/dist/toolkits/gmail/tools/list-labels.d.ts +20 -0
- package/dist/toolkits/gmail/tools/list-labels.js +46 -0
- package/dist/toolkits/gmail/tools/list-threads.d.ts +28 -0
- package/dist/toolkits/gmail/tools/list-threads.js +43 -0
- package/dist/toolkits/gmail/tools/modify-message-labels.d.ts +31 -0
- package/dist/toolkits/gmail/tools/modify-message-labels.js +44 -0
- package/dist/toolkits/gmail/tools/reply-to-thread.d.ts +33 -0
- package/dist/toolkits/gmail/tools/reply-to-thread.js +58 -0
- package/dist/toolkits/gmail/tools/send-draft.d.ts +29 -0
- package/dist/toolkits/gmail/tools/send-draft.js +41 -0
- package/dist/toolkits/gmail/tools/send-message.d.ts +4 -1
- package/dist/toolkits/gmail/tools/send-message.js +18 -16
- package/dist/toolkits/gmail/tools/trash-message.d.ts +29 -0
- package/dist/toolkits/gmail/tools/trash-message.js +37 -0
- package/dist/toolkits/gmail/tools/untrash-message.d.ts +29 -0
- package/dist/toolkits/gmail/tools/untrash-message.js +37 -0
- package/dist/toolkits/gmail/tools/utils.d.ts +41 -0
- package/dist/toolkits/gmail/tools/utils.js +97 -0
- package/dist/toolkits/google-calendar/manifest.js +1 -1
- package/dist/toolkits/google-calendar/tools/delete-event.d.ts +27 -0
- package/dist/toolkits/google-calendar/tools/delete-event.js +38 -0
- package/dist/toolkits/google-calendar/tools/get-event.d.ts +24 -0
- package/dist/toolkits/google-calendar/tools/get-event.js +37 -0
- package/dist/toolkits/google-calendar/tools/index.d.ts +181 -3
- package/dist/toolkits/google-calendar/tools/index.js +31 -2
- package/dist/toolkits/google-calendar/tools/search-events.d.ts +27 -0
- package/dist/toolkits/google-calendar/tools/search-events.js +49 -0
- package/dist/toolkits/google-calendar/tools/update-event.d.ts +29 -0
- package/dist/toolkits/google-calendar/tools/update-event.js +56 -0
- package/dist/toolkits/google-sheets/manifest.js +2 -2
- package/dist/toolkits/google-sheets/tools/append-values.d.ts +41 -0
- package/dist/toolkits/google-sheets/tools/append-values.js +51 -0
- package/dist/toolkits/google-sheets/tools/clear-values.d.ts +27 -0
- package/dist/toolkits/google-sheets/tools/clear-values.js +41 -0
- package/dist/toolkits/google-sheets/tools/create-spreadsheet.d.ts +33 -0
- package/dist/toolkits/google-sheets/tools/create-spreadsheet.js +59 -0
- package/dist/toolkits/google-sheets/tools/index.d.ts +205 -7
- package/dist/toolkits/google-sheets/tools/index.js +39 -4
- package/dist/toolkits/google-sheets/tools/update-values.d.ts +38 -0
- package/dist/toolkits/google-sheets/tools/update-values.js +50 -0
- package/package.json +2 -5
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { tool } from 'ai';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { encodeRFC822Message } from './utils.js';
|
|
4
|
+
export const replyToThread = tool({
|
|
5
|
+
description: 'Reply to an existing Gmail conversation thread, ensuring the message stays grouped in the same thread.',
|
|
6
|
+
inputSchema: z.object({
|
|
7
|
+
gmailToken: z.string().optional().describe('Injected by system; do not provide'),
|
|
8
|
+
threadId: z.string().describe('The ID of the thread to reply to'),
|
|
9
|
+
to: z.string().describe('Recipient email address'),
|
|
10
|
+
subject: z.string().describe('Email subject (typically prefixed with "Re: ")'),
|
|
11
|
+
body: z.string().describe('Reply body (plain text)'),
|
|
12
|
+
cc: z.string().optional().describe('Optional CC recipient email address(es), comma-separated'),
|
|
13
|
+
bcc: z.string().optional().describe('Optional BCC recipient email address(es), comma-separated'),
|
|
14
|
+
inReplyTo: z.string().optional().describe('Optional Message-ID header of the email being replied to'),
|
|
15
|
+
references: z.string().optional().describe('Optional References header string for email threading continuity'),
|
|
16
|
+
}),
|
|
17
|
+
execute: async ({ gmailToken, threadId, to, subject, body, cc, bcc, inReplyTo, references }) => {
|
|
18
|
+
try {
|
|
19
|
+
const encodedMessage = encodeRFC822Message({
|
|
20
|
+
to,
|
|
21
|
+
subject,
|
|
22
|
+
body,
|
|
23
|
+
cc,
|
|
24
|
+
bcc,
|
|
25
|
+
inReplyTo,
|
|
26
|
+
references: references || inReplyTo,
|
|
27
|
+
});
|
|
28
|
+
const response = await fetch('https://gmail.googleapis.com/gmail/v1/users/me/messages/send', {
|
|
29
|
+
method: 'POST',
|
|
30
|
+
headers: {
|
|
31
|
+
Authorization: `Bearer ${gmailToken}`,
|
|
32
|
+
'Content-Type': 'application/json',
|
|
33
|
+
},
|
|
34
|
+
body: JSON.stringify({
|
|
35
|
+
raw: encodedMessage,
|
|
36
|
+
threadId,
|
|
37
|
+
}),
|
|
38
|
+
});
|
|
39
|
+
if (!response.ok) {
|
|
40
|
+
const error = await response.json();
|
|
41
|
+
return { error: 'Failed to reply to thread', details: error };
|
|
42
|
+
}
|
|
43
|
+
const data = await response.json();
|
|
44
|
+
return {
|
|
45
|
+
success: true,
|
|
46
|
+
messageId: data.id,
|
|
47
|
+
threadId: data.threadId,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
return {
|
|
52
|
+
error: 'Error replying to thread',
|
|
53
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
//# sourceMappingURL=reply-to-thread.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export declare const sendDraft: import("ai").Tool<{
|
|
2
|
+
id: string;
|
|
3
|
+
gmailToken?: string | undefined;
|
|
4
|
+
}, {
|
|
5
|
+
error: string;
|
|
6
|
+
details: any;
|
|
7
|
+
success?: undefined;
|
|
8
|
+
messageId?: undefined;
|
|
9
|
+
threadId?: undefined;
|
|
10
|
+
labelIds?: undefined;
|
|
11
|
+
message?: undefined;
|
|
12
|
+
} | {
|
|
13
|
+
success: boolean;
|
|
14
|
+
messageId: any;
|
|
15
|
+
threadId: any;
|
|
16
|
+
labelIds: any;
|
|
17
|
+
error?: undefined;
|
|
18
|
+
details?: undefined;
|
|
19
|
+
message?: undefined;
|
|
20
|
+
} | {
|
|
21
|
+
error: string;
|
|
22
|
+
message: string;
|
|
23
|
+
details?: undefined;
|
|
24
|
+
success?: undefined;
|
|
25
|
+
messageId?: undefined;
|
|
26
|
+
threadId?: undefined;
|
|
27
|
+
labelIds?: undefined;
|
|
28
|
+
}>;
|
|
29
|
+
//# sourceMappingURL=send-draft.d.ts.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { tool } from 'ai';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
export const sendDraft = tool({
|
|
4
|
+
description: 'Send an existing Gmail draft by its draft ID.',
|
|
5
|
+
inputSchema: z.object({
|
|
6
|
+
gmailToken: z.string().optional().describe('Injected by system; do not provide'),
|
|
7
|
+
id: z.string().describe('The ID of the draft to send'),
|
|
8
|
+
}),
|
|
9
|
+
execute: async ({ gmailToken, id }) => {
|
|
10
|
+
try {
|
|
11
|
+
const response = await fetch('https://gmail.googleapis.com/gmail/v1/users/me/drafts/send', {
|
|
12
|
+
method: 'POST',
|
|
13
|
+
headers: {
|
|
14
|
+
Authorization: `Bearer ${gmailToken}`,
|
|
15
|
+
'Content-Type': 'application/json',
|
|
16
|
+
},
|
|
17
|
+
body: JSON.stringify({
|
|
18
|
+
id,
|
|
19
|
+
}),
|
|
20
|
+
});
|
|
21
|
+
if (!response.ok) {
|
|
22
|
+
const error = await response.json();
|
|
23
|
+
return { error: 'Failed to send draft', details: error };
|
|
24
|
+
}
|
|
25
|
+
const data = await response.json();
|
|
26
|
+
return {
|
|
27
|
+
success: true,
|
|
28
|
+
messageId: data.id,
|
|
29
|
+
threadId: data.threadId,
|
|
30
|
+
labelIds: data.labelIds || [],
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
return {
|
|
35
|
+
error: 'Error sending draft',
|
|
36
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
//# sourceMappingURL=send-draft.js.map
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
export declare const sendMessage: import("ai").Tool<{
|
|
2
2
|
subject: string;
|
|
3
|
-
body: string;
|
|
4
3
|
to: string;
|
|
4
|
+
body: string;
|
|
5
5
|
gmailToken?: string | undefined;
|
|
6
|
+
threadId?: string | undefined;
|
|
7
|
+
cc?: string | undefined;
|
|
8
|
+
bcc?: string | undefined;
|
|
6
9
|
}, {
|
|
7
10
|
error: string;
|
|
8
11
|
details: any;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { tool } from 'ai';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
+
import { encodeRFC822Message } from './utils.js';
|
|
3
4
|
export const sendMessage = tool({
|
|
4
5
|
description: 'Send an email via Gmail.',
|
|
5
6
|
inputSchema: z.object({
|
|
@@ -7,31 +8,32 @@ export const sendMessage = tool({
|
|
|
7
8
|
to: z.string().describe('Recipient email address'),
|
|
8
9
|
subject: z.string().describe('Email subject'),
|
|
9
10
|
body: z.string().describe('Email body (plain text)'),
|
|
11
|
+
cc: z.string().optional().describe('Optional CC recipient email address(es), comma-separated'),
|
|
12
|
+
bcc: z.string().optional().describe('Optional BCC recipient email address(es), comma-separated'),
|
|
13
|
+
threadId: z.string().optional().describe('Optional thread ID to reply or append this message to an existing conversation thread'),
|
|
10
14
|
}),
|
|
11
|
-
execute: async ({ gmailToken, to, subject, body }) => {
|
|
15
|
+
execute: async ({ gmailToken, to, subject, body, cc, bcc, threadId }) => {
|
|
12
16
|
try {
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
'Content-Type: text/plain; charset="UTF-8"',
|
|
17
|
-
'MIME-Version: 1.0',
|
|
18
|
-
'',
|
|
17
|
+
const encodedMessage = encodeRFC822Message({
|
|
18
|
+
to,
|
|
19
|
+
subject,
|
|
19
20
|
body,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
cc,
|
|
22
|
+
bcc,
|
|
23
|
+
});
|
|
24
|
+
const payload = {
|
|
25
|
+
raw: encodedMessage,
|
|
26
|
+
};
|
|
27
|
+
if (threadId) {
|
|
28
|
+
payload.threadId = threadId;
|
|
29
|
+
}
|
|
26
30
|
const response = await fetch('https://gmail.googleapis.com/gmail/v1/users/me/messages/send', {
|
|
27
31
|
method: 'POST',
|
|
28
32
|
headers: {
|
|
29
33
|
Authorization: `Bearer ${gmailToken}`,
|
|
30
34
|
'Content-Type': 'application/json',
|
|
31
35
|
},
|
|
32
|
-
body: JSON.stringify(
|
|
33
|
-
raw: encodedMessage,
|
|
34
|
-
}),
|
|
36
|
+
body: JSON.stringify(payload),
|
|
35
37
|
});
|
|
36
38
|
if (!response.ok) {
|
|
37
39
|
const error = await response.json();
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export declare const trashMessage: import("ai").Tool<{
|
|
2
|
+
id: string;
|
|
3
|
+
gmailToken?: string | undefined;
|
|
4
|
+
}, {
|
|
5
|
+
error: string;
|
|
6
|
+
details: any;
|
|
7
|
+
success?: undefined;
|
|
8
|
+
messageId?: undefined;
|
|
9
|
+
threadId?: undefined;
|
|
10
|
+
labelIds?: undefined;
|
|
11
|
+
message?: undefined;
|
|
12
|
+
} | {
|
|
13
|
+
success: boolean;
|
|
14
|
+
messageId: any;
|
|
15
|
+
threadId: any;
|
|
16
|
+
labelIds: any;
|
|
17
|
+
error?: undefined;
|
|
18
|
+
details?: undefined;
|
|
19
|
+
message?: undefined;
|
|
20
|
+
} | {
|
|
21
|
+
error: string;
|
|
22
|
+
message: string;
|
|
23
|
+
details?: undefined;
|
|
24
|
+
success?: undefined;
|
|
25
|
+
messageId?: undefined;
|
|
26
|
+
threadId?: undefined;
|
|
27
|
+
labelIds?: undefined;
|
|
28
|
+
}>;
|
|
29
|
+
//# sourceMappingURL=trash-message.d.ts.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { tool } from 'ai';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
export const trashMessage = tool({
|
|
4
|
+
description: 'Move a Gmail message to the Trash folder (safe recoverable deletion).',
|
|
5
|
+
inputSchema: z.object({
|
|
6
|
+
gmailToken: z.string().optional().describe('Injected by system; do not provide'),
|
|
7
|
+
id: z.string().describe('The ID of the message to move to Trash'),
|
|
8
|
+
}),
|
|
9
|
+
execute: async ({ gmailToken, id }) => {
|
|
10
|
+
try {
|
|
11
|
+
const response = await fetch(`https://gmail.googleapis.com/gmail/v1/users/me/messages/${id}/trash`, {
|
|
12
|
+
method: 'POST',
|
|
13
|
+
headers: {
|
|
14
|
+
Authorization: `Bearer ${gmailToken}`,
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
if (!response.ok) {
|
|
18
|
+
const error = await response.json();
|
|
19
|
+
return { error: 'Failed to trash message', details: error };
|
|
20
|
+
}
|
|
21
|
+
const data = await response.json();
|
|
22
|
+
return {
|
|
23
|
+
success: true,
|
|
24
|
+
messageId: data.id,
|
|
25
|
+
threadId: data.threadId,
|
|
26
|
+
labelIds: data.labelIds || [],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
return {
|
|
31
|
+
error: 'Error moving message to trash',
|
|
32
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
//# sourceMappingURL=trash-message.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export declare const untrashMessage: import("ai").Tool<{
|
|
2
|
+
id: string;
|
|
3
|
+
gmailToken?: string | undefined;
|
|
4
|
+
}, {
|
|
5
|
+
error: string;
|
|
6
|
+
details: any;
|
|
7
|
+
success?: undefined;
|
|
8
|
+
messageId?: undefined;
|
|
9
|
+
threadId?: undefined;
|
|
10
|
+
labelIds?: undefined;
|
|
11
|
+
message?: undefined;
|
|
12
|
+
} | {
|
|
13
|
+
success: boolean;
|
|
14
|
+
messageId: any;
|
|
15
|
+
threadId: any;
|
|
16
|
+
labelIds: any;
|
|
17
|
+
error?: undefined;
|
|
18
|
+
details?: undefined;
|
|
19
|
+
message?: undefined;
|
|
20
|
+
} | {
|
|
21
|
+
error: string;
|
|
22
|
+
message: string;
|
|
23
|
+
details?: undefined;
|
|
24
|
+
success?: undefined;
|
|
25
|
+
messageId?: undefined;
|
|
26
|
+
threadId?: undefined;
|
|
27
|
+
labelIds?: undefined;
|
|
28
|
+
}>;
|
|
29
|
+
//# sourceMappingURL=untrash-message.d.ts.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { tool } from 'ai';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
export const untrashMessage = tool({
|
|
4
|
+
description: 'Restore a Gmail message from the Trash folder back to the mailbox.',
|
|
5
|
+
inputSchema: z.object({
|
|
6
|
+
gmailToken: z.string().optional().describe('Injected by system; do not provide'),
|
|
7
|
+
id: z.string().describe('The ID of the message to restore from Trash'),
|
|
8
|
+
}),
|
|
9
|
+
execute: async ({ gmailToken, id }) => {
|
|
10
|
+
try {
|
|
11
|
+
const response = await fetch(`https://gmail.googleapis.com/gmail/v1/users/me/messages/${id}/untrash`, {
|
|
12
|
+
method: 'POST',
|
|
13
|
+
headers: {
|
|
14
|
+
Authorization: `Bearer ${gmailToken}`,
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
if (!response.ok) {
|
|
18
|
+
const error = await response.json();
|
|
19
|
+
return { error: 'Failed to untrash message', details: error };
|
|
20
|
+
}
|
|
21
|
+
const data = await response.json();
|
|
22
|
+
return {
|
|
23
|
+
success: true,
|
|
24
|
+
messageId: data.id,
|
|
25
|
+
threadId: data.threadId,
|
|
26
|
+
labelIds: data.labelIds || [],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
return {
|
|
31
|
+
error: 'Error restoring message from trash',
|
|
32
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
//# sourceMappingURL=untrash-message.js.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base64URL encodes a string in accordance with RFC 4648 §5.
|
|
3
|
+
*/
|
|
4
|
+
export declare function encodeBase64Url(str: string): string;
|
|
5
|
+
/**
|
|
6
|
+
* Base64URL decodes a string back to UTF-8.
|
|
7
|
+
*/
|
|
8
|
+
export declare function decodeBase64Url(data: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Encodes an email with standard RFC 2822 headers into Base64URL format.
|
|
11
|
+
*/
|
|
12
|
+
export declare function encodeRFC822Message(params: {
|
|
13
|
+
to: string;
|
|
14
|
+
subject: string;
|
|
15
|
+
body: string;
|
|
16
|
+
cc?: string;
|
|
17
|
+
bcc?: string;
|
|
18
|
+
inReplyTo?: string;
|
|
19
|
+
references?: string;
|
|
20
|
+
}): string;
|
|
21
|
+
/**
|
|
22
|
+
* Recursively extracts plain text (or HTML fallback) body from a Gmail message payload.
|
|
23
|
+
*/
|
|
24
|
+
export declare function extractBodyFromPayload(payload: any): string;
|
|
25
|
+
/**
|
|
26
|
+
* Extracts structured message details and headers from a Gmail message API response.
|
|
27
|
+
*/
|
|
28
|
+
export declare function extractMessageDetails(data: any, maxBodyLength?: number): {
|
|
29
|
+
id: any;
|
|
30
|
+
threadId: any;
|
|
31
|
+
labelIds: any;
|
|
32
|
+
snippet: any;
|
|
33
|
+
subject: any;
|
|
34
|
+
from: any;
|
|
35
|
+
to: any;
|
|
36
|
+
cc: any;
|
|
37
|
+
date: any;
|
|
38
|
+
messageIdHeader: any;
|
|
39
|
+
body: string;
|
|
40
|
+
} | null;
|
|
41
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/**
|
|
3
|
+
* Base64URL encodes a string in accordance with RFC 4648 §5.
|
|
4
|
+
*/
|
|
5
|
+
export function encodeBase64Url(str) {
|
|
6
|
+
return Buffer.from(str, 'utf-8')
|
|
7
|
+
.toString('base64')
|
|
8
|
+
.replace(/\+/g, '-')
|
|
9
|
+
.replace(/\//g, '_')
|
|
10
|
+
.replace(/=+$/, '');
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Base64URL decodes a string back to UTF-8.
|
|
14
|
+
*/
|
|
15
|
+
export function decodeBase64Url(data) {
|
|
16
|
+
const base64 = data.replace(/-/g, '+').replace(/_/g, '/');
|
|
17
|
+
return Buffer.from(base64, 'base64').toString('utf-8');
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Encodes an email with standard RFC 2822 headers into Base64URL format.
|
|
21
|
+
*/
|
|
22
|
+
export function encodeRFC822Message(params) {
|
|
23
|
+
const headerLines = [
|
|
24
|
+
`To: ${params.to}`,
|
|
25
|
+
params.cc ? `Cc: ${params.cc}` : null,
|
|
26
|
+
params.bcc ? `Bcc: ${params.bcc}` : null,
|
|
27
|
+
`Subject: ${params.subject}`,
|
|
28
|
+
params.inReplyTo ? `In-Reply-To: ${params.inReplyTo}` : null,
|
|
29
|
+
params.references ? `References: ${params.references}` : null,
|
|
30
|
+
'Content-Type: text/plain; charset="UTF-8"',
|
|
31
|
+
'MIME-Version: 1.0',
|
|
32
|
+
].filter(Boolean);
|
|
33
|
+
const raw = `${headerLines.join('\n')}\n\n${params.body}`;
|
|
34
|
+
return encodeBase64Url(raw);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Recursively extracts plain text (or HTML fallback) body from a Gmail message payload.
|
|
38
|
+
*/
|
|
39
|
+
export function extractBodyFromPayload(payload) {
|
|
40
|
+
if (!payload)
|
|
41
|
+
return '';
|
|
42
|
+
if (payload.body?.data) {
|
|
43
|
+
return decodeBase64Url(payload.body.data);
|
|
44
|
+
}
|
|
45
|
+
if (payload.parts && Array.isArray(payload.parts)) {
|
|
46
|
+
// Look for text/plain first
|
|
47
|
+
const plainPart = payload.parts.find((p) => p.mimeType === 'text/plain');
|
|
48
|
+
if (plainPart?.body?.data) {
|
|
49
|
+
return decodeBase64Url(plainPart.body.data);
|
|
50
|
+
}
|
|
51
|
+
// Check nested parts (multipart/alternative, multipart/mixed, etc.)
|
|
52
|
+
for (const part of payload.parts) {
|
|
53
|
+
if (part.parts) {
|
|
54
|
+
const nested = extractBodyFromPayload(part);
|
|
55
|
+
if (nested)
|
|
56
|
+
return nested;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Fallback to text/html if plain text not available
|
|
60
|
+
const htmlPart = payload.parts.find((p) => p.mimeType === 'text/html');
|
|
61
|
+
if (htmlPart?.body?.data) {
|
|
62
|
+
return decodeBase64Url(htmlPart.body.data);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return '';
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Extracts structured message details and headers from a Gmail message API response.
|
|
69
|
+
*/
|
|
70
|
+
export function extractMessageDetails(data, maxBodyLength = 4000) {
|
|
71
|
+
if (!data)
|
|
72
|
+
return null;
|
|
73
|
+
const headers = data.payload?.headers || [];
|
|
74
|
+
const getHeader = (name) => headers.find((h) => h.name.toLowerCase() === name.toLowerCase())?.value;
|
|
75
|
+
const subject = getHeader('subject');
|
|
76
|
+
const from = getHeader('from');
|
|
77
|
+
const to = getHeader('to');
|
|
78
|
+
const cc = getHeader('cc');
|
|
79
|
+
const date = getHeader('date');
|
|
80
|
+
const messageIdHeader = getHeader('message-id');
|
|
81
|
+
const rawBody = extractBodyFromPayload(data.payload);
|
|
82
|
+
const body = rawBody ? rawBody.substring(0, maxBodyLength) : '';
|
|
83
|
+
return {
|
|
84
|
+
id: data.id,
|
|
85
|
+
threadId: data.threadId,
|
|
86
|
+
labelIds: data.labelIds || [],
|
|
87
|
+
snippet: data.snippet,
|
|
88
|
+
subject,
|
|
89
|
+
from,
|
|
90
|
+
to,
|
|
91
|
+
cc,
|
|
92
|
+
date,
|
|
93
|
+
messageIdHeader,
|
|
94
|
+
body,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -5,7 +5,7 @@ import { googleCalendarTools } from './tools/index.js';
|
|
|
5
5
|
export default defineToolkit({
|
|
6
6
|
id: 'google-calendar',
|
|
7
7
|
displayName: 'Google Calendar',
|
|
8
|
-
shortDescription: 'List
|
|
8
|
+
shortDescription: 'List, search, create, update, and delete calendar events.',
|
|
9
9
|
category: 'Scheduling & Booking',
|
|
10
10
|
icon: GCAL_ICON,
|
|
11
11
|
auth: {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export declare const deleteEvent: import("ai").Tool<{
|
|
2
|
+
googleCalendarToken: string;
|
|
3
|
+
eventId: string;
|
|
4
|
+
calendarId: string;
|
|
5
|
+
}, {
|
|
6
|
+
error: string;
|
|
7
|
+
details: any;
|
|
8
|
+
success?: undefined;
|
|
9
|
+
eventId?: undefined;
|
|
10
|
+
calendarId?: undefined;
|
|
11
|
+
message?: undefined;
|
|
12
|
+
} | {
|
|
13
|
+
success: boolean;
|
|
14
|
+
eventId: string;
|
|
15
|
+
calendarId: string;
|
|
16
|
+
error?: undefined;
|
|
17
|
+
details?: undefined;
|
|
18
|
+
message?: undefined;
|
|
19
|
+
} | {
|
|
20
|
+
error: string;
|
|
21
|
+
message: string;
|
|
22
|
+
details?: undefined;
|
|
23
|
+
success?: undefined;
|
|
24
|
+
eventId?: undefined;
|
|
25
|
+
calendarId?: undefined;
|
|
26
|
+
}>;
|
|
27
|
+
//# sourceMappingURL=delete-event.d.ts.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { tool } from 'ai';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
export const deleteEvent = tool({
|
|
5
|
+
description: 'Delete or cancel an event from Google Calendar by event ID.',
|
|
6
|
+
inputSchema: z.object({
|
|
7
|
+
googleCalendarToken: z.string().describe('The Google Calendar access token'),
|
|
8
|
+
eventId: z.string().describe('The unique ID of the event to delete'),
|
|
9
|
+
calendarId: z.string().optional().default('primary').describe('Calendar identifier. Default is "primary".'),
|
|
10
|
+
}),
|
|
11
|
+
execute: async ({ googleCalendarToken, eventId, calendarId = 'primary' }) => {
|
|
12
|
+
try {
|
|
13
|
+
const url = `https://www.googleapis.com/calendar/v3/calendars/${encodeURIComponent(calendarId)}/events/${encodeURIComponent(eventId)}`;
|
|
14
|
+
const response = await fetch(url, {
|
|
15
|
+
method: 'DELETE',
|
|
16
|
+
headers: {
|
|
17
|
+
Authorization: `Bearer ${googleCalendarToken}`,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
if (!response.ok && response.status !== 204) {
|
|
21
|
+
const error = await response.json().catch(() => ({ status: response.status }));
|
|
22
|
+
return { error: 'Failed to delete event', details: error };
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
success: true,
|
|
26
|
+
eventId,
|
|
27
|
+
calendarId,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
return {
|
|
32
|
+
error: 'Error deleting event',
|
|
33
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
//# sourceMappingURL=delete-event.js.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare const getEvent: import("ai").Tool<{
|
|
2
|
+
googleCalendarToken: string;
|
|
3
|
+
eventId: string;
|
|
4
|
+
calendarId: string;
|
|
5
|
+
}, {
|
|
6
|
+
error: string;
|
|
7
|
+
details: any;
|
|
8
|
+
success?: undefined;
|
|
9
|
+
event?: undefined;
|
|
10
|
+
message?: undefined;
|
|
11
|
+
} | {
|
|
12
|
+
success: boolean;
|
|
13
|
+
event: any;
|
|
14
|
+
error?: undefined;
|
|
15
|
+
details?: undefined;
|
|
16
|
+
message?: undefined;
|
|
17
|
+
} | {
|
|
18
|
+
error: string;
|
|
19
|
+
message: string;
|
|
20
|
+
details?: undefined;
|
|
21
|
+
success?: undefined;
|
|
22
|
+
event?: undefined;
|
|
23
|
+
}>;
|
|
24
|
+
//# sourceMappingURL=get-event.d.ts.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { tool } from 'ai';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
export const getEvent = tool({
|
|
5
|
+
description: 'Get details of a specific event from Google Calendar by event ID.',
|
|
6
|
+
inputSchema: z.object({
|
|
7
|
+
googleCalendarToken: z.string().describe('The Google Calendar access token'),
|
|
8
|
+
eventId: z.string().describe('The unique ID of the event to retrieve'),
|
|
9
|
+
calendarId: z.string().optional().default('primary').describe('Calendar identifier. Default is "primary".'),
|
|
10
|
+
}),
|
|
11
|
+
execute: async ({ googleCalendarToken, eventId, calendarId = 'primary' }) => {
|
|
12
|
+
try {
|
|
13
|
+
const url = `https://www.googleapis.com/calendar/v3/calendars/${encodeURIComponent(calendarId)}/events/${encodeURIComponent(eventId)}`;
|
|
14
|
+
const response = await fetch(url, {
|
|
15
|
+
headers: {
|
|
16
|
+
Authorization: `Bearer ${googleCalendarToken}`,
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
if (!response.ok) {
|
|
20
|
+
const error = await response.json();
|
|
21
|
+
return { error: 'Failed to get event', details: error };
|
|
22
|
+
}
|
|
23
|
+
const data = await response.json();
|
|
24
|
+
return {
|
|
25
|
+
success: true,
|
|
26
|
+
event: data,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
return {
|
|
31
|
+
error: 'Error getting event',
|
|
32
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
//# sourceMappingURL=get-event.js.map
|