import axios from 'axios'; import type { Page } from 'puppeteer'; import { getImages } from './images'; import { getTarget } from './target'; import { randTimer, subscriptionType } from './type'; import { findURLParam, getApiUrl, sleep } from './utils'; /** * Solve captchas using `nocaptchaai.com` API service * * @param page - Puppeteer page instance * @param apiKey - API key * @param uid - UID * @param type - `free` or `pro` * @param debug - true or false */ export const solveCaptcha = async ( page: Page, apiKey: string, uid: string, type: subscriptionType, debug: boolean ): Promise => { const outer = await page.waitForSelector('iframe[data-hcaptcha-response]'); const outerFrame = await outer?.contentFrame(); const inner = await page.waitForSelector('iframe:not([data-hcaptcha-response])'); const innerFrame = await inner?.contentFrame(); if (!outerFrame) throw new Error('solveCaptcha: captcha outer frame not found'); if (!innerFrame) throw new Error('solveCaptcha: captcha inner frame not found'); const checkbox = await outerFrame.waitForSelector('#checkbox'); if (!(await innerFrame.$('.challenge'))) await checkbox?.click(); // await sleep(500000); // debug waiting try { // const language = await page.evaluate(() => document.documentElement.lang); // doesn't work const language = await innerFrame.evaluate(() => document.documentElement.lang); if (debug) console.log('🌍 Language found = ', language); const sitekey = findURLParam(new URLSearchParams(innerFrame.url()), key => key.includes('sitekey') )[1]; await innerFrame.waitForSelector('.challenge-container', { timeout: 10 * 1000 }); while ((await outerFrame.$('#checkbox[aria-checked=false]')) !== null) { const images = await getImages(innerFrame); if (debug && images) console.log('🔍 Puzzle Images found'); const target = await getTarget(innerFrame); if (debug && target) console.log('🔍 Target = ', target); const imageElements = await innerFrame.$$('.task-image'); if (!imageElements) throw new Error('solveCaptcha: captcha images not found'); const { data: query } = await axios.post( getApiUrl(type), { softid: 'pptr-pkg', method: 'hcaptcha_base64', site: page.url(), ln: language, sitekey, images, target }, { headers: { 'Content-type': 'application/json', 'apikey': apiKey, 'uid': uid } } ); switch (query.status) { case 'solved': { console.log('✅', query.status); console.log('---------✓---------'); for (const item of query.solution) { await imageElements[item].click(); await sleep(randTimer(200, 350)); // await sleep(200); } break; } case 'new': { if (debug) console.log('⏳ waiting a second'); for (let i = 0; i < 10; i++) { await sleep(1000); const { data: result } = await axios.get(query.url); if (result.status === 'solved') { if (debug) console.log('🖲️ clicking images'); for (const item of result.solution) { await imageElements[item].click(); await sleep(randTimer(200, 350)); // await sleep(200); } break; } } break; } case 'skip': { console.log('😨 Seems this a new challenge, please contact noCaptchaAi!'); console.error(query.message); throw new Error('😨 Seems this a new challenge, please contact noCaptchaAi!'); } case 'error': { console.log('😨 Error'); console.error(query.message); throw new Error('😨 Error'); } default: { console.log('😨 Unknown status'); console.error(query); throw new Error('😨 Unknown status'); } } const button = await innerFrame.$('.button-submit'); if (debug) console.log('⌛ waiting a second'); await button?.click(); await sleep(1000); } } catch (err) { const isSolved = (await outerFrame.$('#checkbox[aria-checked=true]')) !== null; if (debug) console.log('☑️ Seems puzzle solved'); if (!isSolved) throw err; if (debug && !isSolved) console.log("⁉️ couldn't solve"); } };