╔══════════════════════════════════════════════════╗ ║ CODE REPOSITORY ARCHIVE ║ ╠══════════════════════════════════════════════════╣ ║ Repository: Mail-pro ║ ║ Generated: 10/29/2026, 2:01:04 PM ║ ║ Files: 3 ║ ║ Description: Temp mail ║ ╚══════════════════════════════════════════════════╝ FILE SUMMARY ──────────────────────────────────────────────────── Total files: 3 Total size: 127700 characters Folder structure: Mail-pro/ Languages: - javascript: 2 files - Update temp mail bagian randome name: 1 files FILE CONTENTS ════════════════════════════════════════════════════ ┌── FILE 01: Mail-pro/Mail_pro.js │ Size: 42434 characters │ Language: javascript │ Created: 10/8/2026 └──────────────────────────────────────────────────── // Temp Mail Worker - FINAL FULL API DOCS + Aesthetic 100/10 + MAIL_DB Fix + Login Fix + Human Random Name (No Numbers) export default { async fetch(request, env, ctx) { const url = new URL(request.url); const method = request.method; const path = url.pathname; const checkDB = () => { if (!env.MAIL_DB) { return json({ error: "MAIL_DB not bound. Cek wrangler.toml [[d1_databases]] binding = MAIL_DB" }, 500); } return null; }; try { if (path === "/" && method === "GET") { return new Response(renderPage(), { headers: { "Content-Type": "text/html; charset=UTF-8" } }); } if (path === "/events" && method === "GET") { const dbErr = checkDB(); if (dbErr) return dbErr; const token = url.searchParams.get("token") || ""; const account = verifyToken(token); if (!account) return json({ error: "Invalid token" }, 401); const stream = new ReadableStream({ async start(controller) { const encoder = new TextEncoder(); let lastCount = 0; const sendEvent = async () => { try { const { results } = await env.MAIL_DB.prepare( "SELECT COUNT(*) as count FROM messages WHERE account_id = ? AND is_deleted = 0" ).bind(account.id).all(); const currentCount = results[0]?.count || 0; if (currentCount !== lastCount) { lastCount = currentCount; controller.enqueue(encoder.encode(`data: ${JSON.stringify({ count: currentCount })}\n\n`)); } } catch (e) {} }; await sendEvent(); setInterval(sendEvent, 3000); } }); return new Response(stream, { headers: { "Content-Type": "text/event-stream", "Cache-Control": "no-cache", "Connection": "keep-alive" } }); } if (path === "/domains" && method === "GET") { if (!env.MAIL_DB) { return json({ "hydra:member": [{ domain: "badut.biz.id", id: "default-1", isActive: true, isPrivate: false, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() }] }); } let results = []; try { const res = await env.MAIL_DB.prepare("SELECT * FROM domains WHERE is_active = 1").all(); results = res.results || []; } catch (e) {} if (results.length === 0) results = [{ id: "default-1", domain: "badut.biz.id", created_at: new Date().toISOString() }]; return json({ "hydra:member": results.map(r => ({ domain: r.domain, id: r.id, isActive: true, isPrivate: false, createdAt: r.created_at || new Date().toISOString(), updatedAt: r.created_at || new Date().toISOString() })) }); } if (path === "/accounts" && method === "POST") { const dbErr = checkDB(); if (dbErr) return dbErr; const body = await request.json().catch(() => ({})); const address = body.address; const password = body.password || "Password123!"; if (!address) return json({ error: "Address required" }, 400); const accountId = crypto.randomUUID().replace(/-/g, '').substring(0, 24); const now = new Date().toISOString(); const expires = new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(); try { await env.MAIL_DB.prepare("INSERT INTO accounts (id, address, password, created_at, updated_at, expires_at) VALUES (?, ?, ?, ?, ?, ?)") .bind(accountId, address, password, now, now, expires).run(); return json({ id: accountId, address, quota: 40000000, used: 0, createdAt: now, expiresAt: expires }, 201); } catch (e) { return json({ error: "Address already exists: " + e.message }, 409); } } if (path === "/token" && method === "POST") { const dbErr = checkDB(); if (dbErr) return dbErr; const body = await request.json().catch(() => ({})); const address = body.address; const password = body.password || "Password123!"; try { const { results } = await env.MAIL_DB.prepare("SELECT * FROM accounts WHERE address = ?").bind(address).all(); if (results.length === 0) return json({ error: "Account not found" }, 404); const account = results[0]; if (account.password !== password) return json({ error: "Invalid password" }, 401); const token = btoa(JSON.stringify({ accountId: account.id, address: account.address, createdAt: Date.now() })); return json({ token, id: account.id }); } catch (e) { return json({ error: "DB Error: " + e.message }, 500); } } if (path === "/messages" && method === "GET") { const dbErr = checkDB(); if (dbErr) return dbErr; const token = (request.headers.get("Authorization") || "").replace("Bearer ", ""); const account = verifyToken(token); if (!account) return json({ error: "Invalid token" }, 401); try { const { results } = await env.MAIL_DB.prepare("SELECT * FROM messages WHERE account_id = ? AND is_deleted = 0 ORDER BY created_at DESC LIMIT 20").bind(account.id).all(); return json({ "hydra:member": results.map(m => { const parsed = parseEmailContent(m.text_content || "", m.html_content || ""); return { id: m.id, accountId: m.account_id, from: { address: m.from_address, name: m.from_name }, to: [{ address: m.to_address, name: "" }], subject: m.subject, intro: parsed.cleanText.substring(0, 100), seen: m.seen === 1, isDeleted: false, hasAttachments: m.has_attachments === 1, size: m.size, createdAt: m.created_at, updatedAt: m.updated_at, otpCode: parsed.otpCode }; }), "hydra:totalItems": results.length }); } catch (e) { return json({ error: "DB Error: " + e.message, "hydra:member": [] }, 500); } } const msgMatch = path.match(/^\/messages\/([a-zA-Z0-9]+)$/); if (msgMatch && method === "GET") { const dbErr = checkDB(); if (dbErr) return dbErr; const msgId = msgMatch[1]; const token = (request.headers.get("Authorization") || "").replace("Bearer ", ""); const account = verifyToken(token); if (!account) return json({ error: "Invalid token" }, 401); try { const { results } = await env.MAIL_DB.prepare("SELECT * FROM messages WHERE id = ? AND account_id = ?").bind(msgId, account.id).all(); if (results.length === 0) return json({ error: "Message not found" }, 404); const m = results[0]; await env.MAIL_DB.prepare("UPDATE messages SET seen = 1, updated_at = ? WHERE id = ?").bind(new Date().toISOString(), msgId).run(); const parsed = parseEmailContent(m.text_content || "", m.html_content || ""); return json({ id: m.id, accountId: m.account_id, from: { address: m.from_address, name: m.from_name }, to: [{ address: m.to_address, name: "" }], subject: m.subject, intro: parsed.cleanText.substring(0, 100), text: parsed.cleanText, html: parsed.decodedHtml || m.html_content || "", rawText: m.text_content || "", rawHtml: m.html_content || "", seen: true, isDeleted: false, hasAttachments: m.has_attachments === 1, size: m.size, createdAt: m.created_at, updatedAt: m.updated_at, otpCode: parsed.otpCode, verificationLinks: parsed.links }); } catch (e) { return json({ error: "DB Error: " + e.message }, 500); } } if (msgMatch && method === "DELETE") { const dbErr = checkDB(); if (dbErr) return dbErr; const msgId = msgMatch[1]; const token = (request.headers.get("Authorization") || "").replace("Bearer ", ""); const account = verifyToken(token); if (!account) return json({ error: "Invalid token" }, 401); try { await env.MAIL_DB.prepare("UPDATE messages SET is_deleted = 1 WHERE id = ? AND account_id = ?").bind(msgId, account.id).run(); return json({ success: true }); } catch (e) { return json({ error: e.message }, 500); } } if (path === "/receive" && method === "POST") { const dbErr = checkDB(); if (dbErr) return dbErr; const body = await request.json().catch(() => ({})); const result = await saveEmail(env, ctx, body); if (!result.success) return json({ error: result.error }, result.status); return json(result.message, 201); } if (path === "/webhook" && method === "POST") { const dbErr = checkDB(); if (dbErr) return dbErr; const body = await request.json().catch(() => ({})); const result = await saveEmail(env, ctx, { to: body.to, from: body.from, fromName: body.from_name || body.fromName, subject: body.subject, text: body.text, html: body.html, webhookUrl: body.webhook_url }); if (!result.success) return json({ error: result.error }, result.status); return json({ success: true }); } if (path === "/me" && method === "GET") { const dbErr = checkDB(); if (dbErr) return dbErr; const token = (request.headers.get("Authorization") || "").replace("Bearer ", ""); const account = verifyToken(token); if (!account) return json({ error: "Invalid token" }, 401); try { const { results } = await env.MAIL_DB.prepare("SELECT * FROM accounts WHERE id = ?").bind(account.id).all(); if (results.length === 0) return json({ error: "Account not found" }, 404); const a = results[0]; return json({ id: a.id, address: a.address, quota: a.quota, used: a.used, createdAt: a.created_at, expiresAt: a.expires_at }); } catch (e) { return json({ error: e.message }, 500); } } return json({ error: "Not found: " + path }, 404); } catch (err) { console.error("GLOBAL_WORKER_ERROR", err); return json({ error: "Worker exception: " + err.message }, 500); } }, async scheduled(event, env, ctx) { if (!env.MAIL_DB) return; const now = new Date().toISOString(); ctx.waitUntil(Promise.all([ env.MAIL_DB.prepare("DELETE FROM messages WHERE expires_at < ? OR is_deleted = 1").bind(now).run(), env.MAIL_DB.prepare("DELETE FROM accounts WHERE expires_at < ?").bind(now).run() ])); }, async email(message, env, ctx) { if (!env.MAIL_DB) return; try { const from = message.from; const to = message.to; const subject = message.headers.get("subject") || ""; const rawEmail = await new Response(message.raw).text(); const parsed = parseRawEmail(rawEmail); await saveEmail(env, ctx, { to, from, fromName: "", subject, text: parsed.text, html: parsed.html }); } catch (e) {} } }; function json(data, status = 200) { return new Response(JSON.stringify(data), { status, headers: { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "Content-Type, Authorization" } }); } function verifyToken(token) { try { const d = JSON.parse(atob(token)); return { id: d.accountId, address: d.address }; } catch (e) { return null; } } function decodeQuotedPrintable(str) { if (!str) return ""; return str.replace(/=\r?\n/g, '').replace(/=([0-9A-Fa-f]{2})/g, (m, h) => String.fromCharCode(parseInt(h, 16))); } function parseRawEmail(raw) { let text = ""; let html = ""; const tm = raw.match(/Content-Type: text\/plain[\s\S]*?(?=--[a-zA-Z0-9]+|Content-Type: text\/html|$)/i); if (tm) { text = tm[0].replace(/Content-Type:[^\n]+/gi, '').replace(/Content-Transfer-Encoding:[^\n]+/gi, '').replace(/Content-Disposition:[^\n]+/gi, '').trim(); text = decodeQuotedPrintable(text); } const hm = raw.match(/Content-Type: text\/html[\s\S]*?(?=--[a-zA-Z0-9]+|$)/i); if (hm) { html = hm[0].replace(/Content-Type:[^\n]+/gi, '').replace(/Content-Transfer-Encoding:[^\n]+/gi, '').replace(/Content-Disposition:[^\n]+/gi, '').trim(); html = decodeQuotedPrintable(html); } if (!text && !html) { const p = raw.split(/\r?\n\r?\n/); text = decodeQuotedPrintable(p.slice(1).join('\n\n').trim()); } return { text, html }; } function parseEmailContent(text, html) { let cleanText = decodeQuotedPrintable(text || ""); let decodedHtml = decodeQuotedPrintable(html || ""); let searchContent = cleanText; if (!searchContent && decodedHtml) searchContent = decodedHtml.replace(/<[^>]+>/g, ' '); searchContent = searchContent.replace(/--[a-zA-Z0-9]+/g, '').replace(/Content-Type:[^\n]+/gi, '').replace(/Content-Transfer-Encoding:[^\n]+/gi, '').trim(); let otpCode = null; const patterns = [/(?:OTP|One.?Time.?Password|verifikas?i|verification|verify|code|kode|pin|token)[:\s-]*([0-9]{4,8})/i, /(?:kode|code|otp|pin)\s*(?:is|adalah)?[:\s-]*([A-Z0-9]{4,8})/i, /\b([0-9]{4,8})\b/]; for (const pat of patterns) { const m = searchContent.match(pat); if (m && m[1]) { const c = m[1]; if (!/^(19|20)\d{2}$/.test(c)) { otpCode = c; break; } } } const links = []; const re = /https?:\/\/[^\s"'<>]+/g; let lm; while ((lm = re.exec(searchContent)) !== null) { const u = lm[0].replace(/[.,;:]+$/, ''); if (u.length > 20 && u.length < 1000 && /verify|verification|token|confirm|activate|reset|password|email/i.test(u)) links.push(u); } if (decodedHtml) { const hls = decodedHtml.match(/href=["']([^"']+)["']/gi) || []; for (const hl of hls) { const u = hl.replace(/href=["']/gi, '').replace(/["']$/g, ''); if (u.startsWith('http') && /verify|verification|token|confirm|activate|reset|password|email/i.test(u)) if (!links.includes(u)) links.push(u); } } return { cleanText, decodedHtml, otpCode, links }; } async function saveEmail(env, ctx, emailData) { const toAddress = emailData.to; const fromAddress = emailData.from || "unknown@badut.biz.id"; const fromName = emailData.fromName || ""; const subject = emailData.subject || ""; const text = emailData.text || ""; const html = emailData.html || ""; if (!toAddress) return { success: false, error: "To address required", status: 400 }; try { const { results } = await env.MAIL_DB.prepare("SELECT * FROM accounts WHERE address = ?").bind(toAddress).all(); if (results.length === 0) return { success: false, error: "Account not found", status: 404 }; const account = results[0]; const msgId = crypto.randomUUID().replace(/-/g, '').substring(0, 24); const now = new Date().toISOString(); const expires = new Date(Date.now() + 60 * 60 * 1000).toISOString(); const parsed = parseEmailContent(text, html); await env.MAIL_DB.prepare(`INSERT INTO messages (id, account_id, from_address, from_name, to_address, subject, text_content, html_content, intro, size, created_at, updated_at, expires_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`) .bind(msgId, account.id, fromAddress, fromName, toAddress, subject, text, html, parsed.cleanText.substring(0, 100), text.length + html.length, now, now, expires).run(); if (emailData.webhookUrl || env.GLOBAL_WEBHOOK_URL) { const wh = emailData.webhookUrl || env.GLOBAL_WEBHOOK_URL; ctx.waitUntil(fetch(wh, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ id: msgId, to: toAddress, from: fromAddress, subject, otpCode: parsed.otpCode, links: parsed.links }) }).catch(() => {})); } return { success: true, message: { id: msgId, accountId: account.id, from: { address: fromAddress, name: fromName }, to: [{ address: toAddress, name: "" }], subject, intro: parsed.cleanText.substring(0, 100), text, html, seen: false, isDeleted: false, hasAttachments: false, size: text.length + html.length, createdAt: now, updatedAt: now, otpCode: parsed.otpCode, verificationLinks: parsed.links } }; } catch (e) { return { success: false, error: "DB Error: " + e.message, status: 500 }; } } function renderPage() { return ` 📧 Temp Mail Pro - badut.biz.id
📥 Email Masuk
👆 Buat email dulu untuk mulai
Email akan muncul otomatis

