import type { DeliveryResult, MailAdapter, OwnerRef, ParsedMail } from "../../core/types.ts";
import { createDM, DiscordApiError, sendMessage, type DiscordFile } from "./discord-rest.ts";
import { htmlToText } from "./html-to-text.ts";
const DISCORD_MESSAGE_CAP = 2000;
const INLINE_BODY_CAP = 1500;
const DISCORD_PAYLOAD_CAP = 25 * 1024 * 1024;
// Email HTML is attacker-controlled: anyone who learns an address can send
// to it, and the tag-matching in htmlToText scales quadratically with input
// size. Cloudflare accepts messages far larger than any real email body, so
// bound what gets parsed to keep worst-case CPU well inside Worker limits.
const MAX_HTML_LENGTH = 256 * 1024;
// If the extracted text is thin but the source HTML was substantial, the
// email is likely all-image content (a common marketing-email pattern) that
// htmlToText correctly has nothing to show for. Rather than leaving the
// user with an empty-looking message, fall back to attaching the raw HTML
// so it's still viewable (open it in a browser, the image URLs it
// references still resolve).
const SPARSE_TEXT_THRESHOLD = 200;
const SUBSTANTIAL_HTML_THRESHOLD = 1500;
// A hard character-count slice can land in the middle of a link's "label
// (url)" text, leaving a dangling fragment. Cut on whole-line boundaries
// instead. Every link produced by htmlToText lives entirely within a
// single line, so this never splits one.
function truncateAtLineBoundary(text: string, maxLength: number): string {
const lines = text.split("\n");
let result = "";
for (const line of lines) {
const candidate = result ? `${result}\n${line}` : line;
if (candidate.length > maxLength) {
break;
}
result = candidate;
}
return result || text.slice(0, maxLength);
}