diff --git a/README.md b/README.md
index e0ba989..e7b7e30 100644
--- a/README.md
+++ b/README.md
@@ -52,6 +52,7 @@ Examples of API requests for different captcha types are available on the [JavaS
- [Audio Captcha](#audio-captcha)
- [Yidun NECaptcha](#yidun-necaptcha)
- [Alibaba Captcha](#alibaba-captcha)
+ - [TSPD](#tspd)
- [Other methods](#other-methods)
- [goodReport](#goodreport)
- [badReport](#badreport)
@@ -859,6 +860,33 @@ console.log(err);
})
```
+### TSPD
+
+[API method description.](https://2captcha.com/2captcha-api#tspd)
+
+Cookie-based method for automatic solving of TSPD captcha. Returns cookies that can be used to access the target page.
+
+Required parameters: `pageurl`, `tspdCookie`, `htmlPageBase64`, `proxy`, `proxytype`.
+
+**Important:** `tspdCookie` and `htmlPageBase64` are dynamic — extract them immediately before creating the task. A proxy with a static session and the same IP must be used at all stages.
+
+```js
+solver.tspd({
+ pageurl: "https://example.com/login",
+ tspdCookie: "TS386a400d029=082670...010245; TS386a400d078=082670...dbb3b0c",
+ htmlPageBase64: "PCFET0NUWVBFIGh0bWw+...",
+ userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
+ proxy: "login:password@1.2.3.4:8080",
+ proxytype: "HTTP"
+})
+.then((res) => {
+console.log(res);
+})
+.catch((err) => {
+console.log(err);
+})
+```
+
## Other methods
### goodReport
diff --git a/examples/tspd.js b/examples/tspd.js
new file mode 100644
index 0000000..be199db
--- /dev/null
+++ b/examples/tspd.js
@@ -0,0 +1,19 @@
+const TwoCaptcha = require("../dist/index.js");
+require('dotenv').config();
+const APIKEY = process.env.APIKEY
+const solver = new TwoCaptcha.Solver(APIKEY);
+
+solver.tspd({
+ pageurl: "https://example.com/login",
+ tspdCookie: "TS386a400d029=082670...010245; TS386a400d078=082670...dbb3b0c",
+ htmlPageBase64: "PCFET0NUWVBFIGh0bWw+...",
+ userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
+ proxy: "login:password@1.2.3.4:8080",
+ proxytype: "HTTP"
+})
+.then((res) => {
+console.log(res);
+})
+.catch((err) => {
+console.log(err);
+})
diff --git a/package.json b/package.json
index 532beaa..b52b425 100644
--- a/package.json
+++ b/package.json
@@ -57,7 +57,8 @@
"Binance",
"Audio Recognition",
"Yidun NECaptcha",
- "Alibaba Captcha"
+ "Alibaba Captcha",
+ "TSPD"
],
"scripts": {
"build": "tsc && node ./dist/index.js",
diff --git a/src/structs/2captcha.ts b/src/structs/2captcha.ts
index 3a314a6..691f5a6 100644
--- a/src/structs/2captcha.ts
+++ b/src/structs/2captcha.ts
@@ -353,6 +353,15 @@ export interface paramsAlibaba {
proxytype?: string,
}
+export interface paramsTspd {
+ pageurl: string,
+ tspdCookie: string,
+ htmlPageBase64: string,
+ proxy: string,
+ proxytype: string,
+ userAgent?: string,
+}
+
/**
* An object containing properties of the captcha solution.
* @typedef {Object} CaptchaAnswer
@@ -2502,6 +2511,74 @@ public async alibaba(params: paramsAlibaba): Promise {
}
}
+/**
+ * ### Solves TSPD Captcha
+ *
+ * Cookie-based method for automatic solving of TSPD captcha.
+ * [Read more about TSPD captcha](https://2captcha.com/2captcha-api#tspd-captcha).
+ *
+ * **Important:** `tspdCookie` and `htmlPageBase64` are dynamic — extract them immediately before creating the task,
+ * otherwise the solve may fail. A proxy with a static session and the same IP must be used at all stages.
+ *
+ * @param {{ pageurl, tspdCookie, htmlPageBase64, proxy, proxytype, userAgent }} params Parameters TSPD Captcha as an object.
+ * @param {string} params.pageurl Full URL of the page where you see the captcha.
+ * @param {string} params.tspdCookie Cookies received on the TSPD challenge page. Values starting with `TS...` or `Tspd_...`.
+ * @param {string} params.htmlPageBase64 Full HTML of the challenge page encoded in base64.
+ * @param {string} params.proxy Proxy in 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`.
+ * @param {string} params.userAgent Optional. Browser User-Agent. We recommend sending a valid Windows browser string.
+ *
+ * @returns {Promise} The result from the solve.
+ * @throws APIError
+ *
+ * @example
+ * solver.tspd({
+ * pageurl: "https://example.com/login",
+ * tspdCookie: "TS386a400d029=082670...010245; TS386a400d078=082670...dbb3b0c",
+ * htmlPageBase64: "PCFET0NUWVBFIGh0bWw+...",
+ * userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
+ * proxy: "login:password@1.2.3.4:8080",
+ * proxytype: "HTTP"
+ * })
+ * .then((res) => {
+ * console.log(res);
+ * })
+ * .catch((err) => {
+ * console.log(err);
+ * })
+ */
+public async tspd(params: paramsTspd): Promise {
+ params = renameParams(params)
+
+ checkCaptchaParams(params, "tspd")
+
+ const payload = {
+ ...this.defaultPayload,
+ ...params,
+ method: "tspd",
+ };
+
+ 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)
+ }
+}
+
/**
* Reports a captcha as correctly solved.
*
diff --git a/src/utils/checkCaptchaParams.ts b/src/utils/checkCaptchaParams.ts
index 594a2a2..b8dfdfa 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', 'altcha', 'binance', 'audio', 'yidun', 'alibaba']
+ 'textcaptcha', 'canvas', 'rotatecaptcha', 'keycaptcha', 'cutcaptcha', 'tencent', 'atb_captcha', 'prosopo', 'captchafox', 'vkimage', 'vkcaptcha', 'temu', 'altcha', 'binance', 'audio', 'yidun', 'alibaba', 'tspd']
// Names of required fields that must be contained in the parameters captcha
const recaptchaRequiredFields = ['pageurl','googlekey']
@@ -39,6 +39,7 @@ const binanceRequiredFields = ['pageurl', 'sitekey', 'validate_id']
const audioRequiredFields = ['body', 'lang']
const yidunRequiredFields = ['pageurl', 'sitekey']
const alibabaRequiredFields = ['pageurl', 'scene_id', 'prefix']
+const tspdRequiredFields = ['pageurl', 'tspd_cookie', 'html_page_base64', 'proxy', 'proxytype']
/**
* Getting required arguments for a captcha.
@@ -152,6 +153,9 @@ const getRequiredFildsArr = (method: string):Array => {
case "alibaba":
requiredFieldsArr = alibabaRequiredFields
break;
+ case "tspd":
+ requiredFieldsArr = tspdRequiredFields
+ break;
}
return requiredFieldsArr
}
diff --git a/src/utils/renameParams.ts b/src/utils/renameParams.ts
index c34db86..246e03e 100644
--- a/src/utils/renameParams.ts
+++ b/src/utils/renameParams.ts
@@ -56,7 +56,11 @@ export default function renameParams(params: any) {
"sceneId": "scene_id",
"verifyType": "verify_type",
"userCertifyId": "user_certify_id",
- "apiGetLib": "api_get_lib"
+ "apiGetLib": "api_get_lib",
+
+ // TSPD
+ "tspdCookie": "tspd_cookie",
+ "htmlPageBase64": "html_page_base64"
}
for(let key in params) {