🔧 Temp Mail API - Full Docs

GET/domains

List semua domain aktif. Dipakai untuk dropdown di dashboard.

curl -X GET "{HOST}/domains"

Response: hydra:member array {domain, id, isActive}

POST/accounts

Buat akun / email baru. Harus unik, kalau sudah ada return 409.

curl -X POST "{HOST}/accounts" \\
  -H "Content-Type: application/json" \\
  -d '{"address":"test123@badut.biz.id","password":"Password123!"}'
POST/token

Login & dapatkan Bearer token. Token dipakai untuk akses /messages.

curl -X POST "{HOST}/token" \\
  -H "Content-Type: application/json" \\
  -d '{"address":"test123@badut.biz.id","password":"Password123!"}'
GET/messages

List 20 email masuk terbaru. Butuh header Authorization.

curl -X GET "{HOST}/messages" \\
  -H "Authorization: Bearer TOKEN_KAMU"

Field penting: otpCode (auto deteksi), intro, seen

GET/messages/:id

Baca 1 email lengkap + HTML + OTP + verificationLinks. Auto mark seen=1.

curl -X GET "{HOST}/messages/abc123def456" \\
  -H "Authorization: Bearer TOKEN_KAMU"
DELETE/messages/:id

Hapus email (soft delete, is_deleted=1).

