0

Create Draft

by
Published today

Save an unsent draft in Gmail, optionally as a reply in an existing thread.

Script gmail Verified

The script

Submitted by hugo989 Typescript (fetch-only)
Verified 4 hours ago
1
//native
2

3
/**
4
 * Create Draft
5
 * Save an unsent draft in the connected Gmail account. Set `is_html` to send `body` as HTML. To draft a reply, pass the original's `thread_id` and its `Message-ID` header as `in_reply_to` and keep the same subject.
6
 */
7
export async function main(
8
  auth: RT.Gmail,
9
  to: string,
10
  subject: string,
11
  body: string,
12
  cc: string | undefined,
13
  bcc: string | undefined,
14
  is_html: boolean = false,
15
  thread_id: string | undefined,
16
  in_reply_to: string | undefined
17
) {
18
  const headers = [
19
    `To: ${to}`,
20
    cc ? `Cc: ${cc}` : undefined,
21
    bcc ? `Bcc: ${bcc}` : undefined,
22
    `Subject: =?UTF-8?B?${base64(subject)}?=`,
23
    in_reply_to ? `In-Reply-To: ${in_reply_to}` : undefined,
24
    in_reply_to ? `References: ${in_reply_to}` : undefined,
25
    "MIME-Version: 1.0",
26
    `Content-Type: text/${is_html ? "html" : "plain"}; charset="UTF-8"`,
27
    "Content-Transfer-Encoding: base64",
28
  ].filter((h) => h !== undefined)
29
  const mime = `${headers.join("\r\n")}\r\n\r\n${base64(body)}`
30
  const raw = base64(mime).replace(/\+/g, "-").replace(/\//g, "_")
31

32
  const response = await fetch(
33
    "https://gmail.googleapis.com/gmail/v1/users/me/drafts",
34
    {
35
      method: "POST",
36
      headers: {
37
        Authorization: `Bearer ${auth.token}`,
38
        "Content-Type": "application/json",
39
        Accept: "application/json",
40
      },
41
      body: JSON.stringify({
42
        message: { raw, threadId: thread_id || undefined },
43
      }),
44
    }
45
  )
46
  if (!response.ok) {
47
    throw new Error(`${response.status} ${await response.text()}`)
48
  }
49

50
  return await response.json()
51
}
52

53
function base64(s: string) {
54
  const bytes = new TextEncoder().encode(s)
55
  let binary = ""
56
  for (const b of bytes) binary += String.fromCharCode(b)
57
  return btoa(binary)
58
}
59