export default { // ===================================================== // EMAIL HANDLER // ===================================================== async email(message, env, ctx) { try { const id = Date.now().toString(); const from = message.from; const to = message.to; const subject = message.headers.get("subject") || "(No subject)"; const date = new Date().toISOString(); // ----- Đọc toàn bộ raw MIME email ----- const rawResponse = new Response(message.raw); const buffer = await rawResponse.arrayBuffer(); const raw = new TextDecoder("utf-8").decode(buffer); // ===== LẤY PHẦN NỘI DUNG (CONTENT) & DECODE ===== let body = ""; // Ưu tiên phần text/plain const plainPart = raw.match( /Content-Type:\s*text\/plain[\s\S]*?\r?\n\r?\n([\s\S]*?)(\r?\n--|$)/i ); if (plainPart) { const partFull = plainPart[0]; // cả headers + body let content = plainPart[1].trim(); // chỉ body // xem encoding là gì const encMatch = partFull.match(/Content-Transfer-Encoding:\s*([^\r\n]+)/i); const encoding = encMatch ? encMatch[1].toLowerCase().trim() : ""; if (encoding === "quoted-printable") { body = decodeQuotedPrintableUtf8(content); } else if (encoding === "base64") { body = decodeBase64Utf8(content); } else { body = content; } } else { // Nếu không có text/plain, thử text/html const htmlPart = raw.match( /Content-Type:\s*text\/html[\s\S]*?\r?\n\r?\n([\s\S]*?)(\r?\n--|$)/i ); if (htmlPart) { const partFull = htmlPart[0]; let content = htmlPart[1].trim(); const encMatch = partFull.match(/Content-Transfer-Encoding:\s*([^\r\n]+)/i); const encoding = encMatch ? encMatch[1].toLowerCase().trim() : ""; if (encoding === "quoted-printable") { body = decodeQuotedPrintableUtf8(content); } else if (encoding === "base64") { body = decodeBase64Utf8(content); } else { body = content; } } else { // Bất đắc dĩ: không parse được thì để nguyên raw body = raw; } } const emailData = JSON.stringify({ id, from, to, subject, body, date }); // Lưu email vào KV await env.EMAILS.put(id, emailData); console.log("📩 Email saved:", id); } catch (err) { console.error("❌ Email handler error:", err); } }, // ===================================================== // HTTP HANDLER (UI) // ===================================================== async fetch(request, env) { const url = new URL(request.url); const params = url.searchParams; // ===================================================== // DELETE EMAIL // ===================================================== if (params.get("delete")) { const id = params.get("delete"); await env.EMAILS.delete(id); return new Response("Deleted", { status: 302, headers: { "Location": "/" } }); } // ===================================================== // VIEW SINGLE EMAIL // ===================================================== if (params.get("view")) { const id = params.get("view"); const data = await env.EMAILS.get(id); if (!data) return new Response("Email not found", { status: 404 }); const email = JSON.parse(data); return new Response(`