recognize 1.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +196 -147
- package/dist/index.cjs +426 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +180 -0
- package/dist/index.d.ts +180 -0
- package/dist/index.js +395 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -25
- package/example/captcha.png +0 -0
- package/example/test.js +0 -35
- package/index.js +0 -300
package/README.md
CHANGED
|
@@ -1,168 +1,217 @@
|
|
|
1
1
|
# Recognize
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
Lightweight zero-dependency captcha solving client for **RuCaptcha** and **Anti-Captcha** services (API v2).
|
|
4
|
+
|
|
5
|
+
- **0 runtime dependencies** — uses native `fetch` (Node.js 18+)
|
|
6
|
+
- **TypeScript** — full type safety, autocompletion, exported types
|
|
7
|
+
- **Dual ESM/CJS** — works with `import` and `require`
|
|
8
|
+
- **30+ captcha types** — reCAPTCHA, hCaptcha, Turnstile, FunCaptcha, GeeTest, and more
|
|
9
|
+
- **Auto-polling** — waits for result with configurable interval & timeout
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
7
14
|
npm install recognize
|
|
8
15
|
```
|
|
9
16
|
|
|
10
|
-
##
|
|
11
|
-
* [rucaptcha](https://rucaptcha.com/?from=1027759)
|
|
12
|
-
* [antigate](https://anti-captcha.com)
|
|
13
|
-
* [captcha24](http://captcha24.com)
|
|
17
|
+
## Quick Start
|
|
14
18
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
* [balance](#balance)
|
|
18
|
-
* [report](#report)
|
|
19
|
+
```ts
|
|
20
|
+
import { RuCaptcha } from "recognize";
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
const solver = new RuCaptcha({
|
|
23
|
+
apiKey: "YOUR_API_KEY",
|
|
24
|
+
pollingInterval: 5000, // optional, default 5000ms
|
|
25
|
+
timeout: 180000, // optional, default 180000ms
|
|
26
|
+
});
|
|
22
27
|
|
|
23
|
-
|
|
28
|
+
// Check balance
|
|
29
|
+
const balance = await solver.getBalance();
|
|
30
|
+
console.log("Balance:", balance);
|
|
24
31
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
32
|
+
// Solve reCAPTCHA v2
|
|
33
|
+
const { taskId, solution } = await solver.recaptchaV2(
|
|
34
|
+
"https://example.com",
|
|
35
|
+
"SITE_KEY",
|
|
36
|
+
);
|
|
37
|
+
console.log(solution.gRecaptchaResponse);
|
|
28
38
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
{
|
|
32
|
-
if(err) throw err;
|
|
33
|
-
console.log(id, code);
|
|
34
|
-
});
|
|
39
|
+
// Report result
|
|
40
|
+
await solver.reportCorrect(taskId);
|
|
35
41
|
```
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
});
|
|
42
|
+
|
|
43
|
+
### Anti-Captcha
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
import { AntiCaptcha } from "recognize";
|
|
47
|
+
|
|
48
|
+
const solver = new AntiCaptcha({ apiKey: "YOUR_API_KEY" });
|
|
43
49
|
```
|
|
44
|
-
|
|
45
|
-
###
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
{
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
|
|
51
|
+
### Dynamic service selection
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { createSolver } from "recognize";
|
|
55
|
+
|
|
56
|
+
const solver = createSolver("rucaptcha", { apiKey: "YOUR_API_KEY" });
|
|
57
|
+
// or
|
|
58
|
+
const solver2 = createSolver("anticaptcha", { apiKey: "YOUR_API_KEY" });
|
|
52
59
|
```
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
+
|
|
61
|
+
## Constructor Options
|
|
62
|
+
|
|
63
|
+
| Option | Type | Default | Description |
|
|
64
|
+
| ----------------- | -------- | -------- | ---------------------------- |
|
|
65
|
+
| `apiKey` | `string` | — | **Required.** API key |
|
|
66
|
+
| `pollingInterval` | `number` | `5000` | Polling interval in ms |
|
|
67
|
+
| `timeout` | `number` | `180000` | Max wait time per task in ms |
|
|
68
|
+
|
|
69
|
+
## API
|
|
70
|
+
|
|
71
|
+
All solving methods return `Promise<TaskResult<T>>` where `TaskResult<T> = { taskId: number, solution: T }`.
|
|
72
|
+
|
|
73
|
+
### Account
|
|
74
|
+
|
|
75
|
+
| Method | Description |
|
|
76
|
+
| ------------------------- | ------------------------- |
|
|
77
|
+
| `getBalance()` | Get account balance |
|
|
78
|
+
| `reportCorrect(taskId)` | Report correct solution |
|
|
79
|
+
| `reportIncorrect(taskId)` | Report incorrect solution |
|
|
80
|
+
|
|
81
|
+
### Image & Text
|
|
82
|
+
|
|
83
|
+
| Method | Params | Task Type |
|
|
84
|
+
| ------------------------------ | ------------------------------------------------- | ----------------- |
|
|
85
|
+
| `imageCaptcha(body, options?)` | `body` — Buffer or base64 string | `ImageToTextTask` |
|
|
86
|
+
| `textCaptcha(text, options?)` | `text` — question string | `TextCaptchaTask` |
|
|
87
|
+
| `audioCaptcha(body, lang?)` | `body` — Buffer or base64, `lang` — language code | `AudioTask` |
|
|
88
|
+
|
|
89
|
+
### reCAPTCHA
|
|
90
|
+
|
|
91
|
+
| Method | Params |
|
|
92
|
+
| -------------------------------------------------------- | ---------------------------------- |
|
|
93
|
+
| `recaptchaV2(url, siteKey, options?)` | Supports proxy via `options.proxy` |
|
|
94
|
+
| `recaptchaV3(url, siteKey, action, minScore?, options?)` | `minScore` default `0.3` |
|
|
95
|
+
| `recaptchaV2Enterprise(url, siteKey, options?)` | Enterprise version |
|
|
96
|
+
|
|
97
|
+
### hCaptcha
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
await solver.hcaptcha(url, siteKey, options?)
|
|
60
101
|
```
|
|
61
102
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
103
|
+
### Cloudflare Turnstile
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
await solver.turnstile(url, siteKey, options?)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### FunCaptcha (Arkose Labs)
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
await solver.funcaptcha(url, publicKey, options?)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### GeeTest
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
await solver.geetest(url, gt, challenge, options?)
|
|
119
|
+
await solver.geetestV4(url, captchaId, options?)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Amazon WAF
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
await solver.amazonWaf(url, siteKey, options?)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Other Captcha Types
|
|
67
129
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
130
|
+
| Method | Task Type |
|
|
131
|
+
| -------------------------------------------------------- | --------------------------------- |
|
|
132
|
+
| `keyCaptcha(url, options?)` | `KeyCaptchaTaskProxyless` |
|
|
133
|
+
| `lemin(url, captchaId, apiServer, options?)` | `LeminTaskProxyless` |
|
|
134
|
+
| `capyPuzzle(url, siteKey, options?)` | `CapyTaskProxyless` |
|
|
135
|
+
| `dataDome(url, captchaUrl, userAgent, proxyConfig)` | `DataDomeSliderTask` |
|
|
136
|
+
| `cyberSiara(url, slideMasterUrlId, userAgent, options?)` | `AntiCyberSiAraTaskProxyless` |
|
|
137
|
+
| `mtCaptcha(url, siteKey, options?)` | `MtCaptchaTaskProxyless` |
|
|
138
|
+
| `friendlyCaptcha(url, siteKey, options?)` | `FriendlyCaptchaTaskProxyless` |
|
|
139
|
+
| `cutcaptcha(url, miseryKey, apiKey, options?)` | `CutCaptchaTaskProxyless` |
|
|
140
|
+
| `tencent(url, appId, options?)` | `TencentTaskProxyless` |
|
|
141
|
+
| `atbCaptcha(url, appId, apiServer, options?)` | `AtbCaptchaTaskProxyless` |
|
|
142
|
+
| `yandexSmart(url, siteKey, options?)` | `YandexSmartCaptchaTaskProxyless` |
|
|
143
|
+
| `vkCaptcha(url, siteKey, options?)` | `VKCaptchaTaskProxyless` |
|
|
144
|
+
| `temuCaptcha(url, options?)` | `TemuCaptchaTaskProxyless` |
|
|
145
|
+
|
|
146
|
+
### Image-Based Tasks
|
|
147
|
+
|
|
148
|
+
| Method | Task Type |
|
|
149
|
+
| ------------------------------------ | ----------------- |
|
|
150
|
+
| `rotateCaptcha(body, options?)` | `RotateTask` |
|
|
151
|
+
| `coordinatesCaptcha(body, options?)` | `CoordinatesTask` |
|
|
152
|
+
| `gridCaptcha(body, options?)` | `GridTask` |
|
|
153
|
+
| `boundingBoxCaptcha(body, options?)` | `BoundingBoxTask` |
|
|
154
|
+
| `drawAroundCaptcha(body, options?)` | `DrawAroundTask` |
|
|
155
|
+
|
|
156
|
+
### Generic / Custom
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
// Send any task type directly
|
|
160
|
+
await solver.solve<{ token: string }>({
|
|
161
|
+
type: "SomeNewTaskType",
|
|
162
|
+
websiteURL: "https://example.com",
|
|
71
163
|
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Proxy Support
|
|
167
|
+
|
|
168
|
+
Methods that support proxy accept it via options:
|
|
72
169
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
console.log('Captcha not valid');
|
|
82
|
-
recognize.report(id, function(err, answer)
|
|
83
|
-
{
|
|
84
|
-
console.log(answer);
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
});
|
|
170
|
+
```ts
|
|
171
|
+
await solver.recaptchaV2("https://example.com", "SITE_KEY", {
|
|
172
|
+
proxyType: "http",
|
|
173
|
+
proxyAddress: "1.2.3.4",
|
|
174
|
+
proxyPort: 8080,
|
|
175
|
+
proxyLogin: "user",
|
|
176
|
+
proxyPassword: "pass",
|
|
177
|
+
proxy: true,
|
|
88
178
|
});
|
|
89
179
|
```
|
|
90
180
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
<div><b>2</b> = captcha does not contain any digits</div>
|
|
129
|
-
</td>
|
|
130
|
-
</tr>
|
|
131
|
-
<tr>
|
|
132
|
-
<td>calc</td>
|
|
133
|
-
<td>integer</td>
|
|
134
|
-
<td>0, 1</td>
|
|
135
|
-
<td>
|
|
136
|
-
<div><b>0</b> = default value</div>
|
|
137
|
-
<div><b>1</b> = arithmetical operation must be performed</div>
|
|
138
|
-
</td>
|
|
139
|
-
</tr>
|
|
140
|
-
<tr>
|
|
141
|
-
<td>min_len</td>
|
|
142
|
-
<td>integer</td>
|
|
143
|
-
<td>0..20</td>
|
|
144
|
-
<td>
|
|
145
|
-
<div><b>0</b> = default value</div>
|
|
146
|
-
<div><b>1..20</b> = minimum length of captcha text required to input</div>
|
|
147
|
-
</td>
|
|
148
|
-
</tr>
|
|
149
|
-
<tr>
|
|
150
|
-
<td>max_len</td>
|
|
151
|
-
<td>integer</td>
|
|
152
|
-
<td>0..20</td>
|
|
153
|
-
<td>
|
|
154
|
-
<div><b>0</b> = default value</div>
|
|
155
|
-
<div><b>1..20</b> = maximum length of captcha text required to input</div>
|
|
156
|
-
</td>
|
|
157
|
-
</tr>
|
|
158
|
-
<tr>
|
|
159
|
-
<td>is_russian</td>
|
|
160
|
-
<td>integer</td>
|
|
161
|
-
<td>0, 1</td>
|
|
162
|
-
<td>
|
|
163
|
-
<div><b>0</b> = default value</div>
|
|
164
|
-
<div><b>1</b> = captcha goes to Russian Queue</div>
|
|
165
|
-
</td>
|
|
166
|
-
</tr>
|
|
167
|
-
</tbody><tbody>
|
|
168
|
-
</tbody></table>
|
|
181
|
+
## Exported Types
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
import type {
|
|
185
|
+
SolverOptions,
|
|
186
|
+
TaskResult,
|
|
187
|
+
TokenSolution,
|
|
188
|
+
GRecaptchaSolution,
|
|
189
|
+
ImageSolution,
|
|
190
|
+
GeeTestSolution,
|
|
191
|
+
GeeTestV4Solution,
|
|
192
|
+
ProxyOptions,
|
|
193
|
+
RecaptchaV2Options,
|
|
194
|
+
HCaptchaOptions,
|
|
195
|
+
TurnstileOptions,
|
|
196
|
+
// ... and more
|
|
197
|
+
} from "recognize";
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Migration from v2
|
|
201
|
+
|
|
202
|
+
| v2 (old) | v3 (current) |
|
|
203
|
+
| --------------------------------------- | ------------------------------- |
|
|
204
|
+
| `new Recognize(SOURCE.RUCAPTCHA, {})` | `new RuCaptcha({ apiKey })` |
|
|
205
|
+
| `new Recognize(SOURCE.ANTICAPTCHA, {})` | `new AntiCaptcha({ apiKey })` |
|
|
206
|
+
| `{ key: "..." }` | `{ apiKey: "..." }` |
|
|
207
|
+
| `balanse()` | `getBalance()` |
|
|
208
|
+
| `solvingImage(buff)` | `imageCaptcha(buff)` |
|
|
209
|
+
| `solvingRecaptcha2()` | `recaptchaV2(url, key)` |
|
|
210
|
+
| `solvingRecaptcha3()` | `recaptchaV3(url, key, action)` |
|
|
211
|
+
| `reportGood(id)` | `reportCorrect(taskId)` |
|
|
212
|
+
| `reportBad(id)` | `reportIncorrect(taskId)` |
|
|
213
|
+
| return `{ id, result }` | return `{ taskId, solution }` |
|
|
214
|
+
|
|
215
|
+
## License
|
|
216
|
+
|
|
217
|
+
MIT
|