UNPKG

auto-captcha-solver

Version:

Automatically detect and solve various captcha types in Playwright & Puppeteer with 2Captcha/CapMonster Cloud integration

382 lines 15.7 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.solveWith2Captcha = solveWith2Captcha; const captcha_solver_1 = require("@2captcha/captcha-solver"); const fs_1 = require("fs"); const path_1 = __importDefault(require("path")); const inject_captcha_response_1 = require("../../../utils/inject-captcha-response"); const find_captcha_image_url_1 = require("../../../utils/find-captcha-image-url"); // Function to handle the 2Captcha CAPTCHA solving async function solveWith2Captcha(captchaInfo, captchaData, page) { const solver = new captcha_solver_1.Solver(captchaInfo.apiKey); switch (captchaData.type) { case 'Image To Text': { try { // Get CAPTCHA image element with enhanced waiting const captchaImage = await page.waitForSelector(captchaInfo.imageSelector || '', { timeout: 15000, state: 'visible' }); if (!captchaImage) { return { success: false, message: 'CAPTCHA image element not found' }; } console.log({ captchaImage }); // Get image source URL with validation // const imageUrl = await captchaImage.evaluate(`(function(el) { // if (!(el instanceof HTMLImageElement)) { // throw new Error('Element is not an image'); // } // return el.src; // })();`); const imageUrl = await (0, find_captcha_image_url_1.getCaptchaSource)(page, captchaInfo.imageSelector || ''); console.log({ imageUrl }); if (!imageUrl) { return { success: false, message: 'CAPTCHA image source not found' }; } // Fetch image directly using Node.js HTTP client const response = await fetch(String(imageUrl)); if (!response.ok) { return { success: false, message: `Failed to fetch CAPTCHA image: ${response.status} ${response.statusText}` }; } // Convert response to base64 const buffer = await response.arrayBuffer(); const imageBase64 = Buffer.from(buffer).toString('base64'); // Create Image to Text request with enhanced options const solution = await solver.imageCaptcha({ body: imageBase64, numeric: captchaInfo.numericCount || 2, min_len: captchaInfo.minLength || 5, max_len: captchaInfo.maxLength || 6, calc: captchaInfo.math ? 1 : 0 }); if (!solution.data) { return { success: false, message: 'CAPTCHA solving service returned empty solution' }; } // Enhanced input handling const inputSelector = captchaInfo.inputSelector || ''; await page.waitForSelector(inputSelector, { state: 'visible', timeout: 5000 }); await page.fill(inputSelector, solution.data); return { success: true, message: `CAPTCHA solved: ${solution.data}` }; } catch (error) { return { success: false, message: `CAPTCHA error: ${error.message}` }; } } case 'reCAPTCHA v2': { const solution = (await solver.recaptcha({ pageurl: page.url(), googlekey: captchaData.siteKey || '', version: 'v2' })); if (solution?.data) { // Inject CAPTCHA response into the page const success = await (0, inject_captcha_response_1.injectTokenResponse)(page, 'textarea[name="g-recaptcha-response"]', solution.data); if (success) { return { success: true, message: `reCAPTCHA v2 solved successfully.` }; } } return { success: false, message: `Failed to inject reCAPTCHA v2 token.` }; } case 'reCAPTCHA v2 Invisible': { const solution = (await solver.recaptcha({ pageurl: page.url(), googlekey: captchaData.siteKey || '', version: 'v2', invisible: 1 })); if (solution?.data) { // Inject CAPTCHA response into the page const success = await (0, inject_captcha_response_1.injectTokenResponse)(page, '#g-recaptcha-response', solution.data); if (success) { return { success: true, message: `reCAPTCHA v2 Invisible solved successfully.` }; } } return { success: false, message: `Failed to inject reCAPTCHA v2 Invisible token.` }; } case 'reCAPTCHA v3': { const solution = (await solver.recaptcha({ pageurl: page.url(), googlekey: captchaData.siteKey || '', version: 'v3', min_score: 0.6, action: 'submit' })); if (solution?.data) { const success = await (0, inject_captcha_response_1.injectReCaptchaV3Response)(page, solution.data); if (success) { return { success: true, message: `reCAPTCHA v3 solved successfully.` }; } } return { success: false, message: `Failed to inject reCAPTCHA v3 token.` }; } case 'reCAPTCHA Enterprise': { const solution = await solver.recaptcha({ pageurl: page.url(), googlekey: captchaData.siteKey || '', version: 'v3', min_score: 0.6, enterprise: 1, action: 'submit' }); if (solution?.data) { // Inject CAPTCHA response into the page const success = await (0, inject_captcha_response_1.injectTokenResponse)(page, 'textarea[name="g-recaptcha-response"]', solution.data); if (success) { return { success: true, message: `reCAPTCHA Enterprise solved successfully.` }; } } return { success: false, message: `Failed to inject reCAPTCHA Enterprise token.` }; } case 'GeeTest V4 Captcha': { const solution = await solver.geetestV4({ pageurl: page.url(), captcha_id: captchaData.captchaId ?? '' }); if (solution?.data) { try { const injectionSuccess = await (0, inject_captcha_response_1.injectGeeTestV4Solution)(page, solution.data || {}); console.log({ injectionSuccess }); // Now shows true/false if (injectionSuccess) { return { success: true, message: `GeeTest V4 solved` }; } return { success: false, message: 'Captcha injection failed verification' }; } catch (error) { return { success: false, message: `GeeTest V4 error: ${error.message}` }; } } return { success: false, message: 'No captcha solution received' }; } case 'Text Captcha': { const textSelector = captchaInfo.textSelector; const inputSelector = captchaInfo.inputSelector; try { if (!textSelector || !inputSelector) { return { success: false, message: 'Text Captcha or Input selector not found' }; } await page.waitForSelector(textSelector, { state: 'visible', timeout: 5000 }); const textQuestion = await page.locator(textSelector).innerText(); const solution = (await solver.text({ textcaptcha: textQuestion, lang: captchaInfo.textLanguage || 'en' })); if (solution.status === 1 && solution.data) { await page.waitForSelector(inputSelector, { state: 'visible', timeout: 5000 }); await page.fill(inputSelector, solution.data); return { success: true, message: `Text Captcha solved: ${solution.data}` }; } return { success: false, message: `Failed to solve Text Captcha` }; } catch (error) { return { success: false, message: `Text Captcha error: ${error.message}` }; } } // case 'KeyCaptcha': { // const solution = await solver.keyCaptcha({ // pageurl: page.url(), // userId: captchaData.userId || '', // sessionId: captchaData.sessionId || '', // webServerSign: captchaData.sign || '', // webServerSign2: captchaData.sign2 || '' // }); // return { // success: false, // message: `Failed to inject reCAPTCHA Enterprise token.` // }; // } case 'hCaptcha': { try { const solution = await solver.hcaptcha({ pageurl: page.url(), sitekey: captchaData.siteKey }); if (solution.data) { const success = await (0, inject_captcha_response_1.injectTokenResponse)(page, 'textarea[name="h-captcha-response"]', solution.data); if (success) { return { success: true, message: `hCaptcha successfully solved ` }; } } return { success: false, message: `Failed to inject hCaptcha token.` }; } catch (error) { return { success: false, message: `CAPTCHA error: ${error.message}` }; } } case 'Cloudflare Turnstile': { const solution = (await solver.cloudflareTurnstile({ pageurl: page.url(), sitekey: captchaData.siteKey || '' })); if (solution?.status === 1 && solution?.data) { const success = await (0, inject_captcha_response_1.injectTokenResponse)(page, '[name="cf-turnstile-response"]', solution.data); if (success) { return { success: true, message: `Cloudflare Turnstile solved successfully.` }; } } return { success: false, message: `Failed to inject Cloudflare Turnstile token.` }; } case 'Cloudflare CAPTCHA': { // Inject script on every new document try { const preloadFile = (0, fs_1.readFileSync)(path_1.default.join(__dirname, '../2captcha/cloud-flare-inject.js'), 'utf8'); await page.addInitScript(preloadFile); // Expose function to handle CAPTCHA callback await page.exposeFunction('cfCallback', async (token) => { return token; }); // Intercept console messages page.on('console', async (msg) => { const txt = msg.text(); if (txt.includes('intercepted-params:')) { const params = JSON.parse(txt.replace('intercepted-params:', '')); try { const res = await solver.cloudflareTurnstile(params); // Inject solution into the page const evaluateScript = `(function() { window.cfCallback(${res.data}); })();`; await page.evaluate(evaluateScript); } catch (error) { console.error(`Error solving CAPTCHA: ${error.message}`); process.exit(1); } } }); return { success: true, message: 'Cloud Flare captcha is solved' }; } catch (error) { return { success: false, message: `CAPTCHA error: ${error.message}` }; } } case 'MTCaptcha': { try { const solution = (await solver.mtCaptcha({ pageurl: page.url(), sitekey: captchaData.siteKey || '' })); if (solution?.status === 1 && solution?.data) { const success = await (0, inject_captcha_response_1.injectTokenResponse)(page, 'input[name="mtcaptcha-verifiedtoken"]', solution.data); if (success) { return { success: true, message: `MTCaptcha solved successfully.` }; } } return { success: false, message: `Failed to solved MTCaptcha ` }; } catch (error) { return { success: false, message: `CAPTCHA error: ${error.message}` }; } } default: return { success: false, message: `Unsupported CAPTCHA type: ${captchaData.type}` }; } } //# sourceMappingURL=two-captcha.js.map