const express = require('express'); const puppeteer = require('puppeteer-extra'); puppeteer.use(require('puppeteer-extra-plugin-stealth')()); const path = require('path'); const app = express(); const port = process.env.PORT || 7860; const HTML_TEMPLATE = ` Turnstile Solver
`; const sleep = (ms) => new Promise(r => setTimeout(r, ms)); async function solveTurnstile(url, sitekey) { const browser = await puppeteer.launch({ headless: "new", executablePath: process.env.PUPPETEER_EXECUTABLE_PATH || null, args: [ "--no-sandbox", "--disable-setuid-sandbox", "--disable-dev-shm-usage", "--disable-blink-features=AutomationControlled" ] }); try { const page = await browser.newPage(); const urlFixed = url.endsWith("/") ? url : url + "/"; await page.setRequestInterception(true); page.on('request', (req) => { if (req.url() === urlFixed && req.resourceType() === 'document') { const html = HTML_TEMPLATE.replace('id="turnstile-widget"', `id="turnstile-widget" data-sitekey="${sitekey}"`); req.respond({ status: 200, contentType: 'text/html', body: html }); } else { req.continue(); } }); await page.goto(urlFixed, { waitUntil: 'domcontentloaded' }); // Tunggu iframe muncul dan klik jika perlu await page.waitForSelector('.cf-turnstile', { timeout: 10000 }); await sleep(2000); // Polling token for (let i = 0; i < 30; i++) { const token = await page.evaluate(() => window.capturedToken || null); if (token) { await browser.close(); return token; } await sleep(1000); } throw new Error("Timeout: Gagal mendapatkan token Turnstile"); } catch (err) { await browser.close(); throw err; } } app.get('/solve', async (req, res) => { const { url, siteKey } = req.query; if (!url || !siteKey) { return res.status(400).json({ error: "Parameter 'url' dan 'siteKey' diperlukan" }); } try { console.log(`Menyelesaikan Turnstile untuk: ${url}`); const token = await solveTurnstile(url, siteKey); res.json({ result: token }); } catch (error) { console.error(error); res.status(500).json({ error: error.message }); } }); app.get('/', (req, res) => { res.send('Turnstile Solver API sedang berjalan. Gunakan endpoint /solve'); }); app.listen(port, () => { console.log(`Server berjalan di port ${port}`); });