curl -X DELETE "{HOST}/messages/abc123def456" \\
  -H "Authorization: Bearer TOKEN_KAMU"
GET/me

Cek info akun sendiri, quota & expiry.

curl -X GET "{HOST}/me" \\
  -H "Authorization: Bearer TOKEN_KAMU"
POST/receive

Endpoint untuk forward email masuk dari Email Routing / webhook. Format: {"to","from","subject","text","html"}

curl -X POST "{HOST}/receive" \\
  -H "Content-Type: application/json" \\
  -d '{"to":"test@badut.biz.id","from":"noreply@google.com","subject":"OTP","text":"Your code is 123456"}'
GET/events

Server-Sent Events (SSE) untuk notifikasi realtime. Dipakai dashboard untuk auto-refresh.

GET /events?token=xxx  (EventStream)
──────────────────────────────────────────────────────────── ┌── FILE 02: Mail-pro/Mail_pro.v2.js │ Size: 42950 characters │ Language: Update temp mail bagian randome name │ Created: 10/8/2026 └──────────────────────────────────────────────────── // Temp Mail Worker - FINAL FULL API DOCS + Aesthetic 100/10 + MAIL_DB Fix + Login Fix + Human Random Name Auto No Dot No Number export default { async fetch(request, env, ctx) { const url = new URL(request.url); const method = request.method; const path = url.pathname; const checkDB = () => { if (!env.MAIL_DB) { return json({ error: "MAIL_DB not bound. Cek wrangler.toml [[d1_databases]] binding = MAIL_DB" }, 500); } return null; }; try { if (path === "/" && method === "GET") { return new Response(renderPage(), { headers: { "Content-Type": "text/html; charset=UTF-8" } }); } if (path === "/events" && method === "GET") { const dbErr = checkDB(); if (dbErr) return dbErr; const token = url.searchParams.get("token") || ""; const account = verifyToken(token); if (!account) return json({ error: "Invalid token" }, 401); const stream = new ReadableStream({ async start(controller) { const encoder = new TextEncoder(); let lastCount = 0; const sendEvent = async () => { try { const { results } = await env.MAIL_DB.prepare( "SELECT COUNT(*) as count FROM messages WHERE account_id =? AND is_deleted = 0" ).bind(account.id).all(); const currentCount = results[0]?.count || 0; if (currentCount!== lastCount) { lastCount = currentCount; controller.enqueue(encoder.encode(`data: ${JSON.stringify({ count: currentCount })}\n\n`)); } } catch (e) {} }; await sendEvent(); setInterval(sendEvent, 3000); } }); return new Response(stream, { headers: { "Content-Type": "text/event-stream", "Cache-Control": "no-cache", "Connection": "keep-alive" } }); } if (path === "/domains" && method === "GET") { if (!env.MAIL_DB) { return json({ "hydra:member": [{ domain: "badut.biz.id", id: "default-1", isActive: true, isPrivate: false, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() }] }); } let results = []; try { const res = await env.MAIL_DB.prepare("SELECT * FROM domains WHERE is_active = 1").all(); results = res.results || []; } catch (e) {} if (results.length === 0) results = [{ id: "default-1", domain: "badut.biz.id", created_at: new Date().toISOString() }]; return json({ "hydra:member": results.map(r => ({ domain: r.domain, id: r.id, isActive: true, isPrivate: false, createdAt: r.created_at || new Date().toISOString(), updatedAt: r.created_at || new Date().toISOString() })) }); } if (path === "/accounts" && method === "POST") { const dbErr = checkDB(); if (dbErr) return dbErr; const body = await request.json().catch(() => ({})); const address = body.address; const password = body.password || "Password123!"; if (!address) return json({ error: "Address required" }, 400); const accountId = crypto.randomUUID().replace(/-/g, '').substring(0, 24); const now = new Date().toISOString(); const expires = new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(); try { await env.MAIL_DB.prepare("INSERT INTO accounts (id, address, password, created_at, updated_at, expires_at) VALUES (?,?,?,?,?,?)") .bind(accountId, address, password, now, now, expires).run(); return json({ id: accountId, address, quota: 40000000, used: 0, createdAt: now, expiresAt: expires }, 201); } catch (e) { return json({ error: "Address already exists: " + e.message }, 409); } } if (path === "/token" && method === "POST") { const dbErr = checkDB(); if (dbErr) return dbErr; const body = await request.json().catch(() => ({})); const address = body.address; const password = body.password || "Password123!"; try { const { results } = await env.MAIL_DB.prepare("SELECT * FROM accounts WHERE address =?").bind(address).all(); if (results.length === 0) return json({ error: "Account not found" }, 404); const account = results[0]; if (account.password!== password) return json({ error: "Invalid password" }, 401); const token = btoa(JSON.stringify({ accountId: account.id, address: account.address, createdAt: Date.now() })); return json({ token, id: account.id }); } catch (e) { return json({ error: "DB Error: " + e.message }, 500); } } if (path === "/messages" && method === "GET") { const dbErr = checkDB(); if (dbErr) return dbErr; const token = (request.headers.get("Authorization") || "").replace("Bearer ", ""); const account = verifyToken(token); if (!account) return json({ error: "Invalid token" }, 401); try { const { results } = await env.MAIL_DB.prepare("SELECT * FROM messages WHERE account_id =? AND is_deleted = 0 ORDER BY created_at DESC LIMIT 20").bind(account.id).all(); return json({ "hydra:member": results.map(m => { const parsed = parseEmailContent(m.text_content || "", m.html_content || ""); return { id: m.id, accountId: m.account_id, from: { address: m.from_address, name: m.from_name }, to: [{ address: m.to_address, name: "" }], subject: m.subject, intro: parsed.cleanText.substring(0, 100), seen: m.seen === 1, isDeleted: false, hasAttachments: m.has_attachments === 1, size: m.size, createdAt: m.created_at, updatedAt: m.updated_at, otpCode: parsed.otpCode }; }), "hydra:totalItems": results.length }); } catch (e) { return json({ error: "DB Error: " + e.message, "hydra:member": [] }, 500); } } const msgMatch = path.match(/^\/messages\/([a-zA-Z0-9]+)$/); if (msgMatch && method === "GET") { const dbErr = checkDB(); if (dbErr) return dbErr; const msgId = msgMatch[1]; const token = (request.headers.get("Authorization") || "").replace("Bearer ", ""); const account = verifyToken(token); if (!account) return json({ error: "Invalid token" }, 401); try { const { results } = await env.MAIL_DB.prepare("SELECT * FROM messages WHERE id =? AND account_id =?").bind(msgId, account.id).all(); if (results.length === 0) return json({ error: "Message not found" }, 404); const m = results[0]; await env.MAIL_DB.prepare("UPDATE messages SET seen = 1, updated_at =? WHERE id =?").bind(new Date().toISOString(), msgId).run(); const parsed = parseEmailContent(m.text_content || "", m.html_content || ""); return json({ id: m.id, accountId: m.account_id, from: { address: m.from_address, name: m.from_name }, to: [{ address: m.to_address, name: "" }], subject: m.subject, intro: parsed.cleanText.substring(0, 100), text: parsed.cleanText, html: parsed.decodedHtml || m.html_content || "", rawText: m.text_content || "", rawHtml: m.html_content || "", seen: true, isDeleted: false, hasAttachments: m.has_attachments === 1, size: m.size, createdAt: m.created_at, updatedAt: m.updated_at, otpCode: parsed.otpCode, verificationLinks: parsed.links }); } catch (e) { return json({ error: "DB Error: " + e.message }, 500); } } if (msgMatch && method === "DELETE") { const dbErr = checkDB(); if (dbErr) return dbErr; const msgId = msgMatch[1]; const token = (request.headers.get("Authorization") || "").replace("Bearer ", ""); const account = verifyToken(token); if (!account) return json({ error: "Invalid token" }, 401); try { await env.MAIL_DB.prepare("UPDATE messages SET is_deleted = 1 WHERE id =? AND account_id =?").bind(msgId, account.id).run(); return json({ success: true }); } catch (e) { return json({ error: e.message }, 500); } } if (path === "/receive" && method === "POST") { const dbErr = checkDB(); if (dbErr) return dbErr; const body = await request.json().catch(() => ({})); const result = await saveEmail(env, ctx, body); if (!result.success) return json({ error: result.error }, result.status); return json(result.message, 201); } if (path === "/webhook" && method === "POST") { const dbErr = checkDB(); if (dbErr) return dbErr; const body = await request.json().catch(() => ({})); const result = await saveEmail(env, ctx, { to: body.to, from: body.from, fromName: body.from_name || body.fromName, subject: body.subject, text: body.text, html: body.html, webhookUrl: body.webhook_url }); if (!result.success) return json({ error: result.error }, result.status); return json({ success: true }); } if (path === "/me" && method === "GET") { const dbErr = checkDB(); if (dbErr) return dbErr; const token = (request.headers.get("Authorization") || "").replace("Bearer ", ""); const account = verifyToken(token); if (!account) return json({ error: "Invalid token" }, 401); try { const { results } = await env.MAIL_DB.prepare("SELECT * FROM accounts WHERE id =?").bind(account.id).all(); if (results.length === 0) return json({ error: "Account not found" }, 404); const a = results[0]; return json({ id: a.id, address: a.address, quota: a.quota, used: a.used, createdAt: a.created_at, expiresAt: a.expires_at }); } catch (e) { return json({ error: e.message }, 500); } } return json({ error: "Not found: " + path }, 404); } catch (err) { console.error("GLOBAL_WORKER_ERROR", err); return json({ error: "Worker exception: " + err.message }, 500); } }, async scheduled(event, env, ctx) { if (!env.MAIL_DB) return; const now = new Date().toISOString(); ctx.waitUntil(Promise.all([ env.MAIL_DB.prepare("DELETE FROM messages WHERE expires_at String.fromCharCode(parseInt(h, 16))); } function parseRawEmail(raw) { let text = ""; let html = ""; const tm = raw.match(/Content-Type: text\/plain[\s\S]*?(?=--[a-zA-Z0-9]+|Content-Type: text\/html|$)/i); if (tm) { text = tm[0].replace(/Content-Type:[^\n]+/gi, '').replace(/Content-Transfer-Encoding:[^\n]+/gi, '').replace(/Content-Disposition:[^\n]+/gi, '').trim(); text = decodeQuotedPrintable(text); } const hm = raw.match(/Content-Type: text\/html[\s\S]*?(?=--[a-zA-Z0-9]+|$)/i); if (hm) { html = hm[0].replace(/Content-Type:[^\n]+/gi, '').replace(/Content-Transfer-Encoding:[^\n]+/gi, '').replace(/Content-Disposition:[^\n]+/gi, '').trim(); html = decodeQuotedPrintable(html); } if (!text &&!html) { const p = raw.split(/\r?\n\r?\n/); text = decodeQuotedPrintable(p.slice(1).join('\n\n').trim()); } return { text, html }; } function parseEmailContent(text, html) { let cleanText = decodeQuotedPrintable(text || ""); let decodedHtml = decodeQuotedPrintable(html || ""); let searchContent = cleanText; if (!searchContent && decodedHtml) searchContent = decodedHtml.replace(/<[^>]+>/g, ' '); searchContent = searchContent.replace(/--[a-zA-Z0-9]+/g, '').replace(/Content-Type:[^\n]+/gi, '').replace(/Content-Transfer-Encoding:[^\n]+/gi, '').trim(); let otpCode = null; const patterns = [/(?:OTP|One.?Time.?Password|verifikas?i|verification|verify|code|kode|pin|token)[:\s-]*([0-9]{4,8})/i, /(?:kode|code|otp|pin)\s*(?:is|adalah)?[:\s-]*([A-Z0-9]{4,8})/i, /\b([0-9]{4,8})\b/]; for (const pat of patterns) { const m = searchContent.match(pat); if (m && m[1]) { const c = m[1]; if (!/^(19|20)\d{2}$/.test(c)) { otpCode = c; break; } } } const links = []; const re = /https?:\/\/[^\s"'<>]+/g; let lm; while ((lm = re.exec(searchContent))!== null) { const u = lm[0].replace(/[.,;:]+$/, ''); if (u.length > 20 && u.length < 1000 && /verify|verification|token|confirm|activate|reset|password|email/i.test(u)) links.push(u); } if (decodedHtml) { const hls = decodedHtml.match(/href=["']([^"']+)["']/gi) || []; for (const hl of hls) { const u = hl.replace(/href=["']/gi, '').replace(/["']$/g, ''); if (u.startsWith('http') && /verify|verification|token|confirm|activate|reset|password|email/i.test(u)) if (!links.includes(u)) links.push(u); } } return { cleanText, decodedHtml, otpCode, links }; } async function saveEmail(env, ctx, emailData) { const toAddress = emailData.to; const fromAddress = emailData.from || "unknown@badut.biz.id"; const fromName = emailData.fromName || ""; const subject = emailData.subject || ""; const text = emailData.text || ""; const html = emailData.html || ""; if (!toAddress) return { success: false, error: "To address required", status: 400 }; try { const { results } = await env.MAIL_DB.prepare("SELECT * FROM accounts WHERE address =?").bind(toAddress).all(); if (results.length === 0) return { success: false, error: "Account not found", status: 404 }; const account = results[0]; const msgId = crypto.randomUUID().replace(/-/g, '').substring(0, 24); const now = new Date().toISOString(); const expires = new Date(Date.now() + 60 * 60 * 1000).toISOString(); const parsed = parseEmailContent(text, html); await env.MAIL_DB.prepare(`INSERT INTO messages (id, account_id, from_address, from_name, to_address, subject, text_content, html_content, intro, size, created_at, updated_at, expires_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)`) .bind(msgId, account.id, fromAddress, fromName, toAddress, subject, text, html, parsed.cleanText.substring(0, 100), text.length + html.length, now, now, expires).run(); if (emailData.webhookUrl || env.GLOBAL_WEBHOOK_URL) { const wh = emailData.webhookUrl || env.GLOBAL_WEBHOOK_URL; ctx.waitUntil(fetch(wh, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ id: msgId, to: toAddress, from: fromAddress, subject, otpCode: parsed.otpCode, links: parsed.links }) }).catch(() => {})); } return { success: true, message: { id: msgId, accountId: account.id, from: { address: fromAddress, name: fromName }, to: [{ address: toAddress, name: "" }], subject, intro: parsed.cleanText.substring(0, 100), text, html, seen: false, isDeleted: false, hasAttachments: false, size: text.length + html.length, createdAt: now, updatedAt: now, otpCode: parsed.otpCode, verificationLinks: parsed.links } }; } catch (e) { return { success: false, error: "DB Error: " + e.message, status: 500 }; } } function renderPage() { return ` 📧 Temp Mail Pro - badut.biz.id
📥 Email Masuk
👆 Buat email dulu untuk mulai
Email akan muncul otomatis

