code icon Code

Parse Email

Parse .eml files into structured data

Source Code

import fs from "fs";
import path from "path";
import { simpleParser } from "mailparser";

const [inputPath, outputPath, extractAttachments = "false"] = process.argv.slice(2);

if (!inputPath || !outputPath) {
  console.error("Usage: inputPath outputPath [extractAttachments]");
  process.exit(1);
}

try {
  console.log(`Parsing email: ${inputPath}...`);
  const emlContent = fs.readFileSync(inputPath);

  const parsed = await simpleParser(emlContent);

  const result = {
    from: parsed.from?.value || null,
    to: parsed.to?.value || null,
    cc: parsed.cc?.value || null,
    bcc: parsed.bcc?.value || null,
    subject: parsed.subject || null,
    date: parsed.date?.toISOString() || null,
    messageId: parsed.messageId || null,
    inReplyTo: parsed.inReplyTo || null,
    text: parsed.text || null,
    html: parsed.html || null,
    attachments: [],
  };

  // Handle attachments
  if (parsed.attachments && parsed.attachments.length > 0) {
    const attachmentsDir = path.join(path.dirname(outputPath), "attachments");

    for (const attachment of parsed.attachments) {
      const attachmentInfo = {
        filename: attachment.filename || "unnamed",
        contentType: attachment.contentType,
        size: attachment.size,
      };

      if (extractAttachments === "true" && attachment.content) {
        // Save attachment to disk
        fs.mkdirSync(attachmentsDir, { recursive: true });
        const attachmentPath = path.join(attachmentsDir, attachment.filename || `attachment-${result.attachments.length}`);
        fs.writeFileSync(attachmentPath, attachment.content);
        attachmentInfo.path = attachmentPath;
        console.log(`  Extracted: ${attachment.filename}`);
      }

      result.attachments.push(attachmentInfo);
    }
  }

  // Ensure output directory exists
  const dir = path.dirname(outputPath);
  if (dir && dir !== ".") {
    fs.mkdirSync(dir, { recursive: true });
  }

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

  console.log(`\nāœ“ Parsed email`);
  console.log(`  From: ${result.from?.[0]?.address || "unknown"}`);
  console.log(`  Subject: ${result.subject || "(no subject)"}`);
  console.log(`  Date: ${result.date || "unknown"}`);
  console.log(`  Attachments: ${result.attachments.length}`);
  console.log(`  Written to: ${outputPath}`);

  console.log(
    JSON.stringify({
      success: true,
      inputPath,
      outputPath,
      subject: result.subject,
      from: result.from?.[0]?.address,
      attachmentCount: result.attachments.length,
    })
  );
} catch (error) {
  console.error("Error:", error.message);
  process.exit(1);
}