import PostalMime, { type RawEmail } from "postal-mime";
import { getAddress, incrementReceivedCounter } from "./db.ts";
import type { Dispatcher } from "./dispatch.ts";
import type { SqlExecutor } from "./storage.ts";
import type { OwnerRef, ParsedMail } from "./types.ts";
// Deliberately not Cloudflare's ForwardableEmailMessage: postal-mime already
// accepts every raw format either deployment target hands it (a Worker's
// ReadableStream, a Buffer from a self-hosted SMTP server), so this is the
// only shape core needs to know about.
export interface InboundMessage {
to: string;
from: string;
raw: RawEmail;
}
export async function handleInboundEmail(
message: InboundMessage,
db: SqlExecutor,
dispatcher: Dispatcher
): Promise<void> {
const recipient = message.to.toLowerCase();
const row = await getAddress(db, recipient);
const now = Math.floor(Date.now() / 1000);
if (!row || row.revoked !== 0 || (row.permanent !== 1 && row.expires_at <= now)) {
return;
}
const owner: OwnerRef = { type: row.owner_type, id: row.owner_id };
await incrementReceivedCounter(db);
const parsed = await PostalMime.parse(message.raw, { attachmentEncoding: "arraybuffer" });
const mail: ParsedMail = {
from: parsed.from?.address ?? message.from,
to: row.address,
subject: parsed.subject ?? "(no subject)",
text: parsed.text ?? "",
html: parsed.html,
attachments: parsed.attachments.map((a) => ({