╔══════════════════════════════════════════════════╗
║ 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
📧 Temp Mail Pro
Buat Email Sementara
📥 Email Masuk
👆 Buat email dulu untuk mulai
Email akan muncul otomatis
🔧 Temp Mail API - Full Docs
List semua domain aktif. Dipakai untuk dropdown di dashboard.
curl -X GET "{HOST}/domains"Response: hydra:member array {domain, id, isActive}
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!"}'
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!"}'
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
Baca 1 email lengkap + HTML + OTP + verificationLinks. Auto mark seen=1.
curl -X GET "{HOST}/messages/abc123def456" \\
-H "Authorization: Bearer TOKEN_KAMU"
Hapus email (soft delete, is_deleted=1).
curl -X DELETE "{HOST}/messages/abc123def456" \\
-H "Authorization: Bearer TOKEN_KAMU"
Cek info akun sendiri, quota & expiry.
curl -X GET "{HOST}/me" \\
-H "Authorization: Bearer TOKEN_KAMU"
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"}'
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 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
📧 Temp Mail Pro
Buat Email Sementara
📥 Email Masuk
👆 Buat email dulu untuk mulai
Email akan muncul otomatis
🔧 Temp Mail API - Full Docs
List semua domain aktif. Dipakai untuk dropdown di dashboard.
curl -X GET "{HOST}/domains"Response: hydra:member array {domain, id, isActive}
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!"}'
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!"}'
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
Baca 1 email lengkap + HTML + OTP + verificationLinks. Auto mark seen=1.
curl -X GET "{HOST}/messages/abc123def456" \\
-H "Authorization: Bearer TOKEN_KAMU"
Hapus email (soft delete, is_deleted=1).
curl -X DELETE "{HOST}/messages/abc123def456" \\
-H "Authorization: Bearer TOKEN_KAMU"
Cek info akun sendiri, quota & expiry.
curl -X GET "{HOST}/me" \\
-H "Authorization: Bearer TOKEN_KAMU"
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"}'
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 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
📧 Temp Mail Pro
Buat Email Sementara
📥 Email Masuk
👆 Buat email dulu untuk mulai
Email akan muncul otomatis
🔧 Temp Mail API - Full Docs
List semua domain aktif. Dipakai untuk dropdown di dashboard.
curl -X GET "{HOST}/domains"Response: hydra:member array {domain, id, isActive}
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!"}'
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!"}'
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
Baca 1 email lengkap + HTML + OTP + verificationLinks. Auto mark seen=1.
curl -X GET "{HOST}/messages/abc123def456" \\
-H "Authorization: Bearer TOKEN_KAMU"
Hapus email (soft delete, is_deleted=1).
curl -X DELETE "{HOST}/messages/abc123def456" \\
-H "Authorization: Bearer TOKEN_KAMU"
Cek info akun sendiri, quota & expiry.
curl -X GET "{HOST}/me" \\
-H "Authorization: Bearer TOKEN_KAMU"
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"}'
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
════════════════════════════════════════════════════════════