Crawlr-Browser / src /captcha.js
senku21230's picture
Upload 11 files
ce9e053 verified
Raw
History Blame Contribute Delete
5.2 kB
// src/captcha.js β€” Optional CAPTCHA solving (2captcha / CapSolver)
const fetch = require("node-fetch");
const CAPTCHA_KEY = process.env.CAPTCHA_API_KEY;
const CAPTCHA_SERVICE = process.env.CAPTCHA_SERVICE || "2captcha"; // "2captcha" বা "capsolver"
// ── 2captcha ──────────────────────────────────────────────────────────────
async function solve2captcha(type, params) {
const baseUrl = "https://2captcha.com";
// Submit
const submitRes = await fetch(`${baseUrl}/in.php`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ key: CAPTCHA_KEY, method: type, json: 1, ...params }),
});
const submitData = await submitRes.json();
if (submitData.status !== 1) throw new Error(`2captcha submit failed: ${submitData.request}`);
const taskId = submitData.request;
// Poll result
for (let i = 0; i < 24; i++) {
await new Promise((r) => setTimeout(r, 5000));
const res = await fetch(`${baseUrl}/res.php?key=${CAPTCHA_KEY}&action=get&id=${taskId}&json=1`);
const data = await res.json();
if (data.status === 1) return data.request;
if (data.request !== "CAPCHA_NOT_READY") throw new Error(`2captcha error: ${data.request}`);
}
throw new Error("2captcha timeout");
}
// ── CapSolver ─────────────────────────────────────────────────────────────
async function solveCapsolver(type, params) {
const res = await fetch("https://api.capsolver.com/createTask", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ clientKey: CAPTCHA_KEY, task: { type, ...params } }),
});
const data = await res.json();
if (data.errorId) throw new Error(`CapSolver error: ${data.errorDescription}`);
const taskId = data.taskId;
for (let i = 0; i < 24; i++) {
await new Promise((r) => setTimeout(r, 5000));
const res2 = await fetch("https://api.capsolver.com/getTaskResult", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ clientKey: CAPTCHA_KEY, taskId }),
});
const result = await res2.json();
if (result.status === "ready") return result.solution?.gRecaptchaResponse || result.solution?.token;
if (result.errorId) throw new Error(`CapSolver: ${result.errorDescription}`);
}
throw new Error("CapSolver timeout");
}
// ── Main solver ───────────────────────────────────────────────────────────
async function solveCaptcha(type, params) {
if (!CAPTCHA_KEY) throw new Error("CAPTCHA_API_KEY নেই");
if (CAPTCHA_SERVICE === "capsolver") return solveCapsolver(type, params);
return solve2captcha(type, params);
}
// ── reCAPTCHA v2 solve + inject ───────────────────────────────────────────
async function solveRecaptchaV2(page) {
if (!CAPTCHA_KEY) return false;
try {
const siteKey = await page.evaluate(() => {
const el = document.querySelector(".g-recaptcha,[data-sitekey]");
return el?.dataset?.sitekey || null;
});
if (!siteKey) return false;
console.log("πŸ€– reCAPTCHA v2 solve করছি...");
const token = await solveCaptcha("userrecaptcha", { googlekey: siteKey, pageurl: page.url() });
await page.evaluate((t) => {
document.getElementById("g-recaptcha-response").innerHTML = t;
if (window.___grecaptcha_cfg) {
const entries = Object.entries(window.___grecaptcha_cfg.clients || {});
if (entries.length) entries[0][1]?.aa?.l?.click?.();
}
}, token);
return true;
} catch (err) {
console.warn("CAPTCHA solve failed:", err.message);
return false;
}
}
// ── hCaptcha solve ────────────────────────────────────────────────────────
async function solveHcaptcha(page) {
if (!CAPTCHA_KEY) return false;
try {
const siteKey = await page.evaluate(() =>
document.querySelector("[data-hcaptcha-widget-id],[data-sitekey]")?.dataset?.sitekey || null
);
if (!siteKey) return false;
console.log("πŸ€– hCaptcha solve করছি...");
const token = CAPTCHA_SERVICE === "capsolver"
? await solveCapsolver("HCaptchaTaskProxyLess", { websiteURL: page.url(), websiteKey: siteKey })
: await solve2captcha("hcaptcha", { sitekey: siteKey, pageurl: page.url() });
await page.evaluate((t) => {
const ta = document.querySelector("[name=h-captcha-response]");
if (ta) ta.value = t;
}, token);
return true;
} catch (err) {
console.warn("hCaptcha solve failed:", err.message);
return false;
}
}
function isAvailable() { return !!CAPTCHA_KEY; }
module.exports = { solveCaptcha, solveRecaptchaV2, solveHcaptcha, isAvailable };