auto-captcha-solver
Version:
Automatically detect and solve various captcha types in Playwright & Puppeteer with 2Captcha/CapMonster Cloud integration
285 lines • 14.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.solveWithCapMonster = solveWithCapMonster;
const inject_captcha_response_1 = require("../../../utils/inject-captcha-response");
const capmonster_api_1 = require("./capmonster-api");
/**
* Solve CAPTCHA using CapMonster Cloud
*/
async function solveWithCapMonster(captchaInfo, captchaData, page) {
const apiKey = captchaInfo.apiKey;
try {
switch (captchaData.type) {
case 'Image To Text': {
try {
// Get CAPTCHA image element with enhanced waiting
const captchaImage = await page.waitForSelector(captchaInfo.imageSelector || 'img[alt*="captcha"], .captcha-img', {
timeout: 15000,
state: 'visible'
});
if (!captchaImage) {
return {
success: false,
message: 'CAPTCHA image element not found'
};
}
console.log('bello1');
const imageScript = `(function(el: HTMLImageElement) {
if (!(el instanceof HTMLImageElement)) {
throw new Error('Element is not an image');
}
return el.src;
})();`;
// Get image source URL with validation
const imageUrl = await captchaImage.evaluate(imageScript);
console.log('bello2');
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');
/* Using via official Package of Capmonster*/
// ------------------------------------------------
// Create Image to Text request with enhanced options
// const imageToTextRequest = new ImageToTextRequest({
// body: imageBase64,
// CapMonsterModule: captchaInfo.module || CapMonsterModules.BotDetect,
// Case: captchaInfo.caseSensitive || false,
// numeric: captchaInfo.numericCount ? 1 : 0,
// recognizingThreshold: captchaInfo.threshold || 65,
// math: captchaInfo.math || false
// });
// ------------------------------------------------
/* Using via official Api call of Capmonster*/
// ------------------------------------------------
const taskId = await (0, capmonster_api_1.createCapMonsterTask)(apiKey, {
type: 'ImageToTextTask',
body: imageBase64,
// capMonsterModule: captchaInfo.module || 'BotDetect',
case: captchaInfo.caseSensitive || false,
numeric: captchaInfo.numericCount ? 1 : 0,
recognizingThreshold: captchaInfo.threshold || 65,
math: captchaInfo.math || false
});
const solution = await (0, capmonster_api_1.getCapMonsterTaskResult)(apiKey, taskId);
// ------------------------------------------------
console.log({ solution });
if (!solution?.text) {
return {
success: false,
message: 'CAPTCHA solving service returned empty solution'
};
}
// Enhanced input handling
const inputSelector = captchaInfo.inputSelector ||
'input[name*="captcha"], #captcha, .captcha-input';
await page.waitForSelector(inputSelector, {
state: 'visible',
timeout: 5000
});
await page.fill(inputSelector, solution.text);
return {
success: true,
message: `CAPTCHA solved: ${solution.text}`
};
}
catch (error) {
return {
success: false,
message: `CAPTCHA error: ${error.message}`
};
}
}
case 'reCAPTCHA v2': {
/* Using via official Package of Capmonster*/
// ------------------------------------------------
// const recaptchaV2Request = new RecaptchaV2ProxylessRequest({
// websiteURL: page.url(),
// websiteKey: captchaData.siteKey ?? ''
// });
// const {solution} = await capMonsterClient.Solve(recaptchaV2Request);
// ------------------------------------------------
/* Using via official Api call of Capmonster*/
// ------------------------------------------------
const taskId = await (0, capmonster_api_1.createCapMonsterTask)(apiKey, {
type: 'RecaptchaV2TaskProxyless',
websiteURL: page.url(),
websiteKey: captchaData.siteKey ?? ''
});
const solution = await (0, capmonster_api_1.getCapMonsterTaskResult)(apiKey, taskId);
// ------------------------------------------------
if (solution) {
// Inject CAPTCHA response into the page
const success = await (0, inject_captcha_response_1.injectTokenResponse)(page, 'textarea[name="g-recaptcha-response"]', solution.gRecaptchaResponse || '');
if (success) {
return {
success: true,
message: `reCAPTCHA v2 solved successfully.`
};
}
}
return {
success: false,
message: `Failed to inject reCAPTCHA v2 token.`
};
}
case 'reCAPTCHA v3': {
/* Using via official Package of Capmonster*/
// ------------------------------------------------
// const recaptchaV3Request = new RecaptchaV3ProxylessRequest({
// websiteURL: page.url(),
// websiteKey: captchaData.siteKey ?? '',
// minScore: 0.6, // Default min score
// pageAction: 'submit' // Adjust based on the site’s needs
// });
// const { solution } = await capMonsterClient.Solve(recaptchaV3Request);
// ------------------------------------------------
/* Using via official Api call of Capmonster*/
// ------------------------------------------------
const taskId = await (0, capmonster_api_1.createCapMonsterTask)(apiKey, {
type: 'RecaptchaV3TaskProxyless',
websiteURL: page.url(),
websiteKey: captchaData.siteKey ?? '',
minScore: 0.3,
pageAction: 'submit'
});
const solution = await (0, capmonster_api_1.getCapMonsterTaskResult)(apiKey, taskId);
// ------------------------------------------------
if (solution?.gRecaptchaResponse) {
const success = await (0, inject_captcha_response_1.injectReCaptchaV3Response)(page, solution.gRecaptchaResponse);
if (success) {
return {
success: true,
message: `reCAPTCHA v3 solved successfully.`
};
}
}
return {
success: false,
message: `Failed to inject reCAPTCHA v3 token.`
};
}
case 'Cloudflare Turnstile': {
/* Using via official Package of Capmonster*/
// ------------------------------------------------
// const turnstileRequest = new TurnstileProxylessRequest({
// websiteURL: page.url(),
// websiteKey: captchaData.siteKey ?? ''
// });
// const { solution } = await capMonsterClient.Solve(turnstileRequest);
// ------------------------------------------------
/* Using via official Api call of Capmonster*/
// ------------------------------------------------
const taskId = await (0, capmonster_api_1.createCapMonsterTask)(apiKey, {
type: 'TurnstileTaskProxyless',
websiteURL: page.url(),
websiteKey: captchaData.siteKey ?? ''
});
const solution = await (0, capmonster_api_1.getCapMonsterTaskResult)(apiKey, taskId);
// ------------------------------------------------
if (solution?.token) {
const success = await (0, inject_captcha_response_1.injectTokenResponse)(page, '[name="cf-turnstile-response"]', solution.token);
if (success) {
return {
success: true,
message: `Cloudflare Turnstile solved successfully.`
};
}
}
return {
success: false,
message: `Failed to inject Cloudflare Turnstile token.`
};
}
// case 'GeeTest Captcha': {
// const taskInfo = {
// type: 'GeeTestTaskProxyless',
// websiteURL: page.url(),
// gt: captchaData.gt ?? '',
// challenge: captchaData.challenge ?? ''
// };
// const taskId = await createCapMonsterTask(captchaInfo.apiKey, taskInfo);
// const solution = await getCapMonsterTaskResult(captchaInfo.apiKey, taskId);
// break;
// }
case 'GeeTest V4 Captcha': {
/* Using via official Package of Capmonster*/
// ------------------------------------------------
// const geetestRequest = new GeeTestProxylessRequest({
// websiteURL: page.url(),
// gt: captchaData.captchaId ?? '',
// version: '4',
// initParameters: {
// riskType: captchaData.riskType || 'slide'
// }
// });
// const { solution } = (await capMonsterClient.Solve(
// geetestRequest
// )) as CaptchaResult<GeeTestResponseV4>;
// ------------------------------------------------
/* Using via official Api call of Capmonster*/
// ------------------------------------------------
const taskId = await (0, capmonster_api_1.createCapMonsterTask)(apiKey, {
type: 'GeeTestTaskProxyless',
websiteURL: page.url(),
gt: captchaData.captchaId ?? '',
version: '4',
initParameters: {
riskType: captchaData.riskType || 'slide'
}
});
const startTime = Date.now();
const solution = await (0, capmonster_api_1.getCapMonsterTaskResult)(apiKey, taskId);
if (!solution) {
return {
success: false,
message: 'No captcha solution received'
};
}
try {
const injectionSuccess = await (0, inject_captcha_response_1.injectGeeTestV4Solution)(page, solution);
console.log({ injectionSuccess }); // Now shows true/false
if (injectionSuccess) {
return {
success: true,
message: `GeeTest V4 solved in ${Date.now() - startTime}ms`
};
}
return {
success: false,
message: 'Captcha injection failed verification'
};
}
catch (error) {
return {
success: false,
message: `GeeTest V4 error: ${error.message}`
};
}
}
default:
throw new Error(`Unsupported CAPTCHA type: ${captchaData.type}`);
}
}
catch (error) {
return { success: false, message: `Error solving ${captchaData.type}: ${error.message}` };
}
return {
success: false,
message: `Failed to solve CAPTCHA for ${captchaData.type}.`
};
}
//# sourceMappingURL=capmonster.js.map