1 | |
2 |
|
3 | |
4 | * Get Message |
5 | * Get a Gmail message by ID. With the default `full` format the decoded plain-text body is added as `body_text` (falling back to the HTML body when there is no plain-text part). |
6 | */ |
7 | export async function main( |
8 | auth: RT.Gmail, |
9 | message_id: string, |
10 | format: "full" | "metadata" | "minimal" | "raw" = "full" |
11 | ) { |
12 | const url = new URL( |
13 | `https://gmail.googleapis.com/gmail/v1/users/me/messages/${message_id}` |
14 | ) |
15 | url.searchParams.append("format", format) |
16 |
|
17 | const response = await fetch(url, { |
18 | headers: { |
19 | Authorization: `Bearer ${auth.token}`, |
20 | Accept: "application/json", |
21 | }, |
22 | }) |
23 | if (!response.ok) { |
24 | throw new Error(`${response.status} ${await response.text()}`) |
25 | } |
26 |
|
27 | const message = await response.json() |
28 | if (message.payload) { |
29 | message.body_text = |
30 | findBody(message.payload, "text/plain") ?? |
31 | findBody(message.payload, "text/html") |
32 | } |
33 | return message |
34 | } |
35 |
|
36 | type Part = { mimeType: string; body?: { data?: string }; parts?: Part[] } |
37 |
|
38 | function findBody(part: Part, mimeType: string): string | undefined { |
39 | if (part.mimeType === mimeType && part.body?.data) { |
40 | const b64 = part.body.data.replace(/-/g, "+").replace(/_/g, "/") |
41 | return new TextDecoder().decode( |
42 | Uint8Array.from(atob(b64), (c) => c.charCodeAt(0)) |
43 | ) |
44 | } |
45 | for (const p of part.parts ?? []) { |
46 | const found = findBody(p, mimeType) |
47 | if (found !== undefined) return found |
48 | } |
49 | } |
50 |
|