This commit is contained in:
2026-01-22 15:27:37 +01:00
commit 7212eb6f7a
35 changed files with 1462 additions and 0 deletions

View File

@@ -0,0 +1,45 @@
const headerIncludes = (headers: Map<string, string>, key: string) =>
headers.has(key.toLowerCase());
const headerValue = (headers: Map<string, string>, key: string) =>
headers.get(key.toLowerCase()) ?? "";
const containsAny = (value: string, tokens: string[]) =>
tokens.some((token) => value.includes(token));
export const detectNewsletter = (params: {
headers: Map<string, string>;
subject?: string | null;
from?: string | null;
}) => {
const subject = (params.subject ?? "").toLowerCase();
const from = (params.from ?? "").toLowerCase();
const headers = params.headers;
const hasListUnsubscribe = headerIncludes(headers, "list-unsubscribe");
const hasListId = headerIncludes(headers, "list-id");
const precedence = headerValue(headers, "precedence").toLowerCase();
const bulkHeader = headerValue(headers, "x-precedence").toLowerCase();
const headerHints = containsAny(precedence, ["bulk", "list"]) ||
containsAny(bulkHeader, ["bulk", "list"]) ||
headerIncludes(headers, "list-unsubscribe-post");
const subjectHints = containsAny(subject, ["newsletter", "unsubscribe", "update", "news", "digest"]);
const fromHints = containsAny(from, ["newsletter", "no-reply", "noreply", "news", "updates"]);
const score = [hasListUnsubscribe, hasListId, headerHints, subjectHints, fromHints].filter(Boolean).length;
return {
isNewsletter: score >= 2,
score,
signals: {
hasListUnsubscribe,
hasListId,
headerHints,
subjectHints,
fromHints
}
};
};