mirror of
https://github.com/juherr/kill-the-news.git
synced 2026-06-20 22:03:48 +00:00
refactor: extract ForwardEmail adapter to src/lib/forwardemail.ts
Mirrors the same pattern as cloudflare-email.ts — each provider has its own adapter that translates provider-specific input into ProcessEmailInput and delegates to processEmail(). inbound.ts is now a thin HTTP handler. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
import { EmailParser } from "../utils/email-parser";
|
||||
import { Env } from "../types";
|
||||
import { processEmail } from "./email-processor";
|
||||
|
||||
export interface ForwardEmailPayload {
|
||||
recipients?: string[];
|
||||
from?: {
|
||||
value?: Array<{ address?: string; name?: string }>;
|
||||
text?: string;
|
||||
html?: string;
|
||||
};
|
||||
subject?: string;
|
||||
text?: string;
|
||||
html?: string;
|
||||
date?: string;
|
||||
messageId?: string;
|
||||
headerLines?: Array<{ key: string; line: string }>;
|
||||
headers?: string;
|
||||
raw?: string;
|
||||
attachments?: Array<any>;
|
||||
}
|
||||
|
||||
function normalizeEmail(value: string): string {
|
||||
return value.trim().toLowerCase();
|
||||
}
|
||||
|
||||
function extractSenderAddresses(payload: ForwardEmailPayload): string[] {
|
||||
const valueEntries = payload.from?.value || [];
|
||||
const structuredAddresses = valueEntries
|
||||
.map((entry) => entry.address || "")
|
||||
.map(normalizeEmail)
|
||||
.filter(Boolean);
|
||||
|
||||
if (structuredAddresses.length > 0) {
|
||||
return Array.from(new Set(structuredAddresses));
|
||||
}
|
||||
|
||||
const fromText = payload.from?.text || "";
|
||||
const matches =
|
||||
fromText.match(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/gi) || [];
|
||||
return Array.from(new Set(matches.map(normalizeEmail)));
|
||||
}
|
||||
|
||||
export async function handleForwardEmail(
|
||||
payload: ForwardEmailPayload,
|
||||
env: Env,
|
||||
): Promise<Response> {
|
||||
const emailData = EmailParser.parseForwardEmailPayload(payload);
|
||||
|
||||
return processEmail(
|
||||
{
|
||||
toAddress: payload.recipients?.[0] || "",
|
||||
from: emailData.from,
|
||||
senders: extractSenderAddresses(payload),
|
||||
subject: emailData.subject,
|
||||
content: emailData.content,
|
||||
receivedAt: emailData.receivedAt,
|
||||
headers: emailData.headers,
|
||||
},
|
||||
env,
|
||||
);
|
||||
}
|
||||
+5
-53
@@ -1,44 +1,9 @@
|
||||
import { Context } from "hono";
|
||||
import { EmailParser } from "../utils/email-parser";
|
||||
import { Env } from "../types";
|
||||
import { processEmail } from "../lib/email-processor";
|
||||
|
||||
interface ForwardEmailPayload {
|
||||
recipients?: string[];
|
||||
from?: {
|
||||
value?: Array<{ address?: string; name?: string }>;
|
||||
text?: string;
|
||||
html?: string;
|
||||
};
|
||||
subject?: string;
|
||||
text?: string;
|
||||
html?: string;
|
||||
date?: string;
|
||||
messageId?: string;
|
||||
headerLines?: Array<{ key: string; line: string }>;
|
||||
headers?: string;
|
||||
raw?: string;
|
||||
attachments?: Array<any>;
|
||||
}
|
||||
|
||||
function extractIncomingSenderAddresses(
|
||||
payload: ForwardEmailPayload,
|
||||
): string[] {
|
||||
const valueEntries = payload.from?.value || [];
|
||||
const structuredAddresses = valueEntries
|
||||
.map((entry) => entry.address || "")
|
||||
.map((v) => v.trim().toLowerCase())
|
||||
.filter(Boolean);
|
||||
|
||||
if (structuredAddresses.length > 0) {
|
||||
return Array.from(new Set(structuredAddresses));
|
||||
}
|
||||
|
||||
const fromText = payload.from?.text || "";
|
||||
const matches =
|
||||
fromText.match(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/gi) || [];
|
||||
return Array.from(new Set(matches.map((v) => v.trim().toLowerCase())));
|
||||
}
|
||||
import {
|
||||
ForwardEmailPayload,
|
||||
handleForwardEmail,
|
||||
} from "../lib/forwardemail";
|
||||
|
||||
export async function handle(c: Context): Promise<Response> {
|
||||
try {
|
||||
@@ -52,20 +17,7 @@ export async function handle(c: Context): Promise<Response> {
|
||||
contentType: payload.html ? "HTML" : "Text",
|
||||
});
|
||||
|
||||
const emailData = EmailParser.parseForwardEmailPayload(payload);
|
||||
|
||||
return processEmail(
|
||||
{
|
||||
toAddress: payload.recipients?.[0] || "",
|
||||
from: emailData.from,
|
||||
senders: extractIncomingSenderAddresses(payload),
|
||||
subject: emailData.subject,
|
||||
content: emailData.content,
|
||||
receivedAt: emailData.receivedAt,
|
||||
headers: emailData.headers,
|
||||
},
|
||||
env,
|
||||
);
|
||||
return handleForwardEmail(payload, env);
|
||||
} catch (error) {
|
||||
console.error("Error processing email:", error);
|
||||
return new Response("Error processing email", { status: 500 });
|
||||
|
||||
Reference in New Issue
Block a user