🔧 Temp Mail API - Full Docs

GET/domains

List semua domain aktif. Dipakai untuk dropdown di dashboard.

curl -X GET "{HOST}/domains"

Response: hydra:member array {domain, id, isActive}

POST/accounts

Buat akun / email baru. Harus unik, kalau sudah ada return 409.

curl -X POST "{HOST}/accounts" \\
  -H "Content-Type: application/json" \\
  -d '{"address":"test123@badut.biz.id","password":"Password123!"}'
POST/token

Login & dapatkan Bearer token. Token dipakai untuk akses /messages.

curl -X POST "{HOST}/token" \\
  -H "Content-Type: application/json" \\
  -d '{"address":"test123@badut.biz.id","password":"Password123!"}'
GET/messages

List 20 email masuk terbaru. Butuh header Authorization.

curl -X GET "{HOST}/messages" \\
  -H "Authorization: Bearer TOKEN_KAMU"

Field penting: otpCode (auto deteksi), intro, seen

GET/messages/:id

Baca 1 email lengkap + HTML + OTP + verificationLinks. Auto mark seen=1.

curl -X GET "{HOST}/messages/abc123def456" \\
  -H "Authorization: Bearer TOKEN_KAMU"
DELETE/messages/:id

Hapus email (soft delete, is_deleted=1).

