'use strict'; const express = require('express'); const TurnstileSolver = require('./turnstile-solver'); const app = express(); const PORT = process.env.PORT || 7860; app.use(express.json()); // Singleton solver — browser tetap hidup selama server berjalan const solver = new TurnstileSolver({ timeout: 25000, record: false, width: 1280, height: 720, }); // Inisialisasi browser saat startup let ready = false; (async () => { try { await solver.initialize(); ready = true; console.log('[API] Solver ready.'); } catch (e) { console.error('[API] Solver init failed:', e.message); } })(); /** * GET /bypass/turnstile-min * Query params: * - url : URL target (wajib) * - siteKey : Sitekey Turnstile (opsional, kalau tidak ada pakai mode page) * - apikey : API key sederhana untuk proteksi (opsional, cek env API_KEY) * * Response (sukses): * { status: true, token: "...", time: 3.2 } * * Response (gagal): * { status: false, message: "..." } */ app.get('/bypass/turnstile-min', async (req, res) => { // Cek API key kalau dikonfigurasi const apiKey = process.env.API_KEY; if (apiKey && req.query.apikey !== apiKey) { return res.status(401).json({ status: false, message: 'Invalid API key.' }); } const { url, siteKey } = req.query; if (!url) { return res.status(400).json({ status: false, message: 'Parameter "url" wajib diisi.' }); } if (!ready) { return res.status(503).json({ status: false, message: 'Solver belum siap, coba lagi sebentar.' }); } try { const result = await solver.solve(url, siteKey || null); if (!result.success) { return res.status(500).json({ status: false, message: result.error || 'Gagal mendapatkan token Turnstile.', time: result.time, }); } return res.json({ status: true, creator: 'XAi Community', token: result.token, time: result.time, }); } catch (e) { return res.status(500).json({ status: false, message: e.message }); } }); // Health check app.get('/', (req, res) => { res.json({ status: 'ok', ready, endpoints: [ 'GET /bypass/turnstile-min?url=&siteKey=&apikey=', 'GET /debug/screenshot — lihat screenshot terakhir saat solving gagal', ], }); }); // Debug: lihat screenshot terakhir const fs = require('fs'); app.get('/debug/screenshot', (req, res) => { const p = '/tmp/debug_turnstile.png'; if (!fs.existsSync(p)) return res.status(404).json({ error: 'Belum ada screenshot.' }); res.sendFile(p); }); app.listen(PORT, '0.0.0.0', () => { console.log(`[API] Server jalan di port ${PORT}`); }); // Cleanup saat proses mati process.on('SIGTERM', async () => { await solver.cleanup(); process.exit(0); });