Back to Home
Gistify Snippet
kyiov
Sep 8·1 file(s)
Public

Scraper akunlama.com

Scraper email sementara akunlama.com via REST API tanpa dependencies (fetch native). Support cek inbox, ekstrak OTP/link, dan watch real-time.

#javascript#scraper#tempmail#api
8
Raw
akunlama-scraper.jsjavascript
290 lines
1/**
2 * Usage:
3 * node scripts/akunlama-scraper.js -> Jalankan auto-test lengkap & generate akun
4 * node scripts/akunlama-scraper.js admin -> Cek pesan & detail inbox admin
5 * node scripts/akunlama-scraper.js generate -> Generate alamat email acak baru
6 * node scripts/akunlama-scraper.js admin watch -> Tunggu email baru masuk secara real-time
7 */
8
9const BASE_URL = 'https://akunlama.com/api';
10const DEFAULT_HEADERS = {
11 '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',
12 'Accept': 'application/json, text/plain, */*',
13 'Referer': 'https://akunlama.com/'
14};
15
16const ADJECTIVES = [
17 'sleepy', 'fluffy', 'sneaky', 'bouncy', 'fuzzy', 'lazy', 'happy', 'silly', 'clever',
18 'tiny', 'giant', 'swift', 'calm', 'wild', 'gentle', 'brave', 'quiet', 'loud',
19 'smooth', 'rough', 'bright', 'dark', 'warm', 'cool', 'playful', 'curious'
20];
21
22const ANIMALS = [
23 'kitten', 'cat', 'tiger', 'lion', 'panda', 'fox', 'wolf', 'bear', 'rabbit',
24 'mouse', 'bird', 'fish', 'frog', 'bee', 'butterfly', 'owl', 'penguin', 'dolphin'
25];
26
27function cleanRecipient(recipient) {
28 if (!recipient) return '';
29 return recipient.trim().replace(/@.*$/, '');
30}
31
32function generateRandomEmail() {
33 const adj = ADJECTIVES[Math.floor(Math.random() * ADJECTIVES.length)];
34 const animal = ANIMALS[Math.floor(Math.random() * ANIMALS.length)];
35 const num = Math.floor(Math.random() * 990) + 10;
36 return `${adj}-${animal}-${num}@akunlama.com`;
37}
38
39function htmlToPlainText(html) {
40 if (!html) return '';
41 return html
42 .replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '')
43 .replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '')
44 .replace(/<br\s*[\/]?>/gi, '\n')
45 .replace(/<\/(p|div|tr|h[1-6]|li)>/gi, '\n')
46 .replace(/<[^>]+>/g, '')
47 .replace(/&nbsp;/g, ' ')
48 .replace(/&amp;/g, '&')
49 .replace(/&lt;/g, '<')
50 .replace(/&gt;/g, '>')
51 .replace(/&quot;/g, '"')
52 .replace(/&#39;/g, "'")
53 .split('\n')
54 .map(line => line.trim())
55 .filter(Boolean)
56 .join('\n');
57}
58
59async function listMessages(recipient) {
60 const user = cleanRecipient(recipient);
61 const url = `${BASE_URL}/list?recipient=${encodeURIComponent(user)}`;
62 const res = await fetch(url, { headers: DEFAULT_HEADERS });
63 if (!res.ok) {
64 throw new Error(`Failed to fetch message list: ${res.status} ${res.statusText}`);
65 }
66 return await res.json();
67}
68
69async function getMessageDetail(region, key) {
70 const metaUrl = `${BASE_URL}/getKey?region=${encodeURIComponent(region)}&key=${encodeURIComponent(key)}`;
71 const htmlUrl = `${BASE_URL}/getHtml?region=${encodeURIComponent(region)}&key=${encodeURIComponent(key)}`;
72
73 const [metaRes, htmlRes] = await Promise.all([
74 fetch(metaUrl, { headers: DEFAULT_HEADERS }),
75 fetch(htmlUrl, { headers: DEFAULT_HEADERS })
76 ]);
77
78 const metadata = metaRes.ok ? await metaRes.json() : {};
79 const html = htmlRes.ok ? await htmlRes.text() : '';
80 const plainText = htmlToPlainText(html);
81
82 const codeMatches = plainText.match(/\b\d{4,8}\b/g) || [];
83 const extractedCodes = [...new Set(codeMatches)];
84
85 const linkMatches = html.match(/href=["'](https?:\/\/[^"']+)["']/gi) || [];
86 const extractedLinks = [...new Set(linkMatches.map(m => m.replace(/^href=["']|["']$/gi, '')))];
87
88 return {
89 metadata,
90 plainText,
91 html,
92 extractedCodes,
93 extractedLinks
94 };
95}
96
97async function watchInbox(recipient, intervalMs = 5000, timeoutMs = 60000) {
98 const user = cleanRecipient(recipient);
99 console.log(`[*] Watching inbox: ${user}@akunlama.com...`);
100
101 const initialList = await listMessages(user);
102 const knownKeys = new Set(
103 initialList.map(m => m.storage?.key).filter(Boolean)
104 );
105 console.log(`[*] ${knownKeys.size} pesan yang sudah ada.`);
106
107 const startTime = Date.now();
108 while (Date.now() - startTime < timeoutMs) {
109 await new Promise(resolve => setTimeout(resolve, intervalMs));
110 process.stdout.write('.');
111
112 try {
113 const currentList = await listMessages(user);
114 for (const msg of currentList) {
115 const key = msg.storage?.key;
116 if (key && !knownKeys.has(key)) {
117 console.log('\n\n[+] Email baru diterima!');
118 const region = msg.storage?.region || 'us';
119 return await getMessageDetail(region, key);
120 }
121 }
122 } catch (err) {
123 console.error(`\n[!] Error polling: ${err.message}`);
124 }
125 }
126
127 console.log('\n[-] Waktu habis tanpa pesan baru.');
128 return null;
129}
130
131async function runSelfTest() {
132 console.log('\n=============================================================');
133 console.log(' AKUNLAMA.COM SCRAPER - TEST OTOMATIS & GENERATE AKUN ');
134 console.log('=============================================================\n');
135
136 console.log('[1] MEMBUAT AKUN TEMPORARY BARU...');
137 const newEmail = generateRandomEmail();
138 const username = cleanRecipient(newEmail);
139 console.log(` ✓ Alamat Email : ${newEmail}`);
140 console.log(` ✓ Username : ${username}`);
141 console.log(` ✓ Web Inbox : https://akunlama.com/inbox/${newEmail}`);
142 console.log(` ✓ API Endpoint : ${BASE_URL}/list?recipient=${username}`);
143
144 console.log('\n[2] CEK STATUS INBOX AKUN BARU...');
145 const newInboxMessages = await listMessages(username);
146 console.log(' ✓ Status HTTP : 200 OK');
147 console.log(` ✓ Jumlah Pesan : ${newInboxMessages.length} (Inbox siap digunakan)`);
148
149 console.log('\n[3] PENGUJIAN SCRAPER LENGKAP PADA INBOX AKTIF (admin)...');
150 const testUser = 'admin';
151 const messages = await listMessages(testUser);
152 console.log(` ✓ Ditemukan ${messages.length} pesan di inbox '${testUser}@akunlama.com'`);
153
154 if (messages.length > 0) {
155 const sampleMsg = messages[0];
156 const storage = sampleMsg.storage || {};
157 const headers = sampleMsg.message?.headers || {};
158
159 console.log('\n --- Ringkasan Pesan ---');
160 console.log(` • Subject : ${headers.subject || '(Tanpa Subject)'}`);
161 console.log(` • From : ${headers.from || '(Tidak diketahui)'}`);
162 console.log(` • Preview : ${(sampleMsg.preview || '').trim().slice(0, 100)}`);
163 console.log(` • Region : ${storage.region} | Storage Key: ${storage.key}`);
164
165 if (storage.key && storage.region) {
166 console.log('\n[4] MENGAMBIL DETAIL KONTEN LENGKAP & EKSTRAKSI DATA...');
167 const detail = await getMessageDetail(storage.region, storage.key);
168
169 console.log(` ✓ Metadata Subject : ${detail.metadata.subject}`);
170 console.log(` ✓ Pengirim Asli : ${detail.metadata.name} <${detail.metadata.emailAddress}>`);
171 console.log(` ✓ Waktu Kirim : ${detail.metadata.Date}`);
172 console.log(` ✓ Ukuran Raw HTML : ${detail.html.length} bytes`);
173 console.log(` ✓ Panjang Teks : ${detail.plainText.length} karakter`);
174
175 if (detail.extractedCodes.length > 0) {
176 console.log(` ✓ Kode OTP/Verifikasi Terdeteksi: [ ${detail.extractedCodes.join(', ')} ]`);
177 } else {
178 console.log(' • Kode OTP/Verifikasi: Tidak ada kode angka');
179 }
180
181 if (detail.extractedLinks.length > 0) {
182 console.log(` ✓ Link/URL Terdeteksi (${detail.extractedLinks.length} link):`);
183 detail.extractedLinks.slice(0, 3).forEach((link, i) => {
184 const displayLink = link.length > 80 ? link.slice(0, 80) + '...' : link;
185 console.log(` [${i + 1}] ${displayLink}`);
186 });
187 }
188
189 console.log('\n --- Cuplikan Teks Bersih ---');
190 const snippetLines = detail.plainText.split('\n').filter(l => l.trim().length > 0).slice(0, 5);
191 snippetLines.forEach(l => console.log(` | ${l}`));
192 console.log(' ----------------------------');
193 }
194 }
195
196 console.log('\n=============================================================');
197 console.log(' PENGUJIAN SELESAI & SEMUA FUNGSI NORMAL ');
198 console.log('=============================================================\n');
199}
200
201async function main() {
202 const [target, action] = process.argv.slice(2);
203
204 if (!target) {
205 await runSelfTest();
206 return;
207 }
208
209 if (target === 'generate') {
210 const email = generateRandomEmail();
211 console.log(`Email Baru : ${email}`);
212 console.log(`Web Inbox URL: https://akunlama.com/inbox/${email}`);
213 return;
214 }
215
216 if (action === 'watch') {
217 const result = await watchInbox(target);
218 if (result) {
219 console.log('\n========================================');
220 console.log(`Subject : ${result.metadata.subject || '(Tanpa Subject)'}`);
221 console.log(`From : ${result.metadata.name || ''} <${result.metadata.emailAddress}>`);
222 console.log(`Date : ${result.metadata.Date}`);
223 if (result.extractedCodes.length > 0) {
224 console.log(`OTP : ${result.extractedCodes.join(', ')}`);
225 }
226 if (result.extractedLinks.length > 0) {
227 console.log(`Links : ${result.extractedLinks.slice(0, 3).join('\n ')}`);
228 }
229 console.log(`\nKonten:\n${result.plainText.slice(0, 400)}...\n`);
230 }
231 return;
232 }
233
234 const user = cleanRecipient(target);
235 const messages = await listMessages(user);
236
237 console.log('\n=======================================================');
238 console.log(` Inbox: ${user}@akunlama.com`);
239 console.log(` Total Pesan: ${messages.length}`);
240 console.log('=======================================================\n');
241
242 if (messages.length === 0) {
243 console.log('Inbox kosong. Belum ada pesan masuk.');
244 return;
245 }
246
247 for (let i = 0; i < messages.length; i++) {
248 const msg = messages[i];
249 const headers = msg.message?.headers || {};
250 const storage = msg.storage || {};
251
252 console.log(`[${i + 1}] Subject : ${headers.subject || '(Tanpa Subject)'}`);
253 console.log(` From : ${headers.from}`);
254 console.log(` Preview : ${(msg.preview || '').trim().slice(0, 80)}`);
255 console.log(` Region : ${storage.region} | Key: ${storage.key}`);
256
257 if (storage.key && storage.region) {
258 const detail = await getMessageDetail(storage.region, storage.key);
259 if (detail.extractedCodes.length > 0) {
260 console.log(` >> Kode OTP: ${detail.extractedCodes.join(', ')}`);
261 }
262 if (detail.extractedLinks.length > 0) {
263 console.log(` >> Link (${detail.extractedLinks.length}):`);
264 detail.extractedLinks.slice(0, 3).forEach(link => console.log(` - ${link}`));
265 }
266 console.log('\n --- Isi Pesan ---');
267 detail.plainText.split('\n').slice(0, 6).forEach(line => console.log(` ${line}`));
268 console.log(' -----------------\n');
269 }
270 console.log('-------------------------------------------------------');
271 }
272}
273
274module.exports = {
275 cleanRecipient,
276 generateRandomEmail,
277 htmlToPlainText,
278 listMessages,
279 getMessageDetail,
280 watchInbox,
281 runSelfTest
282};
283
284if (require.main === module) {
285 main().catch(err => {
286 console.error('Error:', err.message);
287 process.exit(1);
288 });
289}
290
Discussion & Comments0

No comments yet — be the first to leave feedback or start a code discussion.

Sign in with your GitHub account to write comments and join the discussion.