/** * email.js * * author : zavedyaaid * ch author : https://whatsapp.com/channel/0029VbC6Qmr4dTnGB19pok0Y * * Command: * node email.js --new [nama] -> bikin email baru * node email.js --get -> list ringkas semua pesan + ID & setengah isi * node email.js --read -> baca isi lengkap pesan tertentu (beserta link) * node email.js -> liat email yang lagi aktif */ const fs = require('fs'); const path = require('path'); const crypto = require('crypto'); const STATE_FILE = path.join(__dirname, '.tempmail.json'); const API = 'https://api.mail.tm'; function loadState() { if (fs.existsSync(STATE_FILE)) { return JSON.parse(fs.readFileSync(STATE_FILE, 'utf8')); } return null; } function saveState(state) { fs.writeFileSync(STATE_FILE, JSON.stringify(state, null, 2)); } // Fungsi request dengan retry otomatis untuk mengatasi 503 / gangguan jaringan sesaat async function apiRequest(method, endpoint, { body, token } = {}, retries = 3) { const headers = { 'Content-Type': 'application/json', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' }; if (token) headers.Authorization = `Bearer ${token}`; for (let i = 0; i < retries; i++) { try { const res = await fetch(`${API}${endpoint}`, { method, headers, body: body ? JSON.stringify(body) : undefined, }); const text = await res.text(); let json; try { json = text ? JSON.parse(text) : {}; } catch { json = { raw: text }; } if (!res.ok) { const msg = json.message || json['hydra:description'] || text || res.statusText; // Kalau error 503 atau 5xx, coba ulangi lagi beberapa detik kemudian if (res.status >= 500 && i < retries - 1) { await new Promise(r => setTimeout(r, 2000)); continue; } throw new Error(`API error: ${res.status} — ${msg}`); } return json; } catch (err) { if (i === retries - 1) throw err; await new Promise(r => setTimeout(r, 2000)); } } } function randomString(len) { return crypto.randomBytes(len).toString('hex').slice(0, len); } function parseContent(msgObj) { if (msgObj.text && msgObj.text.trim()) { return msgObj.text; } if (msgObj.html && msgObj.html.length > 0) { const htmlCombined = msgObj.html.join('\n'); let cleanText = htmlCombined .replace(/]*?\s+)?href="([^"]*)"[^>]*>(.*?)<\/a>/gi, '$2 ($1)') .replace(/<[^>]+>/g, '') .replace(/ /g, ' ') .trim(); return cleanText; } return '(tidak ada isi teks)'; } async function createNewEmail(customName) { const domains = await apiRequest('GET', '/domains'); if (!domains['hydra:member'] || domains['hydra:member'].length === 0) { throw new Error('Tidak ada domain mail.tm yang tersedia saat ini.'); } const domain = domains['hydra:member'][0].domain; const login = customName ? `${customName.toLowerCase().replace(/[^a-z0-9]/g, '')}${randomString(3)}` : `zvd${randomString(8)}`; const password = randomString(16); const address = `${login}@${domain}`; const accRes = await apiRequest('POST', '/accounts', { body: { address, password } }); const tokenRes = await apiRequest('POST', '/token', { body: { address, password } }); const state = { id: accRes.id, address, password, token: tokenRes.token, createdAt: new Date().toISOString(), }; saveState(state); console.log(`✅ Email sementara dibuat:`); console.log(`- ID Akun : ${state.id}`); console.log(`- Alamat : ${state.address}`); return state; } function requireState(targetEmail) { if (!targetEmail) { console.log('⚠️ Format salah! Wajib sertakan email.'); process.exit(1); } const state = loadState(); if (!state) { console.log('⚠️ Belum ada data email tersimpan di lokal.'); process.exit(1); } if (state.address.toLowerCase() !== targetEmail.toLowerCase()) { console.log(`⚠️ Email "${targetEmail}" tidak cocok atau tidak aktif di state lokal saat ini.`); console.log(`ℹ️ Email aktif: ${state.address}`); process.exit(1); } return state; } async function refreshTokenIfNeeded(state) { try { await apiRequest('GET', '/me', { token: state.token }); return state; } catch { const tokenRes = await apiRequest('POST', '/token', { body: { address: state.address, password: state.password }, }); state.token = tokenRes.token; saveState(state); return state; } } async function getInboxList(targetEmail) { let state = requireState(targetEmail); state = await refreshTokenIfNeeded(state); const listRes = await apiRequest('GET', '/messages', { token: state.token }); const messages = listRes['hydra:member'] || []; console.log(`📬 Inbox untuk ${state.address}`); if (messages.length === 0) { console.log(' (kosong, belum ada pesan masuk)'); return; } messages.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt)); for (const m of messages) { const snippet = m.intro || (m.text ? m.text.slice(0, 100) : '(tanpa teks preview)'); console.log('\n──────────────────────────────'); console.log(`ID Pesan : ${m.id}`); console.log(`Dari : ${m.from.address}`); console.log(`Subjek : ${m.subject}`); console.log(`Waktu : ${m.createdAt}`); console.log(`Isi : ${snippet.trim()}...`); console.log('──────────────────────────────'); } console.log(`\n💡 Tips: Untuk baca isi lengkap beserta link, ketik:`); console.log(` node email.js --read ${state.address} `); } async function readMessageDetail(targetEmail, messageId) { let state = requireState(targetEmail); if (!messageId) { console.log('⚠️ Wajib sertakan ID pesan! Contoh: node email.js --read '); process.exit(1); } state = await refreshTokenIfNeeded(state); try { const full = await apiRequest('GET', `/messages/${messageId}`, { token: state.token }); const contentParsed = parseContent(full); console.log('\n========================================'); console.log(`📩 DETAIL PESAN`); console.log('========================================'); console.log(`ID : ${full.id}`); console.log(`Dari : ${full.from.address}`); console.log(`Subjek : ${full.subject}`); console.log(`Waktu : ${full.createdAt}`); console.log('----------------------------------------'); console.log(contentParsed); console.log('========================================'); } catch (err) { console.error(`❌ Gagal mengambil pesan dengan ID "${messageId}":`, err.message); } } function printHelp() { console.log(` email.js — email sementara dari terminal (pakai mail.tm) node email.js --new [nama] bikin email baru node email.js --get list ringkas semua pesan + ID & setengah isi node email.js --read baca isi lengkap pesan tertentu (beserta link) node email.js tampilkan email yang lagi aktif `); } async function main() { const args = process.argv.slice(2); let cmd = args[0]; let targetParam = args[1]; let extraParam = args[2]; if (cmd && cmd.includes('@')) { targetParam = cmd; cmd = args[1]; extraParam = args[2]; } try { if (!cmd) { const state = loadState(); if (!state) { console.log('⚠️ Belum ada email aktif. Jalankan: node email.js --new'); } else { console.log(`📧 Email aktif: ${state.address}`); } return; } switch (cmd) { case '--new': await createNewEmail(targetParam); break; case '--get': await getInboxList(targetParam); break; case '--read': await readMessageDetail(targetParam, extraParam); break; case '--help': case '-h': printHelp(); break; default: console.log(`⚠️ Command "${cmd}" nggak dikenal.`); printHelp(); } } catch (err) { console.error('❌ Error:', err.message); process.exit(1); } } main();