curl -X DELETE "{HOST}/messages/abc123def456" \\
  -H "Authorization: Bearer TOKEN_KAMU"
GET/me

Cek info akun sendiri, quota & expiry.

curl -X GET "{HOST}/me" \\
  -H "Authorization: Bearer TOKEN_KAMU"
POST/receive

Endpoint untuk forward email masuk dari Email Routing / webhook. Format: {"to","from","subject","text","html"}

curl -X POST "{HOST}/receive" \\
  -H "Content-Type: application/json" \\
  -d '{"to":"test@badut.biz.id","from":"noreply@google.com","subject":"OTP","text":"Your code is 123456"}'
GET/events

Server-Sent Events (SSE) untuk notifikasi realtime. Dipakai dashboard untuk auto-refresh.

GET /events?token=xxx (EventStream)
`; } ──────────────────────────────────────────────────────────── ┌── FILE 03: Mail-pro/Mail_pro.v3.js │ Size: 42316 characters │ Language: javascript │ Created: 10/10/2026 └──────────────────────────────────────────────────── // Temp Mail Worker - FINAL FULL API DOCS + Aesthetic 100/10 + MAIL_DB Fix + Random 4huruf+angka export default { async fetch(request, env, ctx) { const url = new URL(request.url); const method = request.method; const path = url.pathname; const checkDB = () => { if (!env.MAIL_DB) { return json({ error: "MAIL_DB not bound. Cek wrangler.toml [[d1_databases]] binding = MAIL_DB" }, 500); } return null; }; try { if (path === "/" && method === "GET") { return new Response(renderPage(), { headers: { "Content-Type": "text/html; charset=UTF-8" } }); } if (path === "/events" && method === "GET") { const dbErr = checkDB(); if (dbErr) return dbErr; const token = url.searchParams.get("token") || ""; const account = verifyToken(token); if (!account) return json({ error: "Invalid token" }, 401); const stream = new ReadableStream({ async start(controller) { const encoder = new TextEncoder(); let lastCount = 0; const sendEvent = async () => { try { const { results } = await env.MAIL_DB.prepare( "SELECT COUNT(*) as count FROM messages WHERE account_id =? AND is_deleted = 0" ).bind(account.id).all(); const currentCount = results[0]?.count || 0; if (currentCount!== lastCount) { lastCount = currentCount; controller.enqueue(encoder.encode(`data: ${JSON.stringify({ count: currentCount })}\n\n`)); } } catch (e) {} }; await sendEvent(); setInterval(sendEvent, 3000); } }); return new Response(stream, { headers: { "Content-Type": "text/event-stream", "Cache-Control": "no-cache", "Connection": "keep-alive" } }); } if (path === "/domains" && method === "GET") { if (!env.MAIL_DB) { return json({ "hydra:member": [{ domain: "badut.biz.id", id: "default-1", isActive: true, isPrivate: false, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() }] }); } let results = []; try { const res = await env.MAIL_DB.prepare("SELECT * FROM domains WHERE is_active = 1").all(); results = res.results || []; } catch (e) {} if (results.length === 0) results = [{ id: "default-1", domain: "badut.biz.id", created_at: new Date().toISOString() }]; return json({ "hydra:member": results.map(r => ({ domain: r.domain, id: r.id, isActive: true, isPrivate: false, createdAt: r.created_at || new Date().toISOString(), updatedAt: r.created_at || new Date().toISOString() })) }); } if (path === "/accounts" && method === "POST") { const dbErr = checkDB(); if (dbErr) return dbErr; const body = await request.json().catch(() => ({})); const address = body.address; const password = body.password || "Password123!"; if (!address) return json({ error: "Address required" }, 400); const accountId = crypto.randomUUID().replace(/-/g, '').substring(0, 24); const now = new Date().toISOString(); const expires = new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(); try { await env.MAIL_DB.prepare("INSERT INTO accounts (id, address, password, created_at, updated_at, expires_at) VALUES (?,?,?,?,?,?)") .bind(accountId, address, password, now, now, expires).run(); return json({ id: accountId, address, quota: 40000000, used: 0, createdAt: now, expiresAt: expires }, 201); } catch (e) { return json({ error: "Address already exists: " + e.message }, 409); } } if (path === "/token" && method === "POST") { const dbErr = checkDB(); if (dbErr) return dbErr; const body = await request.json().catch(() => ({})); const address = body.address; const password = body.password || "Password123!"; try { const { results } = await env.MAIL_DB.prepare("SELECT * FROM accounts WHERE address =?").bind(address).all(); if (results.length === 0) return json({ error: "Account not found" }, 404); const account = results[0]; if (account.password!== password) return json({ error: "Invalid password" }, 401); const token = btoa(JSON.stringify({ accountId: account.id, address: account.address, createdAt: Date.now() })); return json({ token, id: account.id }); } catch (e) { return json({ error: "DB Error: " + e.message }, 500); } } if (path === "/messages" && method === "GET") { const dbErr = checkDB(); if (dbErr) return dbErr; const token = (request.headers.get("Authorization") || "").replace("Bearer ", ""); const account = verifyToken(token); if (!account) return json({ error: "Invalid token" }, 401); try { const { results } = await env.MAIL_DB.prepare("SELECT * FROM messages WHERE account_id =? AND is_deleted = 0 ORDER BY created_at DESC LIMIT 20").bind(account.id).all(); return json({ "hydra:member": results.map(m => { const parsed = parseEmailContent(m.text_content || "", m.html_content || ""); return { id: m.id, accountId: m.account_id, from: { address: m.from_address, name: m.from_name }, to: [{ address: m.to_address, name: "" }], subject: m.subject, intro: parsed.cleanText.substring(0, 100), seen: m.seen === 1, isDeleted: false, hasAttachments: m.has_attachments === 1, size: m.size, createdAt: m.created_at, updatedAt: m.updated_at, otpCode: parsed.otpCode }; }), "hydra:totalItems": results.length }); } catch (e) { return json({ error: "DB Error: " + e.message, "hydra:member": [] }, 500); } } const msgMatch = path.match(/^\/messages\/([a-zA-Z0-9]+)$/); if (msgMatch && method === "GET") { const dbErr = checkDB(); if (dbErr) return dbErr; const msgId = msgMatch[1]; const token = (request.headers.get("Authorization") || "").replace("Bearer ", ""); const account = verifyToken(token); if (!account) return json({ error: "Invalid token" }, 401); try { const { results } = await env.MAIL_DB.prepare("SELECT * FROM messages WHERE id =? AND account_id =?").bind(msgId, account.id).all(); if (results.length === 0) return json({ error: "Message not found" }, 404); const m = results[0]; await env.MAIL_DB.prepare("UPDATE messages SET seen = 1, updated_at =? WHERE id =?").bind(new Date().toISOString(), msgId).run(); const parsed = parseEmailContent(m.text_content || "", m.html_content || ""); return json({ id: m.id, accountId: m.account_id, from: { address: m.from_address, name: m.from_name }, to: [{ address: m.to_address, name: "" }], subject: m.subject, intro: parsed.cleanText.substring(0, 100), text: parsed.cleanText, html: parsed.decodedHtml || m.html_content || "", rawText: m.text_content || "", rawHtml: m.html_content || "", seen: true, isDeleted: false, hasAttachments: m.has_attachments === 1, size: m.size, createdAt: m.created_at, updatedAt: m.updated_at, otpCode: parsed.otpCode, verificationLinks: parsed.links }); } catch (e) { return json({ error: "DB Error: " + e.message }, 500); } } if (msgMatch && method === "DELETE") { const dbErr = checkDB(); if (dbErr) return dbErr; const msgId = msgMatch[1]; const token = (request.headers.get("Authorization") || "").replace("Bearer ", ""); const account = verifyToken(token); if (!account) return json({ error: "Invalid token" }, 401); try { await env.MAIL_DB.prepare("UPDATE messages SET is_deleted = 1 WHERE id =? AND account_id =?").bind(msgId, account.id).run(); return json({ success: true }); } catch (e) { return json({ error: e.message }, 500); } } if (path === "/receive" && method === "POST") { const dbErr = checkDB(); if (dbErr) return dbErr; const body = await request.json().catch(() => ({})); const result = await saveEmail(env, ctx, body); if (!result.success) return json({ error: result.error }, result.status); return json(result.message, 201); } if (path === "/webhook" && method === "POST") { const dbErr = checkDB(); if (dbErr) return dbErr; const body = await request.json().catch(() => ({})); const result = await saveEmail(env, ctx, { to: body.to, from: body.from, fromName: body.from_name || body.fromName, subject: body.subject, text: body.text, html: body.html, webhookUrl: body.webhook_url }); if (!result.success) return json({ error: result.error }, result.status); return json({ success: true }); } if (path === "/me" && method === "GET") { const dbErr = checkDB(); if (dbErr) return dbErr; const token = (request.headers.get("Authorization") || "").replace("Bearer ", ""); const account = verifyToken(token); if (!account) return json({ error: "Invalid token" }, 401); try { const { results } = await env.MAIL_DB.prepare("SELECT * FROM accounts WHERE id =?").bind(account.id).all(); if (results.length === 0) return json({ error: "Account not found" }, 404); const a = results[0]; return json({ id: a.id, address: a.address, quota: a.quota, used: a.used, createdAt: a.created_at, expiresAt: a.expires_at }); } catch (e) { return json({ error: e.message }, 500); } } return json({ error: "Not found: " + path }, 404); } catch (err) { console.error("GLOBAL_WORKER_ERROR", err); return json({ error: "Worker exception: " + err.message }, 500); } }, async scheduled(event, env, ctx) { if (!env.MAIL_DB) return; const now = new Date().toISOString(); ctx.waitUntil(Promise.all([ env.MAIL_DB.prepare("DELETE FROM messages WHERE expires_at String.fromCharCode(parseInt(h, 16))); } function parseRawEmail(raw) { let text = ""; let html = ""; const tm = raw.match(/Content-Type: text\/plain[\s\S]*?(?=--[a-zA-Z0-9]+|Content-Type: text\/html|$)/i); if (tm) { text = tm[0].replace(/Content-Type:[^\n]+/gi, '').replace(/Content-Transfer-Encoding:[^\n]+/gi, '').replace(/Content-Disposition:[^\n]+/gi, '').trim(); text = decodeQuotedPrintable(text); } const hm = raw.match(/Content-Type: text\/html[\s\S]*?(?=--[a-zA-Z0-9]+|$)/i); if (hm) { html = hm[0].replace(/Content-Type:[^\n]+/gi, '').replace(/Content-Transfer-Encoding:[^\n]+/gi, '').replace(/Content-Disposition:[^\n]+/gi, '').trim(); html = decodeQuotedPrintable(html); } if (!text &&!html) { const p = raw.split(/\r?\n\r?\n/); text = decodeQuotedPrintable(p.slice(1).join('\n\n').trim()); } return { text, html }; } function parseEmailContent(text, html) { let cleanText = decodeQuotedPrintable(text || ""); let decodedHtml = decodeQuotedPrintable(html || ""); let searchContent = cleanText; if (!searchContent && decodedHtml) searchContent = decodedHtml.replace(/<[^>]+>/g, ' '); searchContent = searchContent.replace(/--[a-zA-Z0-9]+/g, '').replace(/Content-Type:[^\n]+/gi, '').replace(/Content-Transfer-Encoding:[^\n]+/gi, '').trim(); let otpCode = null; const patterns = [/(?:OTP|One.?Time.?Password|verifikas?i|verification|verify|code|kode|pin|token)[:\s-]*([0-9]{4,8})/i, /(?:kode|code|otp|pin)\s*(?:is|adalah)?[:\s-]*([A-Z0-9]{4,8})/i, /\b([0-9]{4,8})\b/]; for (const pat of patterns) { const m = searchContent.match(pat); if (m && m[1]) { const c = m[1]; if (!/^(19|20)\d{2}$/.test(c)) { otpCode = c; break; } } } const links = []; const re = /https?:\/\/[^\s"'<>]+/g; let lm; while ((lm = re.exec(searchContent))!== null) { const u = lm[0].replace(/[.,;:]+$/, ''); if (u.length > 20 && u.length < 1000 && /verify|verification|token|confirm|activate|reset|password|email/i.test(u)) links.push(u); } if (decodedHtml) { const hls = decodedHtml.match(/href=["']([^"']+)["']/gi) || []; for (const hl of hls) { const u = hl.replace(/href=["']/gi, '').replace(/["']$/g, ''); if (u.startsWith('http') && /verify|verification|token|confirm|activate|reset|password|email/i.test(u)) if (!links.includes(u)) links.push(u); } } return { cleanText, decodedHtml, otpCode, links }; } async function saveEmail(env, ctx, emailData) { const toAddress = emailData.to; const fromAddress = emailData.from || "unknown@badut.biz.id"; const fromName = emailData.fromName || ""; const subject = emailData.subject || ""; const text = emailData.text || ""; const html = emailData.html || ""; if (!toAddress) return { success: false, error: "To address required", status: 400 }; try { const { results } = await env.MAIL_DB.prepare("SELECT * FROM accounts WHERE address =?").bind(toAddress).all(); if (results.length === 0) return { success: false, error: "Account not found", status: 404 }; const account = results[0]; const msgId = crypto.randomUUID().replace(/-/g, '').substring(0, 24); const now = new Date().toISOString(); const expires = new Date(Date.now() + 60 * 60 * 1000).toISOString(); const parsed = parseEmailContent(text, html); await env.MAIL_DB.prepare(`INSERT INTO messages (id, account_id, from_address, from_name, to_address, subject, text_content, html_content, intro, size, created_at, updated_at, expires_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)`) .bind(msgId, account.id, fromAddress, fromName, toAddress, subject, text, html, parsed.cleanText.substring(0, 100), text.length + html.length, now, now, expires).run(); if (emailData.webhookUrl || env.GLOBAL_WEBHOOK_URL) { const wh = emailData.webhookUrl || env.GLOBAL_WEBHOOK_URL; ctx.waitUntil(fetch(wh, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ id: msgId, to: toAddress, from: fromAddress, subject, otpCode: parsed.otpCode, links: parsed.links }) }).catch(() => {})); } return { success: true, message: { id: msgId, accountId: account.id, from: { address: fromAddress, name: fromName }, to: [{ address: toAddress, name: "" }], subject, intro: parsed.cleanText.substring(0, 100), text, html, seen: false, isDeleted: false, hasAttachments: false, size: text.length + html.length, createdAt: now, updatedAt: now, otpCode: parsed.otpCode, verificationLinks: parsed.links } }; } catch (e) { return { success: false, error: "DB Error: " + e.message, status: 500 }; } } function renderPage() { return ` 📧 Temp Mail Pro - badut.biz.id
📥 Email Masuk
👆 Buat email dulu untuk mulai
Email akan muncul otomatis

