Skip to content

Commit b293eb1

Browse files
New Methods & extendedResponse option (#19)
* FriendlyCaptcha * FriendlyCaptchaExample * response type json * response type json * json param * json param * added json param to tests * added json param to tests * readme * new TwoCaptcha() * new TwoCaptcha() * cleanup * new TwoCaptcha(args[0]) * extendedResponse * MtCaptcha * Tencent * Tencent * pom.xml * json response * Update hCaptcha examples * json to string * Update Friendly Captcha param * Add example of Friendly captcha * Add tencent example * Update pageurl * Update README.md * Update MtCaptcha examples * Update README.md --------- Co-authored-by: dzmitry-duboyski <[email protected]>
1 parent be39d4c commit b293eb1

File tree

76 files changed

+489
-81
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+489
-81
lines changed

README.md

+62-18
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
# JAVA Module for 2Captcha API (captcha solver)
1111
The easiest way to quickly integrate [2Captcha] into your code to automate solving of any types of captcha.
12-
Examples of API requests for different captcha types are available on the [Java captcha solver](https://2captcha.com/lang/java) page.
12+
Examples of API requests for different captcha types are available on the [Java captcha solver] page.
1313

1414
- [JAVA Module for 2Captcha API (captcha solver)](#java-module-for-2captcha-api-captcha-solver)
1515
- [Installation](#installation)
@@ -37,6 +37,9 @@ Examples of API requests for different captcha types are available on the [Java
3737
- [Lemin](#lemin)
3838
- [Turnstile](#turnstile)
3939
- [AmazonWaf](#amazonwaf)
40+
- [Friendly Captcha](#friendly-captcha)
41+
- [MTCaptcha](#mtcaptcha)
42+
- [Tencent](#tencent)
4043
- [Other methods](#other-methods)
4144
- [send / getResult](#send--getresult)
4245
- [balance](#balance)
@@ -64,21 +67,30 @@ solver.setCallback("https://your.site/result-receiver");
6467
solver.setDefaultTimeout(120);
6568
solver.setRecaptchaTimeout(600);
6669
solver.setPollingInterval(10);
70+
solver.setExtendedResponse(1);
6771
```
6872

6973
### TwoCaptcha instance options
7074

71-
| Option | Default value | Description |
72-
| ---------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
73-
| softId | - | your software ID obtained after publishing in [2captcha sofware catalog] |
74-
| callback | - | URL of your web-sever that receives the captcha recognition result. The URl should be first registered in [pingback settings] of your account |
75-
| defaultTimeout | 120 | Polling timeout in seconds for all captcha types except ReCaptcha. Defines how long the module tries to get the answer from `res.php` API endpoint |
76-
| recaptchaTimeout | 600 | Polling timeout for ReCaptcha in seconds. Defines how long the module tries to get the answer from `res.php` API endpoint |
77-
| pollingInterval | 10 | Interval in seconds between requests to `res.php` API endpoint, setting values less than 5 seconds is not recommended |
78-
79-
> **IMPORTANT:** once *callback URL* is defined for `TwoCaptcha` instance with `setCallback`, all methods return only the captcha ID and DO NOT poll the API to get the result. The result will be sent to the callback URL.
75+
| Option | Default value| Description |
76+
|------------------| ------------ |----------------------------------------------------------------------------------------------------------------------------------------------------|
77+
| host |`2captcha.com`| API server. You can set it to `rucaptcha.com` if your account is registered there |
78+
| softId | 4581 | your software ID obtained after publishing in [2captcha sofware catalog] |
79+
| callback | - | URL of your web-sever that receives the captcha recognition result. The URl should be first registered in [pingback settings] of your account |
80+
| defaultTimeout | 120 | Polling timeout in seconds for all captcha types except ReCaptcha. Defines how long the module tries to get the answer from `res.php` API endpoint |
81+
| recaptchaTimeout | 600 | Polling timeout for ReCaptcha in seconds. Defines how long the module tries to get the answer from `res.php` API endpoint |
82+
| pollingInterval | 10 | Interval in seconds between requests to `res.php` API endpoint, setting values less than 5 seconds is not recommended |
83+
| extendedResponse | 0 | Json or String format response from `res.php` API endpoint, extendedResponse = 1 returns JSON format response |
84+
85+
> [!IMPORTANT] once *callback URL* is defined for `TwoCaptcha` instance with `setCallback`, all methods return only the captcha ID and DO NOT poll the API to get the result. The result will be sent to the callback URL.
8086
To get the answer manually use [getResult method](#send--getresult)
8187

88+
> [!TIP]
89+
> Use the `extendedResponse(1)` setting to obtain an extended response for the captcha. When using `extendedResponse(1)`, the response will be presented as a `JSON` string. Utilizing the extended response `extendedResponse(1)` will be helpful when solving captchas such as [hCaptcha](#hcaptcha) and [ClickCaptcha](#clickcaptcha). When using `extendedResponse(1)` for hCaptcha, the response will include additional fields, such as `respKe`y and `useragent`.<br>
90+
> Default answer for hCaptcha answer looks like this: `P1_eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...`<br>
91+
> An extended response using `extendedResponse(1)` for an hCaptcha answer looks like this: `{"request":"P1_eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...","respKey":"E0_eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...","useragent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.127 Safari/537.36","status":1}`
92+
93+
8294
## Solve captcha
8395
When you submit any image-based captcha use can provide additional options to help 2captcha workers to solve it properly.
8496

@@ -206,12 +218,13 @@ captcha.setProxy("HTTPS", "login:password@IP_address:PORT");
206218
```
207219

208220
### hCaptcha
209-
Method to solve GeeTest puzzle captcha. Returns a set of tokens as JSON.
221+
Method to solve hCaptcha captcha. Returns a token.
222+
Use `setExtendedResponse` to get `respKey` and `useragent` in captcha answer.
210223

211224
```java
212225
HCaptcha captcha = new HCaptcha();
213-
captcha.setSiteKey("10000000-ffff-ffff-ffff-000000000001");
214-
captcha.setUrl("https://www.site.com/page/");
226+
captcha.setSiteKey("c0421d06-b92e-47fc-ab9a-5caa43c04538");
227+
captcha.setUrl("https://2captcha.com/demo/hcaptcha");
215228
captcha.setProxy("HTTPS", "login:password@IP_address:PORT");
216229
```
217230

@@ -293,7 +306,7 @@ captcha.setHintText("Put the images in the correct way up");
293306
This method can be used to solve a audio captcha
294307

295308
```java
296-
TwoCaptcha solver = new TwoCaptcha("YOUR_API_KEY");
309+
TwoCaptcha solver = new TwoCaptcha(args[0]);
297310
byte[] bytes = Files.readAllBytes(Paths.get("src/main/resources/audio-en.mp3"));
298311
String base64EncodedImage = Base64.getEncoder().encodeToString(bytes);
299312
Audio captcha = new Audio();
@@ -304,7 +317,7 @@ captcha.setBase64(base64EncodedImage);
304317
Use this method to solve Yandex and obtain a token to bypass the protection.
305318

306319
```java
307-
TwoCaptcha solver = new TwoCaptcha("YOUR_API_KEY");
320+
TwoCaptcha solver = new TwoCaptcha(args[0]);
308321
Yandex captcha = new Yandex();
309322
captcha.setSiteKey("Y5Lh0tiycconMJGsFd3EbbuNKSp1yaZESUOIHfeV");
310323
captcha.setUrl("https://rutube.ru");
@@ -314,7 +327,7 @@ captcha.setUrl("https://rutube.ru");
314327
Use this method to solve Lemin and obtain a token to bypass the protection.
315328

316329
```java
317-
TwoCaptcha solver = new TwoCaptcha("YOUR_API_KEY");
330+
TwoCaptcha solver = new TwoCaptcha(args[0]);
318331
Lemin captcha = new Lemin();
319332
captcha.setСaptchaId("CROPPED_d3d4d56_73ca4008925b4f83a8bed59c2dd0df6d");
320333
captcha.setUrl("http://sat2.aksigorta.com.tr");
@@ -325,7 +338,7 @@ captcha.setApiServer("api.leminnow.com");
325338
Use this method to solve Turnstile and obtain a token to bypass the protection.
326339

327340
```java
328-
TwoCaptcha solver = new TwoCaptcha("YOUR_API_KEY");
341+
TwoCaptcha solver = new TwoCaptcha(args[0]);
329342
Turnstile captcha = new Turnstile();
330343
captcha.setSiteKey("0x4AAAAAAAChNiVJM_WtShFf");
331344
captcha.setUrl("https://ace.fusionist.io");
@@ -335,14 +348,44 @@ captcha.setUrl("https://ace.fusionist.io");
335348
Use this method to solve AmazonWaf and obtain a token to bypass the protection.
336349

337350
```java
338-
TwoCaptcha solver = new TwoCaptcha("YOUR_API_KEY");
351+
TwoCaptcha solver = new TwoCaptcha(args[0]);
339352
AmazonWaf captcha = new AmazonWaf();
340353
captcha.setSiteKey("AQIDAHjcYu/GjX+QlghicBgQ/7bFaQZ+m5FKCMDnO+vTbNg96AF5H1K/siwSLK7RfstKtN5bAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglg");
341354
captcha.setUrl("https://non-existent-example.execute-api.us-east-1.amazonaws.com");
342355
captcha.setIV("test_iv");
343356
captcha.setContext("test_context");
344357
```
345358

359+
### Friendly Captcha
360+
Use this method to solve Friendly Captcha and obtain a token to bypass the protection.
361+
362+
```java
363+
TwoCaptcha solver = new TwoCaptcha(args[0]);
364+
FriendlyCaptcha friendlyCaptcha = new FriendlyCaptcha();
365+
friendlyCaptcha.setSiteKey("FCMST5VUMCBOCGQ9");
366+
friendlyCaptcha.setPageUrl("https://mysite.com/page/with/FriendlyCaptcha");
367+
```
368+
369+
### MtCaptcha
370+
Use this method to solve MtCaptcha and obtain a token to bypass the protection.
371+
372+
```java
373+
TwoCaptcha solver = new TwoCaptcha(args[0]);
374+
MtCaptcha mtCaptcha = new MtCaptcha();
375+
mtCaptcha.setSiteKey("MTPublic-KzqLY1cKH");
376+
mtCaptcha.setPageUrl("https://2captcha.com/demo/mtcaptcha");
377+
```
378+
379+
### Tencent
380+
Use this method to solve Tencent and obtain a token to bypass the protection.
381+
382+
```java
383+
TwoCaptcha solver = new TwoCaptcha(args[0]);
384+
Tencent tencent = new Tencent();
385+
tencent.setAppId("2092215077");
386+
tencent.setPageUrl("https://mysite.com/page/with/tencent");
387+
```
388+
346389
## Other methods
347390

348391
### send / getResult
@@ -423,3 +466,4 @@ The graphics and trademarks included in this repository are not covered by the M
423466
[Pingback settings]: https://2captcha.com/setting/pingback
424467
[Post options]: https://2captcha.com/2captcha-api#normal_post
425468
[List of supported languages]: https://2captcha.com/2captcha-api#language
469+
[Java captcha solver]: https://2captcha.com/lang/java

pom.xml

+5
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@
5252
</properties>
5353

5454
<dependencies>
55+
<dependency>
56+
<groupId>org.json</groupId>
57+
<artifactId>json</artifactId>
58+
<version>20240303</version>
59+
</dependency>
5560
<dependency>
5661
<groupId>com.squareup.okhttp3</groupId>
5762
<artifactId>okhttp</artifactId>

src/main/java/com/twocaptcha/TwoCaptcha.java

+66-14
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import com.twocaptcha.exceptions.NetworkException;
77
import com.twocaptcha.exceptions.TimeoutException;
88
import com.twocaptcha.exceptions.ValidationException;
9+
import org.json.JSONException;
10+
import org.json.JSONObject;
911

1012
import java.io.File;
1113
import java.util.HashMap;
@@ -54,6 +56,8 @@ public class TwoCaptcha {
5456
*/
5557
private boolean lastCaptchaHasCallback;
5658

59+
private int extendedResponse = 0;
60+
5761
/**
5862
* Network client
5963
*/
@@ -76,6 +80,12 @@ public TwoCaptcha(String apiKey) {
7680
setApiKey(apiKey);
7781
}
7882

83+
public TwoCaptcha(String apiKey, int extendedResponse) {
84+
this();
85+
setApiKey(apiKey);
86+
this.extendedResponse = extendedResponse;
87+
}
88+
7989
/**
8090
* @param apiKey
8191
*/
@@ -189,9 +199,10 @@ public void waitForResult(Captcha captcha, Map<String, Integer> waitOptions) thr
189199
}
190200

191201
try {
192-
String result = getResult(captcha.getId());
202+
Object result = getResult(captcha.getId());
203+
193204
if (result != null) {
194-
captcha.setCode(result);
205+
captcha.setCode(String.valueOf(result));
195206
return;
196207
}
197208
} catch (NetworkException e) {
@@ -219,11 +230,55 @@ public String send(Captcha captcha) throws Exception {
219230

220231
String response = apiClient.in(params, files);
221232

222-
if (!response.startsWith("OK|")) {
223-
throw new ApiException("Cannot recognise api response (" + response + ")");
233+
return getCaptchaId(response);
234+
}
235+
236+
String getCaptchaId(String response) throws ApiException {
237+
try {
238+
JSONObject jsonObject = new JSONObject(response);
239+
String request = jsonObject.getString("request");
240+
241+
if (request.equals("CAPCHA_NOT_READY")) {
242+
return null;
243+
}
244+
245+
return jsonObject.getString("request");
246+
247+
} catch (JSONException exception) {
248+
if (response.equals("CAPCHA_NOT_READY")) {
249+
return null;
250+
}
251+
252+
if (!response.startsWith("OK|")) {
253+
throw new ApiException("Cannot recognise api response (" + response + ")");
254+
}
255+
256+
return response.substring(3);
224257
}
258+
}
259+
260+
String handleResponse(String response) throws ApiException {
261+
try {
262+
JSONObject jsonObject = new JSONObject(response);
263+
Object requestVal = jsonObject.get("request");
264+
265+
if (requestVal.equals("CAPCHA_NOT_READY")) {
266+
return null;
267+
}
225268

226-
return response.substring(3);
269+
return jsonObject.toString();
270+
271+
} catch (JSONException exception) {
272+
if (response.equals("CAPCHA_NOT_READY")) {
273+
return null;
274+
}
275+
276+
if (!response.startsWith("OK|")) {
277+
throw new ApiException("Cannot recognise api response (" + response + ")");
278+
}
279+
280+
return response.substring(3);
281+
}
227282
}
228283

229284
/**
@@ -237,18 +292,11 @@ public String getResult(String id) throws Exception {
237292
Map<String, String> params = new HashMap<>();
238293
params.put("action", "get");
239294
params.put("id", id);
295+
params.put("json", String.valueOf(this.extendedResponse));
240296

241297
String response = res(params);
242298

243-
if (response.equals("CAPCHA_NOT_READY")) {
244-
return null;
245-
}
246-
247-
if (!response.startsWith("OK|")) {
248-
throw new ApiException("Cannot recognise api response (" + response + ")");
249-
}
250-
251-
return response.substring(3);
299+
return handleResponse(response);
252300
}
253301

254302
/**
@@ -314,6 +362,7 @@ private String res(Map<String, String> params) throws Exception {
314362
*/
315363
private void sendAttachDefaultParams(Map<String, String> params) {
316364
params.put("key", apiKey);
365+
params.put("json", String.valueOf(this.extendedResponse));
317366

318367
if (callback != null) {
319368
if (!params.containsKey("pingback")) {
@@ -350,4 +399,7 @@ private void validateFiles(Map<String, File> files) throws ValidationException {
350399
}
351400
}
352401

402+
public void setExtendedResponse(int extendedResponse) {
403+
this.extendedResponse = extendedResponse;
404+
}
353405
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.twocaptcha.captcha;
2+
3+
public class FriendlyCaptcha extends Captcha {
4+
5+
public FriendlyCaptcha() {
6+
super();
7+
params.put("method", "friendly_captcha");
8+
}
9+
10+
public void setSiteKey(String siteKey) {
11+
params.put("sitekey", siteKey);
12+
}
13+
14+
public void setPageUrl(String url) {
15+
params.put("pageurl", url);
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.twocaptcha.captcha;
2+
3+
public class MtCaptcha extends Captcha {
4+
5+
public MtCaptcha() {
6+
super();
7+
params.put("method", "mt_captcha");
8+
}
9+
10+
public void setSiteKey(String siteKey) {
11+
params.put("sitekey", siteKey);
12+
}
13+
14+
public void setPageUrl(String url) {
15+
params.put("pageurl", url);
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.twocaptcha.captcha;
2+
3+
public class Tencent extends Captcha {
4+
5+
public Tencent() {
6+
super();
7+
params.put("method", "tencent");
8+
}
9+
10+
public void setAppId(String appId) {
11+
params.put("app_id", appId);
12+
}
13+
14+
public void setPageUrl(String url) {
15+
params.put("pageurl", url);
16+
}
17+
}

src/main/java/examples/AmazonWafExample.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
public class AmazonWafExample {
77

88
public static void main(String[] args) {
9-
TwoCaptcha solver = new TwoCaptcha("YOUR_API_KEY");
9+
TwoCaptcha solver = new TwoCaptcha(args[0]);
1010

1111
AmazonWaf captcha = new AmazonWaf();
1212
captcha.setSiteKey("AQIDAHjcYu/GjX+QlghicBgQ/7bFaQZ+m5FKCMDnO+vTbNg96AF5H1K/siwSLK7RfstKtN5bAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglg");

src/main/java/examples/AmazonWafOptionsExample.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
public class AmazonWafOptionsExample {
77

88
public static void main(String[] args) {
9-
TwoCaptcha solver = new TwoCaptcha("YOUR_API_KEY");
9+
TwoCaptcha solver = new TwoCaptcha(args[0]);
1010
solver.setHost("rucaptcha.com");
1111
solver.setSoftId(0);
1212
solver.setDefaultTimeout(120);

src/main/java/examples/AudioExample.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
public class AudioExample {
1111

1212
public static void main(String[] args) throws Exception {
13-
TwoCaptcha solver = new TwoCaptcha("YOUR_API_KEY");
13+
TwoCaptcha solver = new TwoCaptcha(args[0]);
1414

1515
byte[] bytes = Files.readAllBytes(Paths.get("src/main/resources/audio-en.mp3"));
1616
String base64EncodedImage = Base64.getEncoder().encodeToString(bytes);

0 commit comments

Comments
 (0)