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) {