mirror of
https://github.com/juherr/kill-the-news.git
synced 2026-06-20 22:03:48 +00:00
feat: add Cloudflare Email Workers support alongside ForwardEmail
Both email providers now work in parallel on the same Worker:
- ForwardEmail: existing POST /api/inbound webhook (unchanged)
- Cloudflare Email Routing: native `email` handler using postal-mime
New files:
- src/lib/email-processor.ts shared business logic (feed lookup,
sender allowlist, KV storage) extracted from inbound.ts
- src/lib/cloudflare-email.ts Cloudflare `email` handler; parses
raw RFC 2822 email with postal-mime, delegates to processEmail()
- src/lib/email-processor.test.ts 9 unit tests
- src/lib/cloudflare-email.test.ts 5 integration tests
Also fixes pre-existing CORS 204 response: c.text("", 204) →
c.body(null, 204) to match Hono's EmptyStatusCode constraint.
To enable: configure Cloudflare Email Routing with a catch-all rule
`*@domain.com` pointing to this Worker.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
import PostalMime from "postal-mime";
|
||||
import { Env } from "../types";
|
||||
import { processEmail } from "./email-processor";
|
||||
|
||||
export async function handleCloudflareEmail(
|
||||
message: ForwardableEmailMessage,
|
||||
env: Env,
|
||||
ctx: ExecutionContext,
|
||||
): Promise<void> {
|
||||
try {
|
||||
const email = await PostalMime.parse(message.raw);
|
||||
|
||||
const fromAddress = email.from?.address ?? message.from;
|
||||
const from =
|
||||
email.from?.name && email.from.address
|
||||
? `${email.from.name} <${email.from.address}>`
|
||||
: fromAddress;
|
||||
|
||||
const headers: Record<string, string> = {};
|
||||
for (const h of email.headers) {
|
||||
headers[h.key] = h.value;
|
||||
}
|
||||
|
||||
await processEmail(
|
||||
{
|
||||
toAddress: message.to,
|
||||
from,
|
||||
senders: [message.from],
|
||||
subject: email.subject ?? "(no subject)",
|
||||
content: email.html ?? email.text ?? "",
|
||||
receivedAt: email.date ? new Date(email.date).getTime() : Date.now(),
|
||||
headers,
|
||||
},
|
||||
env,
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("Error processing Cloudflare email:", error);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user