Spaces:
Paused
Paused
| // 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 }; | |