@marcfargas/go-easy 0.0.1 → 0.3.0
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/CHANGELOG.md +90 -0
- package/LICENSE +21 -0
- package/README.md +224 -0
- package/dist/auth-flow.d.ts +50 -0
- package/dist/auth-flow.d.ts.map +1 -0
- package/dist/auth-flow.js +219 -0
- package/dist/auth-flow.js.map +1 -0
- package/dist/auth-server.d.ts +18 -0
- package/dist/auth-server.d.ts.map +1 -0
- package/dist/auth-server.js +327 -0
- package/dist/auth-server.js.map +1 -0
- package/dist/auth-store.d.ts +81 -0
- package/dist/auth-store.d.ts.map +1 -0
- package/dist/auth-store.js +185 -0
- package/dist/auth-store.js.map +1 -0
- package/dist/auth.d.ts +47 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +131 -0
- package/dist/auth.js.map +1 -0
- package/dist/bin/calendar.d.ts +17 -0
- package/dist/bin/calendar.d.ts.map +1 -0
- package/dist/bin/calendar.js +224 -0
- package/dist/bin/calendar.js.map +1 -0
- package/dist/bin/drive.d.ts +18 -0
- package/dist/bin/drive.d.ts.map +1 -0
- package/dist/bin/drive.js +205 -0
- package/dist/bin/drive.js.map +1 -0
- package/dist/bin/easy.d.ts +11 -0
- package/dist/bin/easy.d.ts.map +1 -0
- package/dist/bin/easy.js +140 -0
- package/dist/bin/easy.js.map +1 -0
- package/dist/bin/gmail.d.ts +25 -0
- package/dist/bin/gmail.d.ts.map +1 -0
- package/dist/bin/gmail.js +243 -0
- package/dist/bin/gmail.js.map +1 -0
- package/dist/bin/tasks.d.ts +17 -0
- package/dist/bin/tasks.d.ts.map +1 -0
- package/dist/bin/tasks.js +190 -0
- package/dist/bin/tasks.js.map +1 -0
- package/dist/calendar/helpers.d.ts +35 -0
- package/dist/calendar/helpers.d.ts.map +1 -0
- package/dist/calendar/helpers.js +178 -0
- package/dist/calendar/helpers.js.map +1 -0
- package/dist/calendar/index.d.ts +64 -0
- package/dist/calendar/index.d.ts.map +1 -0
- package/dist/calendar/index.js +210 -0
- package/dist/calendar/index.js.map +1 -0
- package/dist/calendar/types.d.ts +191 -0
- package/dist/calendar/types.d.ts.map +1 -0
- package/dist/calendar/types.js +12 -0
- package/dist/calendar/types.js.map +1 -0
- package/dist/drive/helpers.d.ts +22 -0
- package/dist/drive/helpers.d.ts.map +1 -0
- package/dist/drive/helpers.js +85 -0
- package/dist/drive/helpers.js.map +1 -0
- package/dist/drive/index.d.ts +114 -0
- package/dist/drive/index.d.ts.map +1 -0
- package/dist/drive/index.js +418 -0
- package/dist/drive/index.js.map +1 -0
- package/dist/drive/types.d.ts +91 -0
- package/dist/drive/types.d.ts.map +1 -0
- package/dist/drive/types.js +5 -0
- package/dist/drive/types.js.map +1 -0
- package/dist/errors.d.ts +58 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +73 -0
- package/dist/errors.js.map +1 -0
- package/dist/gmail/helpers.d.ts +59 -0
- package/dist/gmail/helpers.d.ts.map +1 -0
- package/dist/gmail/helpers.js +308 -0
- package/dist/gmail/helpers.js.map +1 -0
- package/dist/gmail/index.d.ts +95 -0
- package/dist/gmail/index.d.ts.map +1 -0
- package/dist/gmail/index.js +465 -0
- package/dist/gmail/index.js.map +1 -0
- package/dist/gmail/markdown.d.ts +22 -0
- package/dist/gmail/markdown.d.ts.map +1 -0
- package/dist/gmail/markdown.js +30 -0
- package/dist/gmail/markdown.js.map +1 -0
- package/dist/gmail/types.d.ts +154 -0
- package/dist/gmail/types.d.ts.map +1 -0
- package/dist/gmail/types.js +5 -0
- package/dist/gmail/types.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/safety.d.ts +58 -0
- package/dist/safety.d.ts.map +1 -0
- package/dist/safety.js +61 -0
- package/dist/safety.js.map +1 -0
- package/dist/scopes.d.ts +16 -0
- package/dist/scopes.d.ts.map +1 -0
- package/dist/scopes.js +28 -0
- package/dist/scopes.js.map +1 -0
- package/dist/tasks/helpers.d.ts +10 -0
- package/dist/tasks/helpers.d.ts.map +1 -0
- package/dist/tasks/helpers.js +33 -0
- package/dist/tasks/helpers.js.map +1 -0
- package/dist/tasks/index.d.ts +63 -0
- package/dist/tasks/index.d.ts.map +1 -0
- package/dist/tasks/index.js +253 -0
- package/dist/tasks/index.js.map +1 -0
- package/dist/tasks/types.d.ts +79 -0
- package/dist/tasks/types.d.ts.map +1 -0
- package/dist/tasks/types.js +5 -0
- package/dist/tasks/types.js.map +1 -0
- package/package.json +73 -4
- package/skills/go-easy/SKILL.md +146 -0
- package/skills/go-easy/calendar.md +366 -0
- package/skills/go-easy/drive.md +309 -0
- package/skills/go-easy/gmail.md +478 -0
- package/skills/go-easy/tasks.md +260 -0
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gmail module — search, read, send, reply, forward, labels, drafts.
|
|
3
|
+
*
|
|
4
|
+
* All functions take an OAuth2Client as first argument.
|
|
5
|
+
* Use `getAuth('gmail', 'account@email.com')` from the auth module.
|
|
6
|
+
*/
|
|
7
|
+
import { gmail } from '@googleapis/gmail';
|
|
8
|
+
import { guardOperation } from '../safety.js';
|
|
9
|
+
import { NotFoundError, QuotaError, GoEasyError } from '../errors.js';
|
|
10
|
+
import { parseMessage, buildMimeMessage, buildForwardMime, base64UrlEncode } from './helpers.js';
|
|
11
|
+
import { markdownToHtml } from './markdown.js';
|
|
12
|
+
export { markdownToHtml } from './markdown.js';
|
|
13
|
+
/**
|
|
14
|
+
* Resolve markdown field to html. If html is already set, markdown is ignored.
|
|
15
|
+
* Also sets body from markdown source if body is not provided.
|
|
16
|
+
*/
|
|
17
|
+
function resolveMarkdown(opts) {
|
|
18
|
+
if (opts.markdown && !opts.html) {
|
|
19
|
+
return {
|
|
20
|
+
...opts,
|
|
21
|
+
html: markdownToHtml(opts.markdown),
|
|
22
|
+
body: opts.body ?? opts.markdown, // plain text fallback = raw markdown
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
return opts;
|
|
26
|
+
}
|
|
27
|
+
/** Get a Gmail API client instance */
|
|
28
|
+
function gmailApi(auth) {
|
|
29
|
+
return gmail({ version: 'v1', auth });
|
|
30
|
+
}
|
|
31
|
+
/** Wrap Google API errors into our error types */
|
|
32
|
+
function handleApiError(err, context) {
|
|
33
|
+
if (err instanceof GoEasyError)
|
|
34
|
+
throw err;
|
|
35
|
+
const gErr = err;
|
|
36
|
+
if (gErr.code === 404)
|
|
37
|
+
throw new NotFoundError('message', context, err);
|
|
38
|
+
if (gErr.code === 429)
|
|
39
|
+
throw new QuotaError('gmail', err);
|
|
40
|
+
throw new GoEasyError(`Gmail ${context}: ${gErr.message ?? 'Unknown error'}`, 'GMAIL_ERROR', err);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Get the authenticated user's email address.
|
|
44
|
+
*/
|
|
45
|
+
export async function getProfile(auth) {
|
|
46
|
+
const gmail = gmailApi(auth);
|
|
47
|
+
const res = await gmail.users.getProfile({ userId: 'me' });
|
|
48
|
+
return res.data.emailAddress ?? '';
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Search messages using Gmail query syntax.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* const results = await search(auth, { query: 'from:client is:unread' });
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export async function search(auth, opts) {
|
|
59
|
+
const gmail = gmailApi(auth);
|
|
60
|
+
try {
|
|
61
|
+
const listRes = await gmail.users.messages.list({
|
|
62
|
+
userId: 'me',
|
|
63
|
+
q: opts.query,
|
|
64
|
+
maxResults: opts.maxResults ?? 20,
|
|
65
|
+
pageToken: opts.pageToken,
|
|
66
|
+
includeSpamTrash: opts.includeSpamTrash ?? false,
|
|
67
|
+
});
|
|
68
|
+
const messageRefs = listRes.data.messages ?? [];
|
|
69
|
+
// Fetch full message data for each result
|
|
70
|
+
const messages = await Promise.all(messageRefs.map(async (ref) => {
|
|
71
|
+
const msg = await gmail.users.messages.get({
|
|
72
|
+
userId: 'me',
|
|
73
|
+
id: ref.id,
|
|
74
|
+
format: 'full',
|
|
75
|
+
});
|
|
76
|
+
return parseMessage(msg.data);
|
|
77
|
+
}));
|
|
78
|
+
return {
|
|
79
|
+
items: messages,
|
|
80
|
+
nextPageToken: listRes.data.nextPageToken ?? undefined,
|
|
81
|
+
resultSizeEstimate: listRes.data.resultSizeEstimate ?? undefined,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
handleApiError(err, `search "${opts.query}"`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Get a single message by ID.
|
|
90
|
+
*/
|
|
91
|
+
export async function getMessage(auth, messageId) {
|
|
92
|
+
const gmail = gmailApi(auth);
|
|
93
|
+
try {
|
|
94
|
+
const res = await gmail.users.messages.get({
|
|
95
|
+
userId: 'me',
|
|
96
|
+
id: messageId,
|
|
97
|
+
format: 'full',
|
|
98
|
+
});
|
|
99
|
+
return parseMessage(res.data);
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
handleApiError(err, messageId);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get a thread (conversation) by ID.
|
|
107
|
+
*/
|
|
108
|
+
export async function getThread(auth, threadId) {
|
|
109
|
+
const gmail = gmailApi(auth);
|
|
110
|
+
try {
|
|
111
|
+
const res = await gmail.users.threads.get({
|
|
112
|
+
userId: 'me',
|
|
113
|
+
id: threadId,
|
|
114
|
+
format: 'full',
|
|
115
|
+
});
|
|
116
|
+
const messages = (res.data.messages ?? []).map(parseMessage);
|
|
117
|
+
return {
|
|
118
|
+
id: res.data.id ?? threadId,
|
|
119
|
+
snippet: res.data.snippet ?? '',
|
|
120
|
+
messages,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
handleApiError(err, threadId);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Send an email.
|
|
129
|
+
*
|
|
130
|
+
* ⚠️ DESTRUCTIVE — requires safety confirmation.
|
|
131
|
+
*/
|
|
132
|
+
export async function send(auth, opts) {
|
|
133
|
+
const to = Array.isArray(opts.to) ? opts.to.join(', ') : opts.to;
|
|
134
|
+
await guardOperation({
|
|
135
|
+
name: 'gmail.send',
|
|
136
|
+
level: 'DESTRUCTIVE',
|
|
137
|
+
description: `Send email to ${to}: "${opts.subject}"`,
|
|
138
|
+
details: { to: opts.to, subject: opts.subject },
|
|
139
|
+
});
|
|
140
|
+
const gmail = gmailApi(auth);
|
|
141
|
+
const from = await getProfile(auth);
|
|
142
|
+
// Resolve markdown → html (html takes precedence if both set)
|
|
143
|
+
const resolvedOpts = resolveMarkdown(opts);
|
|
144
|
+
const mime = await buildMimeMessage(from, resolvedOpts);
|
|
145
|
+
const raw = base64UrlEncode(mime);
|
|
146
|
+
try {
|
|
147
|
+
const res = await gmail.users.messages.send({
|
|
148
|
+
userId: 'me',
|
|
149
|
+
requestBody: { raw },
|
|
150
|
+
});
|
|
151
|
+
return {
|
|
152
|
+
ok: true,
|
|
153
|
+
id: res.data.id ?? '',
|
|
154
|
+
threadId: res.data.threadId ?? undefined,
|
|
155
|
+
labelIds: res.data.labelIds ?? undefined,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
handleApiError(err, 'send');
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Reply to a thread.
|
|
164
|
+
*
|
|
165
|
+
* ⚠️ DESTRUCTIVE — requires safety confirmation.
|
|
166
|
+
*/
|
|
167
|
+
export async function reply(auth, opts) {
|
|
168
|
+
await guardOperation({
|
|
169
|
+
name: 'gmail.reply',
|
|
170
|
+
level: 'DESTRUCTIVE',
|
|
171
|
+
description: `Reply to thread ${opts.threadId}`,
|
|
172
|
+
details: { threadId: opts.threadId, messageId: opts.messageId },
|
|
173
|
+
});
|
|
174
|
+
const gmail = gmailApi(auth);
|
|
175
|
+
const from = await getProfile(auth);
|
|
176
|
+
// Get the original message for threading headers and recipients
|
|
177
|
+
const original = await getMessage(auth, opts.messageId);
|
|
178
|
+
const replyTo = opts.replyAll
|
|
179
|
+
? [...new Set([original.from, ...original.to, ...original.cc])].filter((addr) => !addr.includes(from))
|
|
180
|
+
: [original.from];
|
|
181
|
+
const sendOpts = resolveMarkdown({
|
|
182
|
+
to: replyTo,
|
|
183
|
+
subject: original.subject.startsWith('Re:')
|
|
184
|
+
? original.subject
|
|
185
|
+
: `Re: ${original.subject}`,
|
|
186
|
+
body: opts.body,
|
|
187
|
+
html: opts.html,
|
|
188
|
+
markdown: opts.markdown,
|
|
189
|
+
attachments: opts.attachments,
|
|
190
|
+
});
|
|
191
|
+
// Use the proper RFC 2822 Message-ID header if available, fall back to Gmail internal ID
|
|
192
|
+
const messageIdRef = original.rfc822MessageId ?? `<${opts.messageId}>`;
|
|
193
|
+
const extraHeaders = {
|
|
194
|
+
'In-Reply-To': messageIdRef,
|
|
195
|
+
References: messageIdRef,
|
|
196
|
+
};
|
|
197
|
+
const mime = await buildMimeMessage(from, sendOpts, extraHeaders);
|
|
198
|
+
const raw = base64UrlEncode(mime);
|
|
199
|
+
try {
|
|
200
|
+
const res = await gmail.users.messages.send({
|
|
201
|
+
userId: 'me',
|
|
202
|
+
requestBody: {
|
|
203
|
+
raw,
|
|
204
|
+
threadId: opts.threadId,
|
|
205
|
+
},
|
|
206
|
+
});
|
|
207
|
+
return {
|
|
208
|
+
ok: true,
|
|
209
|
+
id: res.data.id ?? '',
|
|
210
|
+
threadId: res.data.threadId ?? undefined,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
catch (err) {
|
|
214
|
+
handleApiError(err, 'reply');
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Forward a message to new recipients.
|
|
219
|
+
*
|
|
220
|
+
* Fetches the original message, quotes its body, and re-attaches attachments.
|
|
221
|
+
* By default creates a **draft** (WRITE, no safety gate). Use `sendNow: true`
|
|
222
|
+
* to send immediately (⚠️ DESTRUCTIVE — requires safety confirmation).
|
|
223
|
+
*
|
|
224
|
+
* Supports keeping in thread, filtering attachments by include/exclude
|
|
225
|
+
* lists, and markdown/html bodies.
|
|
226
|
+
*/
|
|
227
|
+
export async function forward(auth, opts) {
|
|
228
|
+
const to = Array.isArray(opts.to) ? opts.to.join(', ') : opts.to;
|
|
229
|
+
if (opts.sendNow) {
|
|
230
|
+
await guardOperation({
|
|
231
|
+
name: 'gmail.forward',
|
|
232
|
+
level: 'DESTRUCTIVE',
|
|
233
|
+
description: `Forward message ${opts.messageId} to ${to}`,
|
|
234
|
+
details: { messageId: opts.messageId, to: opts.to },
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
const gmail = gmailApi(auth);
|
|
238
|
+
const from = await getProfile(auth);
|
|
239
|
+
// Fetch original message
|
|
240
|
+
const original = await getMessage(auth, opts.messageId);
|
|
241
|
+
// Resolve which attachments to include
|
|
242
|
+
const bufferAttachments = [];
|
|
243
|
+
if (opts.includeAttachments !== false && original.attachments.length > 0) {
|
|
244
|
+
const includeList = Array.isArray(opts.includeAttachments)
|
|
245
|
+
? opts.includeAttachments
|
|
246
|
+
: undefined;
|
|
247
|
+
const excludeList = opts.excludeAttachments ?? [];
|
|
248
|
+
for (const att of original.attachments) {
|
|
249
|
+
// If include list provided, only include matching filenames
|
|
250
|
+
if (includeList && !includeList.some((f) => att.filename.includes(f)))
|
|
251
|
+
continue;
|
|
252
|
+
// Exclude matching filenames
|
|
253
|
+
if (excludeList.some((f) => att.filename.includes(f)))
|
|
254
|
+
continue;
|
|
255
|
+
const data = await getAttachmentContent(auth, opts.messageId, att.id);
|
|
256
|
+
bufferAttachments.push({
|
|
257
|
+
filename: att.filename,
|
|
258
|
+
mimeType: att.mimeType,
|
|
259
|
+
data,
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
const subject = original.subject.startsWith('Fwd:')
|
|
264
|
+
? original.subject
|
|
265
|
+
: `Fwd: ${original.subject}`;
|
|
266
|
+
// Resolve markdown → html
|
|
267
|
+
const resolved = resolveMarkdown(opts);
|
|
268
|
+
const keepInThread = opts.keepInThread !== false; // default true
|
|
269
|
+
const mime = await buildForwardMime(from, to, subject, resolved.body, original.body, bufferAttachments, undefined, resolved.html);
|
|
270
|
+
const raw = base64UrlEncode(mime);
|
|
271
|
+
if (!opts.sendNow) {
|
|
272
|
+
try {
|
|
273
|
+
const res = await gmail.users.drafts.create({
|
|
274
|
+
userId: 'me',
|
|
275
|
+
requestBody: {
|
|
276
|
+
message: {
|
|
277
|
+
raw,
|
|
278
|
+
threadId: keepInThread ? original.threadId : undefined,
|
|
279
|
+
},
|
|
280
|
+
},
|
|
281
|
+
});
|
|
282
|
+
return {
|
|
283
|
+
ok: true,
|
|
284
|
+
id: res.data.id ?? '',
|
|
285
|
+
threadId: original.threadId,
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
catch (err) {
|
|
289
|
+
handleApiError(err, 'forward (draft)');
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
try {
|
|
293
|
+
const res = await gmail.users.messages.send({
|
|
294
|
+
userId: 'me',
|
|
295
|
+
requestBody: {
|
|
296
|
+
raw,
|
|
297
|
+
threadId: keepInThread ? original.threadId : undefined,
|
|
298
|
+
},
|
|
299
|
+
});
|
|
300
|
+
return {
|
|
301
|
+
ok: true,
|
|
302
|
+
id: res.data.id ?? '',
|
|
303
|
+
threadId: res.data.threadId ?? undefined,
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
catch (err) {
|
|
307
|
+
handleApiError(err, 'forward');
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Batch modify labels on multiple messages.
|
|
312
|
+
*
|
|
313
|
+
* This is a WRITE operation (reversible), no safety gate.
|
|
314
|
+
*/
|
|
315
|
+
export async function batchModifyLabels(auth, opts) {
|
|
316
|
+
const gmail = gmailApi(auth);
|
|
317
|
+
try {
|
|
318
|
+
await gmail.users.messages.batchModify({
|
|
319
|
+
userId: 'me',
|
|
320
|
+
requestBody: {
|
|
321
|
+
ids: opts.messageIds,
|
|
322
|
+
addLabelIds: opts.addLabelIds,
|
|
323
|
+
removeLabelIds: opts.removeLabelIds,
|
|
324
|
+
},
|
|
325
|
+
});
|
|
326
|
+
return {
|
|
327
|
+
ok: true,
|
|
328
|
+
id: `batch:${opts.messageIds.length}`,
|
|
329
|
+
labelIds: opts.addLabelIds,
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
catch (err) {
|
|
333
|
+
handleApiError(err, 'batchModifyLabels');
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* List all labels for the account.
|
|
338
|
+
*/
|
|
339
|
+
export async function listLabels(auth) {
|
|
340
|
+
const gmail = gmailApi(auth);
|
|
341
|
+
try {
|
|
342
|
+
const res = await gmail.users.labels.list({ userId: 'me' });
|
|
343
|
+
return (res.data.labels ?? []).map((l) => ({
|
|
344
|
+
id: l.id ?? '',
|
|
345
|
+
name: l.name ?? '',
|
|
346
|
+
type: l.type ?? '',
|
|
347
|
+
}));
|
|
348
|
+
}
|
|
349
|
+
catch (err) {
|
|
350
|
+
handleApiError(err, 'listLabels');
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Create a draft.
|
|
355
|
+
*
|
|
356
|
+
* WRITE operation (reversible), no safety gate.
|
|
357
|
+
*
|
|
358
|
+
* @param opts.threadId - Optional thread ID to place the draft in an existing thread
|
|
359
|
+
* @param opts.extraHeaders - Optional extra MIME headers (e.g. In-Reply-To, References)
|
|
360
|
+
*/
|
|
361
|
+
export async function createDraft(auth, opts) {
|
|
362
|
+
const gmail = gmailApi(auth);
|
|
363
|
+
const from = await getProfile(auth);
|
|
364
|
+
const resolvedOpts = resolveMarkdown(opts);
|
|
365
|
+
const mime = await buildMimeMessage(from, resolvedOpts, opts.extraHeaders);
|
|
366
|
+
const raw = base64UrlEncode(mime);
|
|
367
|
+
try {
|
|
368
|
+
const res = await gmail.users.drafts.create({
|
|
369
|
+
userId: 'me',
|
|
370
|
+
requestBody: {
|
|
371
|
+
message: {
|
|
372
|
+
raw,
|
|
373
|
+
threadId: opts.threadId,
|
|
374
|
+
},
|
|
375
|
+
},
|
|
376
|
+
});
|
|
377
|
+
return {
|
|
378
|
+
id: res.data.id ?? '',
|
|
379
|
+
message: parseMessage(res.data.message ?? {}),
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
catch (err) {
|
|
383
|
+
handleApiError(err, 'createDraft');
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Send an existing draft.
|
|
388
|
+
*
|
|
389
|
+
* ⚠️ DESTRUCTIVE — requires safety confirmation.
|
|
390
|
+
*/
|
|
391
|
+
export async function sendDraft(auth, draftId) {
|
|
392
|
+
await guardOperation({
|
|
393
|
+
name: 'gmail.sendDraft',
|
|
394
|
+
level: 'DESTRUCTIVE',
|
|
395
|
+
description: `Send draft ${draftId}`,
|
|
396
|
+
details: { draftId },
|
|
397
|
+
});
|
|
398
|
+
const gmail = gmailApi(auth);
|
|
399
|
+
try {
|
|
400
|
+
const res = await gmail.users.drafts.send({
|
|
401
|
+
userId: 'me',
|
|
402
|
+
requestBody: { id: draftId },
|
|
403
|
+
});
|
|
404
|
+
return {
|
|
405
|
+
ok: true,
|
|
406
|
+
id: res.data.id ?? '',
|
|
407
|
+
threadId: res.data.threadId ?? undefined,
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
catch (err) {
|
|
411
|
+
handleApiError(err, 'sendDraft');
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* List drafts.
|
|
416
|
+
*/
|
|
417
|
+
export async function listDrafts(auth, maxResults = 20, pageToken) {
|
|
418
|
+
const gmail = gmailApi(auth);
|
|
419
|
+
try {
|
|
420
|
+
const res = await gmail.users.drafts.list({
|
|
421
|
+
userId: 'me',
|
|
422
|
+
maxResults,
|
|
423
|
+
pageToken,
|
|
424
|
+
});
|
|
425
|
+
const drafts = await Promise.all((res.data.drafts ?? []).map(async (d) => {
|
|
426
|
+
const full = await gmail.users.drafts.get({
|
|
427
|
+
userId: 'me',
|
|
428
|
+
id: d.id,
|
|
429
|
+
format: 'full',
|
|
430
|
+
});
|
|
431
|
+
return {
|
|
432
|
+
id: full.data.id ?? '',
|
|
433
|
+
message: parseMessage(full.data.message ?? {}),
|
|
434
|
+
};
|
|
435
|
+
}));
|
|
436
|
+
return {
|
|
437
|
+
items: drafts,
|
|
438
|
+
nextPageToken: res.data.nextPageToken ?? undefined,
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
catch (err) {
|
|
442
|
+
handleApiError(err, 'listDrafts');
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Download an attachment's content as a Buffer.
|
|
447
|
+
*/
|
|
448
|
+
export async function getAttachmentContent(auth, messageId, attachmentId) {
|
|
449
|
+
const gmail = gmailApi(auth);
|
|
450
|
+
try {
|
|
451
|
+
const res = await gmail.users.messages.attachments.get({
|
|
452
|
+
userId: 'me',
|
|
453
|
+
messageId,
|
|
454
|
+
id: attachmentId,
|
|
455
|
+
});
|
|
456
|
+
const data = res.data.data;
|
|
457
|
+
if (!data)
|
|
458
|
+
throw new GoEasyError('Empty attachment data', 'GMAIL_ERROR');
|
|
459
|
+
return Buffer.from(data, 'base64url');
|
|
460
|
+
}
|
|
461
|
+
catch (err) {
|
|
462
|
+
handleApiError(err, `attachment ${attachmentId}`);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gmail/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown → HTML conversion for email bodies.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the `marked` library with email-safe defaults:
|
|
5
|
+
* - GitHub-flavored markdown (tables, strikethrough, etc.)
|
|
6
|
+
* - Inline HTML wrapper with basic email-safe styling
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Convert a Markdown string to HTML suitable for email.
|
|
10
|
+
*
|
|
11
|
+
* Returns a complete HTML fragment with minimal inline styling
|
|
12
|
+
* for consistent rendering across email clients.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { markdownToHtml } from '@marcfargas/go-easy/gmail';
|
|
17
|
+
*
|
|
18
|
+
* const html = markdownToHtml('# Hello\n\nThis is **bold** and _italic_.');
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function markdownToHtml(md: string): string;
|
|
22
|
+
//# sourceMappingURL=markdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/gmail/markdown.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAQjD"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown → HTML conversion for email bodies.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the `marked` library with email-safe defaults:
|
|
5
|
+
* - GitHub-flavored markdown (tables, strikethrough, etc.)
|
|
6
|
+
* - Inline HTML wrapper with basic email-safe styling
|
|
7
|
+
*/
|
|
8
|
+
import { marked } from 'marked';
|
|
9
|
+
/**
|
|
10
|
+
* Convert a Markdown string to HTML suitable for email.
|
|
11
|
+
*
|
|
12
|
+
* Returns a complete HTML fragment with minimal inline styling
|
|
13
|
+
* for consistent rendering across email clients.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* import { markdownToHtml } from '@marcfargas/go-easy/gmail';
|
|
18
|
+
*
|
|
19
|
+
* const html = markdownToHtml('# Hello\n\nThis is **bold** and _italic_.');
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export function markdownToHtml(md) {
|
|
23
|
+
const body = marked.parse(md, { async: false, gfm: true, breaks: true });
|
|
24
|
+
return [
|
|
25
|
+
'<div style="font-family: -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, sans-serif; font-size: 14px; line-height: 1.5; color: #222;">',
|
|
26
|
+
body,
|
|
27
|
+
'</div>',
|
|
28
|
+
].join('\n');
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/gmail/markdown.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,cAAc,CAAC,EAAU;IACvC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAW,CAAC;IAEnF,OAAO;QACL,iJAAiJ;QACjJ,IAAI;QACJ,QAAQ;KACT,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
|