code icon Code

Create Gmail Draft

Create a draft email in Gmail (does not send)

Source Code

import fs from "fs";

const [
  to = "",
  subject = "",
  body = "",
  threadId = "",
  outputPath = "session/draft-result.json",
] = process.argv.slice(2);

if (!to) {
  console.error("Recipient (to) is required");
  console.log(JSON.stringify({ success: false, error: "missing_recipient" }));
  process.exit(1);
}

if (!subject && !threadId) {
  console.error("Subject is required for new emails");
  console.log(JSON.stringify({ success: false, error: "missing_subject" }));
  process.exit(1);
}

console.log(`Creating draft to: ${to}`);
console.log(`Subject: ${subject || "(reply)"}`);

/**
 * Build RFC 2822 formatted email message
 */
function buildRawMessage(to, subject, body) {
  const lines = [
    `To: ${to}`,
    `Subject: ${subject}`,
    "Content-Type: text/plain; charset=utf-8",
    "",
    body,
  ];
  return Buffer.from(lines.join("\r\n"))
    .toString("base64")
    .replace(/\+/g, "-")
    .replace(/\//g, "_")
    .replace(/=+$/, "");
}

try {
  const raw = buildRawMessage(to, subject, body);

  const requestBody = {
    message: { raw },
  };

  if (threadId) {
    requestBody.message.threadId = threadId;
  }

  const res = await fetch(
    "https://gmail.googleapis.com/gmail/v1/users/me/drafts",
    {
      method: "POST",
      headers: {
        Authorization: "Bearer PLACEHOLDER_TOKEN",
        "Content-Type": "application/json",
      },
      body: JSON.stringify(requestBody),
    }
  );

  if (!res.ok) {
    const errorText = await res.text();
    console.error(`Gmail API error: ${res.status}`);
    console.error(errorText);
    throw new Error(`Failed to create draft: ${res.status}`);
  }

  const draft = await res.json();

  // Write result
  const dir = outputPath.split("/").slice(0, -1).join("/");
  if (dir) fs.mkdirSync(dir, { recursive: true });

  const output = {
    success: true,
    createdAt: new Date().toISOString(),
    draftId: draft.id,
    messageId: draft.message?.id,
    threadId: draft.message?.threadId,
    to,
    subject,
  };

  fs.writeFileSync(outputPath, JSON.stringify(output, null, 2));

  console.log(`\nāœ“ Draft created`);
  console.log(`  Draft ID: ${draft.id}`);
  console.log(`  Open Gmail to review and send.`);

  console.log(JSON.stringify(output));
} catch (error) {
  console.error("Failed to create draft:", error.message);
  throw error;
}