diff --git a/README.md b/README.md index 2374036..0559ab0 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ Examples of API requests for different captcha types are available on the [JavaS - [VkImage](#vkimage) - [VkCaptcha](#vkcaptcha) - [Temu](#temu) + - [Altcha](#altcha) - [Audio Captcha](#audio-captcha) - [Other methods](#other-methods) - [goodReport](#goodreport) @@ -737,6 +738,25 @@ console.log(err); }) ``` +### Altcha + +[API method description.](https://2captcha.com/2captcha-api#altchacaptcha) + +This method can be used to solve Altcha captcha. Returns a token. + +```js +solver.altcha({ + pageurl: "https://mysite.com/page/with/altcha", + challenge_url: "https://example/altcha", +}) +.then((res) => { +console.log(res); +}) +.catch((err) => { +console.log(err); +}) +``` + ### Audio Captcha [API method description.](https://2captcha.com/2captcha-api#audio-recognition) diff --git a/examples/altcha.js b/examples/altcha.js new file mode 100644 index 0000000..13e5b55 --- /dev/null +++ b/examples/altcha.js @@ -0,0 +1,16 @@ +const TwoCaptcha = require("../dist/index.js"); +require('dotenv').config(); +const APIKEY = process.env.APIKEY +const solver = new TwoCaptcha.Solver(APIKEY); + +solver.altcha({ + pageurl: "https://mysite.com/page/with/altcha", + challenge_url: "https://example/altcha", + // challenge_json: '{"algorithm":"SHA-256","challenge":"a4c9d8e7f1b23a6c...",..."signature":"7b3e2a9d5c8f1046e2d91c3a..."}' +}) +.then((res) => { + console.log(res); +}) +.catch((err) => { + console.log(err); +}) \ No newline at end of file diff --git a/src/structs/2captcha.ts b/src/structs/2captcha.ts index 2d16c43..41d36e0 100644 --- a/src/structs/2captcha.ts +++ b/src/structs/2captcha.ts @@ -302,6 +302,14 @@ export interface paramsTemu { part3: string, } +export interface paramsAltcha { + pageurl: string, + challengeUrl?: string, + challengeJson?: string, + proxy?: string, + proxytype?: string, +} + export interface paramsAudioCaptcha { body: string, lang: string, @@ -2144,6 +2152,64 @@ public async temu(params: paramsTemu): Promise { } } +/** + * ### Solves Altcha Captcha + * + * This method can be used to solve Altcha captcha. Returns a token. + * [Read more about Altcha Method](https://2captcha.com/2captcha-api#altchacaptcha). + * + * @param {{ pageurl, challenge_url, challenge_json, proxy, proxytype}} params Parameters Altcha as an object. + * @param {string} params.pageurl Full URL of the page where you solve the captcha. + * @param {string} params.challenge_url The value of the 'challenge_url' parameter for the 'altcha-widget' element containing the captcha on the page. You can send either challenge_url or challenge_json parameter, but not two of it simultaneously. + * @param {string} params.challenge_json The contents of the file from the 'challenge_url' parameter. You can send either challenge_url or challenge_json parameter, but not two of it simultaneously. + * @param {string} params.proxy Format: `login:password@123.123.123.123:3128` You can find more info about proxies [here](https://2captcha.com/2captcha-api#proxies). + * @param {string} params.proxytype Type of your proxy: `HTTP`, `HTTPS`, `SOCKS4`, `SOCKS5`. + * + * @example + * solver.altcha({ + * pageurl: "https://mysite.com/page/with/altcha", + * challenge_url: "https://example/altcha", + * }) + * .then((res) => { + * console.log(res); + * }) + * .catch((err) => { + * console.log(err); + * }) + */ + +public async altcha(params: paramsAltcha): Promise { + params = renameParams(params) + + checkCaptchaParams(params, "altcha") + + const payload = { + ...this.defaultPayload, + ...params, + method: "altcha", + }; + + const response = await fetch(this.in, { + body: JSON.stringify(payload), + method: "post", + headers: { "Content-Type": "application/json" } + }) + const result = await response.text() + + let data; + try { + data = JSON.parse(result) + } catch { + throw new APIError(result) + } + + if (data.status == 1) { + return this.pollResponse(data.request) + } else { + throw new APIError(data.request) + } +} + /** * ### Method for solving Audio captcha. * diff --git a/src/utils/checkCaptchaParams.ts b/src/utils/checkCaptchaParams.ts index 8cdbbc0..8d0cfde 100644 --- a/src/utils/checkCaptchaParams.ts +++ b/src/utils/checkCaptchaParams.ts @@ -1,7 +1,7 @@ // Captcha methods for which parameter checking is available const supportedMethods = ["userrecaptcha", "hcaptcha", "geetest", "geetest_v4","yandex","funcaptcha","lemin","amazon_waf", "turnstile", "base64", "capy","datadome", "cybersiara", "mt_captcha", "bounding_box", 'friendly_captcha', 'grid', - 'textcaptcha', 'canvas', 'rotatecaptcha', 'keycaptcha', 'cutcaptcha', 'tencent', 'atb_captcha', 'prosopo', 'captchafox', 'vkimage', 'vkcaptcha', 'temu', 'audio'] + 'textcaptcha', 'canvas', 'rotatecaptcha', 'keycaptcha', 'cutcaptcha', 'tencent', 'atb_captcha', 'prosopo', 'captchafox', 'vkimage', 'vkcaptcha', 'temu', 'altcha', 'audio'] // Names of required fields that must be contained in the parameters captcha const recaptchaRequiredFields = ['pageurl','googlekey'] @@ -34,6 +34,7 @@ const captchaFoxRequiredFields = ['pageurl', 'sitekey', 'userAgent', 'proxy', ' const vkimageRequiredFields = ['body', 'steps'] const vkcaptchaRequiredFields = ['redirect_uri', 'userAgent', 'proxy', 'proxytype'] const temuRequiredFields = ['body', 'part1', 'part2', 'part3'] +const altchaRequiredFields = ['pageurl'] const audioRequiredFields = ['body', 'lang'] /** @@ -133,6 +134,9 @@ const getRequiredFildsArr = (method: string):Array => { case "temu": requiredFieldsArr = temuRequiredFields break; + case "altcha": + requiredFieldsArr = altchaRequiredFields + break; case "audio": requiredFieldsArr = audioRequiredFields break; @@ -176,6 +180,23 @@ export default function checkCaptchaParams(params: Object, method: string) { } }) + if(method === "altcha") { + const hasChallengeUrl = params.hasOwnProperty('challenge_url') + const hasChallengeJson = params.hasOwnProperty('challenge_json') + + if(!hasChallengeUrl && !hasChallengeJson) { + isCorrectCaptchaParams = false + throw new Error(`Error when check params captcha.\nNot found "challenge_url" or "challenge_json" field in the Object. One of this field is required for "${method}" method. Please add field "challenge_url" or "challenge_json" to captcha parameters.`) + } + + if(hasChallengeUrl && hasChallengeJson) { + isCorrectCaptchaParams = false + throw new Error(`Error when check params captcha.\nYou must provide exactly one of "challenge_url" or "challenge_json" for "${method}" method.`) + } + + isCorrectCaptchaParams = true + } + //The parameters `textinstructions` and `imginstructions` are mandatory for the methods `bounding_box`, `grid`, and `canvas`. if(method === "bounding_box" || method === "grid" || method === "canvas") { if(params.hasOwnProperty('textinstructions') || params.hasOwnProperty('imginstructions')) { diff --git a/src/utils/renameParams.ts b/src/utils/renameParams.ts index d3953e4..4fce3d0 100644 --- a/src/utils/renameParams.ts +++ b/src/utils/renameParams.ts @@ -39,6 +39,10 @@ export default function renameParams(params: any) { // atbCAPTCHA "apiServer": "api_server", + + // Altcha + "challengeUrl": "challenge_url", + "challengeJson": "challenge_json", } for(let key in params) {