🔧 Temp Mail API - Full Docs

GET/domains

List semua domain aktif. Dipakai untuk dropdown di dashboard.

curl -X GET "{HOST}/domains"

Response: hydra:member array {domain, id, isActive}

POST/accounts

Buat akun / email baru. Harus unik, kalau sudah ada return 409.

curl -X POST "{HOST}/accounts" \\
  -H "Content-Type: application/json" \\
  -d '{"address":"test123@badut.biz.id","password":"Password123!"}'
POST/token

Login & dapatkan Bearer token. Token dipakai untuk akses /messages.

curl -X POST "{HOST}/token" \\
  -H "Content-Type: application/json" \\
  -d '{"address":"test123@badut.biz.id","password":"Password123!"}'
GET/messages

List 20 email masuk terbaru. Butuh header Authorization.

curl -X GET "{HOST}/messages" \\
  -H "Authorization: Bearer TOKEN_KAMU"

Field penting: otpCode (auto deteksi), intro, seen

GET/messages/:id

Baca 1 email lengkap + HTML + OTP + verificationLinks. Auto mark seen=1.

curl -X GET "{HOST}/messages/abc123def456" \\
  -H "Authorization: Bearer TOKEN_KAMU"
DELETE/messages/:id

Hapus email (soft delete, is_deleted=1).

curl -X DELETE "{HOST}/messages/abc123def456" \\
  -H "Authorization: Bearer TOKEN_KAMU"
GET/me

Cek info akun sendiri, quota & expiry.

curl -X GET "{HOST}/me" \\
  -H "Authorization: Bearer TOKEN_KAMU"
POST/receive

Endpoint untuk forward email masuk dari Email Routing / webhook. Format: {"to","from","subject","text","html"}

curl -X POST "{HOST}/receive" \\
  -H "Content-Type: application/json" \\
  -d '{"to":"test@badut.biz.id","from":"noreply@google.com","subject":"OTP","text":"Your code is 123456"}'
GET/events

Server-Sent Events (SSE) untuk notifikasi realtime. Dipakai dashboard untuk auto-refresh.

GET /events?token=xxx (EventStream)
`; } ════════════════════════════════════════════════════════════ ARCHIVE COMPLETE - 3 files exported Location: Mail-pro/ Exported: 10/29/2026, 2:01:04 PM Source: CodeHub Repository ════════════════════════════════════════════════════════════