| |
| |
| |
| |
| async function recaptchaV2({ domain, siteKey, action = "submit", isInvisible = false, proxy }, page) { |
| if (!domain) throw new Error("Missing domain parameter"); |
| if (!siteKey) throw new Error("Missing siteKey parameter"); |
|
|
| |
| const timeout = global.timeOut || 300000; |
|
|
| return new Promise(async (resolve, reject) => { |
| let isResolved = false; |
|
|
| |
| const cl = setTimeout(() => { |
| if (!isResolved) { |
| isResolved = true; |
| reject(new Error("Timeout Error: Ext not responsive. Check logs & debug_captcha.png")); |
| } |
| }, timeout); |
|
|
| try { |
| const htmlContent = ` |
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>reCAPTCHA Solver</title> |
| <script src="https://www.google.com/recaptcha/api.js" async defer></script> |
| <style> |
| body { display: flex; justify-content: center; align-items: center; min-height: 100vh; background: #ffffff; margin: 0; } |
| </style> |
| </head> |
| <body> |
| <div class="g-recaptcha" data-sitekey="${siteKey}" data-size="${isInvisible ? 'invisible' : 'normal'}"></div> |
| <textarea id="g-recaptcha-response" name="g-recaptcha-response" style="display:none"></textarea> |
| </body> |
| </html> |
| `; |
|
|
| |
| await page.setRequestInterception(true); |
| page.removeAllListeners("request"); |
|
|
| page.on("request", async (req) => { |
| const url = req.url(); |
| const resource = req.resourceType(); |
|
|
| |
| if ([domain, domain + "/"].includes(url) && resource === "document") { |
| await req.respond({ status: 200, contentType: "text/html", body: htmlContent }); |
| } |
| |
| else if (["image", "font", "media"].includes(resource)) { |
| await req.abort(); |
| } |
| |
| else { |
| await req.continue(); |
| } |
| }); |
|
|
| console.log(`[SOLVER] Loading target with custom UI...`); |
| |
| await page.goto(domain, { waitUntil: "domcontentloaded", timeout: 60000 }); |
|
|
| |
| await new Promise(r => setTimeout(r, 5000)); |
|
|
| |
| console.log("[SOLVER] Attempting to click checkbox..."); |
| try { |
| |
| await page.waitForSelector('iframe[title*="reCAPTCHA"]', { timeout: 15000 }); |
| const frames = await page.frames(); |
| const anchorFrame = frames.find(f => f.url().includes('api2/anchor')); |
|
|
| if (anchorFrame) { |
| await anchorFrame.click('#recaptcha-anchor'); |
| console.log("[SOLVER] Checkbox clicked!"); |
| } |
| } catch (e) { |
| console.log(`[SOLVER] Warning: Could not click checkbox: ${e.message}`); |
| } |
|
|
| |
| |
| |
| console.log("[SOLVER] Taking debug screenshot..."); |
| await page.screenshot({ path: 'debug_captcha.png', fullPage: false }); |
| console.log("[SOLVER] Screenshot saved as debug_captcha.png. Cek di tab Files!"); |
|
|
| |
| console.log("[SOLVER] Waiting for rektCaptcha token..."); |
| const tokenValue = await page.waitForFunction(() => { |
| const input = document.querySelector('#g-recaptcha-response'); |
| return (input && input.value.length > 50) ? input.value : null; |
| }, { timeout, polling: 1000 }).then(h => h.jsonValue()); |
|
|
| isResolved = true; |
| clearTimeout(cl); |
| resolve({ data: tokenValue, status: "done" }); |
|
|
| } catch (error) { |
| if (!isResolved) { |
| isResolved = true; |
| clearTimeout(cl); |
| console.error("[SOLVER] Critical Error:", error.message); |
| |
| await page.screenshot({ path: 'debug_error.png' }); |
| reject(new Error(`Bypass failed: ${error.message}`)); |
| } |
| } |
| }); |
| } |
|
|
| module.exports = recaptchaV2; |
|
|