anticaptchaofficial 1.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f1ad28663392944f25a7f6f29840c6689194c4f478d4f3a47364f3c61d241f50
4
+ data.tar.gz: 05ab6c1d0bc3d1732a4fb95a6fdd7d1f46af17171256e4999f13219e8422edc2
5
+ SHA512:
6
+ metadata.gz: 660639d5735936fd016159b8ac6efebb4b7c794229baf0802ff0219252e75a4376d7bf3e93b8833c30f53a6302ed754b9ff3877559544dd3a5a6cd6858e73da6
7
+ data.tar.gz: 9dc1f87b6da1b3e5fde9eeea7137da9bcbecbb01792fcd282630965ef5ea8b7e2d47ddcfcc687f6de7dd68a8d72c0e4b79beb74261ded698c5905aff88547e73
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 ANTICAPTCHA DEVELOPMENT LP
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,442 @@
1
+ ## Official Anti-Captcha.com Ruby gem ##
2
+
3
+ Official anti-captcha.com Ruby gem for solving images with text, Recaptcha v2/v3 Enterprise/non-Enterprise, Funcaptcha, GeeTest, HCaptcha Enterprise/non-Enterprise, Turnstile, Amazon WAF, Prosopo, Friendly Captcha and Altcha.
4
+
5
+ [Anti-captcha](https://anti-captcha.com) is an oldest and cheapest web service dedicated to solving captchas by human workers from around the world. By solving captchas with us you help people in poorest regions of the world to earn money, which not only cover their basic needs, but also gives them ability to financially help their families, study and avoid jobs where they're simply not happy.
6
+
7
+ To use the service you need to [register](https://anti-captcha.com/clients/) and topup your balance. Prices start from $0.0005 per image captcha and $0.002 for Recaptcha. That's $0.5 per 1000 for images and $2 for 1000 Recaptchas.
8
+
9
+ For more technical information and articles visit our [documentation](https://anti-captcha.com/apidoc) page.
10
+
11
+ **Install the gem**:
12
+ ```bash
13
+ gem install anticaptchaofficial
14
+ ```
15
+ or add it to your `Gemfile`:
16
+ ```ruby
17
+ gem "anticaptchaofficial"
18
+ ```
19
+
20
+ The gem is called `anticaptchaofficial`, what you require is `anticaptcha`:
21
+ ```ruby
22
+ require "anticaptcha"
23
+ ```
24
+
25
+ Requires Ruby 3.0 or newer and has **no runtime dependencies** — everything comes from the standard library.
26
+
27
+ **Examples how to solve:**
28
+
29
+ - [Image Captcha](#solve-image-captcha)
30
+ - [Recaptcha V2](#solve-recaptcha-v2)
31
+ - [Recaptcha V2 Enterprise](#solve-recaptcha-v2-enterprise)
32
+ - [Recaptcha V3](#solve-recaptcha-v3)
33
+ - [hCaptcha](#solve-hcaptcha)
34
+ - [FunCaptcha](#solve-funcaptcha)
35
+ - [GeeTest](#solve-geetest)
36
+ - [Turnstile](#solve-turnstile)
37
+ - [Image to coordinates](#image-to-coordinates)
38
+ - [AntiGate (custom tasks)](#solve-antigate-custom-tasks)
39
+ - [AntiBot cookies](#get-antibot-cookies)
40
+ - [Prosopo](#solve-prosopo)
41
+ - [Friendly Captcha](#solve-friendly-captcha)
42
+ - [Amazon WAF](#solve-amazon-waf)
43
+ - [Altcha](#solve-altcha)
44
+
45
+ ### Solve image captcha
46
+ ```ruby
47
+ require "anticaptcha"
48
+
49
+ # Create the API client and set the API key
50
+ ac = Anticaptcha.new("API_KEY_HERE")
51
+
52
+ # Specify a soft id to earn 10% commission with your app.
53
+ # Get yours at https://anti-captcha.com/clients/tools/devcenter
54
+ ac.soft_id = 0
55
+
56
+ # Set to false to turn the debug output off
57
+ ac.verbose = true
58
+
59
+ # Make sure the API key funds balance is positive
60
+ balance = ac.balance
61
+ if balance <= 0
62
+ # Stop here to make sure you don't DDoS the API while having empty balance
63
+ abort "Empty balance"
64
+ end
65
+ puts "Balance: #{balance}"
66
+
67
+ solution = ac.solve_image_file(
68
+ "captcha.jpg",
69
+ # Optional settings, see https://anti-captcha.com/apidoc/task-types/ImageToTextTask
70
+ # phrase: true, # the image has 2 or more words
71
+ # case_sensitive: true, # the answer is case sensitive
72
+ # numeric: 1, # 1 - digits only, 2 - no digits
73
+ # math_operation: true, # the answer is the result of 50+5
74
+ # min_length: 1,
75
+ # max_length: 10,
76
+ language_pool: "en", # "en" or "rn"
77
+ comment: "Type in green characters"
78
+ )
79
+ # OR ac.solve_image(body: "image-encoded-in-base64", ...)
80
+
81
+ puts "Captcha Solution: #{solution.text}"
82
+
83
+ # If the answer turns out to be wrong:
84
+ # ac.report_incorrect_image_captcha(solution.task_id)
85
+ ```
86
+ &nbsp;
87
+
88
+ ### Solve Recaptcha V2
89
+ ```ruby
90
+ solution = ac.solve_recaptcha_v2(
91
+ website_url: "https://www.website.com/",
92
+ website_key: "6Lcyu8UZAAAAACwSh6Xf58WrNXTu0LLu4F85xf20",
93
+ is_invisible: false, # set to true if you are solving an invisible Recaptcha V2
94
+ data_s_value: nil # fill this for a Recaptcha V2 with the "data-s" parameter,
95
+ # typically found at google.com websites
96
+ )
97
+
98
+ puts "Recaptcha g-response token: #{solution.g_recaptcha_response}"
99
+ # In case you need the worker's user-agent
100
+ puts "User-Agent: #{solution.user_agent}"
101
+ ```
102
+ Also with [proxy](https://anti-captcha.com/apidoc/task-types/RecaptchaV2Task):
103
+ ```ruby
104
+ solution = ac.solve_recaptcha_v2_proxy_on(
105
+ website_url: "https://www.website.com/",
106
+ website_key: "6Lcyu8UZAAAAACwSh6Xf58WrNXTu0LLu4F85xf20",
107
+ user_agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " \
108
+ "(KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
109
+ proxy: {
110
+ type: "http", # "http", "socks4" or "socks5", defaults to "http"
111
+ address: "1.2.3.4",
112
+ port: 1234,
113
+ login: "login-optional",
114
+ password: "pass-optional"
115
+ }
116
+ )
117
+ ```
118
+ &nbsp;
119
+
120
+ ### Solve Recaptcha V2 Enterprise
121
+ The same method, `is_enterprise` switches the task type:
122
+ ```ruby
123
+ solution = ac.solve_recaptcha_v2(
124
+ website_url: "https://store.steampowered.com/join",
125
+ website_key: "6LdIFr0ZAAAAAO3vz0O0OQrtAefzdJcWQM2TMYQH",
126
+ is_enterprise: true,
127
+ # set to "true" if there's "size":"invisible" option in "grecaptcha.enterprise.render" function
128
+ # is_invisible: true,
129
+ # Additional parameters passed to the grecaptcha.enterprise.render call
130
+ enterprise_payload: { "s" => "TEMPORARY_TOKEN_VALUE_IF_PRESENT", "action" => "form_submit" }
131
+ # api_domain: "recaptcha.net" # only for a non-google.com script domain
132
+ )
133
+
134
+ puts solution.g_recaptcha_response
135
+ ```
136
+ Use `solve_recaptcha_v2_proxy_on` for the proxy-on version.
137
+
138
+ &nbsp;
139
+
140
+ ### Solve Recaptcha V3
141
+ ```ruby
142
+ solution = ac.solve_recaptcha_v3(
143
+ website_url: "https://www.website.com/",
144
+ website_key: "6LcvNcwdAAAAAMWAuNRXH74u3QePsEzTm6GEjx0J",
145
+ page_action: "somefun",
146
+ min_score: 0.9 # one of 0.3, 0.7, 0.9
147
+ # is_enterprise: true # set to true for a Recaptcha V3 Enterprise
148
+ )
149
+
150
+ puts "Recaptcha g-response token: #{solution.g_recaptcha_response}"
151
+ ```
152
+ Recaptcha V3 has no proxy-on version.
153
+
154
+ &nbsp;
155
+
156
+ ### Solve Hcaptcha
157
+ ```ruby
158
+ solution = ac.solve_hcaptcha(
159
+ website_url: "https://www.website.com/",
160
+ website_key: "00000000-1111-2222-3333-444444444444"
161
+ # is_invisible: true,
162
+ # is_enterprise: true,
163
+ # hCaptcha Enterprise parameters like rqdata, sentry, apiEndpoint, endpoint,
164
+ # reportapi, assethost, imghost:
165
+ # enterprise_payload: { "rqdata" => "rqdata value from the target website" }
166
+ )
167
+
168
+ puts "Hcaptcha Token: #{solution.g_recaptcha_response}"
169
+ # Use this user-agent for the form submission
170
+ puts "User-Agent: #{solution.user_agent}"
171
+ # Optional "respkey" value, you may need it too
172
+ puts "respkey: #{solution.resp_key}"
173
+ ```
174
+ Also with [proxy](https://anti-captcha.com/apidoc/task-types/HCaptchaTask) — `solve_hcaptcha_proxy_on` with a `proxy:` hash.
175
+
176
+ &nbsp;
177
+
178
+ ### Solve FunCaptcha
179
+ ```ruby
180
+ solution = ac.solve_funcaptcha(
181
+ website_url: "https://www.website.com/",
182
+ website_public_key: "00000000-1111-2222-3333-444444444444",
183
+ # Make sure to find and set this correctly, look for a URL like
184
+ # https://somewebsite-api.arkoselabs.com/v2/00000000-1111-2222-3333-444444444444/api.js
185
+ api_subdomain: "somewebsite-api.arkoselabs.com",
186
+ data_blob: '{"blob":"HERE_COMES_THE_blob_VALUE"}'
187
+ )
188
+
189
+ puts "Funcaptcha Token: #{solution.token}"
190
+ ```
191
+ Also with [proxy](https://anti-captcha.com/apidoc/task-types/FunCaptchaTask) — `solve_funcaptcha_proxy_on`.
192
+
193
+ &nbsp;
194
+
195
+ ### Solve Turnstile
196
+ ```ruby
197
+ solution = ac.solve_turnstile(
198
+ website_url: "https://www.website.com/",
199
+ website_key: "0x4AAAAAAABD2Inoxs-yJ8bz"
200
+ # action: "optional page action",
201
+ # c_data: "cdata token for cloudflare",
202
+ # chl_page_data: "chlPageData token for cloudflare"
203
+ )
204
+
205
+ puts "Turnstile Token: #{solution.token}"
206
+ # In case you need the worker's user-agent
207
+ puts "User-Agent: #{solution.user_agent}"
208
+ ```
209
+ Also with [proxy](https://anti-captcha.com/apidoc/task-types/TurnstileTask) — `solve_turnstile_proxy_on`.
210
+
211
+ &nbsp;
212
+
213
+ ### Solve GeeTest
214
+ GeeTest has 2 versions, number 3 and 4. Number 3 requires the parameter `challenge`. Number 4 has the optional setting `init_parameters`.
215
+ ```ruby
216
+ solution = ac.solve_geetest(
217
+ website_url: "https://bitget.com/",
218
+ gt: "e9ca9c9ca19ad540a8017f5c107b2d0f",
219
+
220
+ # Solve GeeTest 4:
221
+ version: 4,
222
+ init_parameters: { "riskType" => "slide" }
223
+
224
+ # Solve GeeTest 3:
225
+ # version: 3,
226
+ # challenge: "1234567890abcdef1234567890abcdef"
227
+ )
228
+
229
+ # GeeTest v4
230
+ puts "captcha_id: #{solution.captcha_id}"
231
+ puts "lot_number: #{solution.lot_number}"
232
+ puts "pass_token: #{solution.pass_token}"
233
+ puts "gen_time: #{solution.gen_time}"
234
+ puts "captcha_output: #{solution.captcha_output}"
235
+
236
+ # GeeTest v3
237
+ # puts "#{solution.challenge} #{solution.seccode} #{solution.validate}"
238
+ ```
239
+ Also with [proxy](https://anti-captcha.com/apidoc/task-types/GeeTestTask) — `solve_geetest_proxy_on`.
240
+
241
+ &nbsp;
242
+
243
+ ### Image to coordinates
244
+ ```ruby
245
+ solution = ac.solve_image_to_coordinates_file(
246
+ "coordinates.jpg",
247
+ mode: "points", # "points" or "rectangles"
248
+ comment: "Select objects in the specified order"
249
+ )
250
+ # OR ac.solve_image_to_coordinates(body: "image-encoded-in-base64", ...)
251
+
252
+ puts "Objects X,Y coordinates: #{solution.coordinates.inspect}"
253
+ ```
254
+ &nbsp;
255
+
256
+ ### Solve AntiGate (custom tasks)
257
+ ```ruby
258
+ solution = ac.solve_antigate(
259
+ website_url: "http://antigate.com/logintest.php",
260
+ template_name: "Sign-in and wait for control text",
261
+ variables: {
262
+ "login_input_css" => "#login",
263
+ "login_input_value" => "the login",
264
+ "password_input_css" => "#password",
265
+ "password_input_value" => "the password",
266
+ "control_text" => "You have been logged successfully"
267
+ },
268
+ # The proxy is optional for AntiGate tasks
269
+ proxy: { address: "1.2.3.4", port: 1234, login: "login-optional", password: "pass-optional" }
270
+ # domains_of_interest: ["some-other-domain.com"]
271
+ )
272
+
273
+ puts "cookies: #{solution.cookies.inspect}"
274
+ puts "localStorage: #{solution.local_storage.inspect}"
275
+ puts "fingerprint: #{solution.fingerprint.inspect}"
276
+ puts "url: #{solution.url}"
277
+ ```
278
+ &nbsp;
279
+
280
+ ### Get AntiBot cookies
281
+ Makes a worker open the page through your proxy and hands you back the anti-bot cookies, so you can reuse them in your own requests. The proxy is required — the cookies are only valid for the IP address they were issued to.
282
+ ```ruby
283
+ solution = ac.solve_antibot_cookie(
284
+ website_url: "https://www.somewebsite.com/",
285
+ proxy: { address: "1.2.3.4", port: 3128, login: "login", password: "password" }
286
+ )
287
+
288
+ # Ready to be sent as a Cookie header
289
+ puts "Cookie: #{solution.cookie_header}"
290
+ puts "User-Agent: #{solution.fingerprint_user_agent}"
291
+ ```
292
+ &nbsp;
293
+
294
+ ### Solve Prosopo
295
+ ```ruby
296
+ solution = ac.solve_prosopo(
297
+ website_url: "https://www.website.com/",
298
+ website_key: "sitekey-here"
299
+ )
300
+
301
+ puts "Prosopo Token: #{solution.token}"
302
+ ```
303
+ Also with [proxy](https://anti-captcha.com/apidoc/task-types/ProsopoTask) — `solve_prosopo_proxy_on`.
304
+
305
+ &nbsp;
306
+
307
+ ### Solve Friendly Captcha
308
+ ```ruby
309
+ solution = ac.solve_friendly_captcha(
310
+ website_url: "https://www.website.com/",
311
+ website_key: "sitekey-here"
312
+ )
313
+
314
+ puts "Friendly Captcha Token: #{solution.token}"
315
+ ```
316
+ Also with [proxy](https://anti-captcha.com/apidoc/task-types/FriendlyCaptchaTask) — `solve_friendly_captcha_proxy_on`.
317
+
318
+ &nbsp;
319
+
320
+ ### Solve Amazon WAF
321
+ Two options here:
322
+
323
+ 1. When the captcha is at the bot filtering page and you need the `aws-waf-token` cookie:
324
+ ```ruby
325
+ solution = ac.solve_amazon(
326
+ website_url: "https://www.website.com/",
327
+ website_key: "key_value_from_window.gokuProps_object",
328
+ iv: "iv_value_from_window.gokuProps_object",
329
+ context: "context_value_from_window.gokuProps_object"
330
+ # captcha_script: "optional_captcha.js_script_url",
331
+ # challenge_script: "optional_challenge.js_script_url"
332
+ )
333
+
334
+ puts "aws-waf-token: #{solution.token}"
335
+ ```
336
+
337
+ 2. When the captcha is a standalone widget triggered by a user's action:
338
+ ```ruby
339
+ solution = ac.solve_amazon(
340
+ website_url: "https://www.website.com/",
341
+ # Captcha widget's API key from the AwsWafCaptcha.renderCaptcha function
342
+ website_key: "captcha_key_value",
343
+ waf_type: "widget",
344
+ # Full URL to jsapi.js
345
+ jsapi_script: "https://164cb210e333.edge.captcha-sdk.awswaf.com/164cb210e333/jsapi.js"
346
+ )
347
+ ```
348
+ Both options have a [proxy-on](https://anti-captcha.com/apidoc/task-types/AmazonTask) version — `solve_amazon_proxy_on`.
349
+
350
+ &nbsp;
351
+
352
+ ### Solve Altcha
353
+ ```ruby
354
+ solution = ac.solve_altcha(
355
+ website_url: "https://www.website.com/",
356
+
357
+ # Option 1: use the challenge URL (use one of the options!)
358
+ challenge_url: "/some/path/to/challenge/url"
359
+
360
+ # Option 2: use the challenge JSON
361
+ # challenge_json: '{"algorithm":"SHA-256","challenge":"1a40f7ba3393f9513016879de41c7221f14e563856de2f647233a00accf9c28b","salt":"0887f273d79df143355b9e5f","signature":"1de2bbf282420aef6ca0a84c38c85e2b1e40023d28bef72278d735555a8f47fb"}'
362
+ )
363
+
364
+ puts "Altcha Token: #{solution.token}"
365
+ ```
366
+ Also with [proxy](https://anti-captcha.com/apidoc/task-types/AltchaTask) — `solve_altcha_proxy_on`.
367
+
368
+ &nbsp;
369
+
370
+ ### Error handling
371
+ Every method raises on failure. All errors descend from `Anticaptcha::Error`, which descends from `StandardError`:
372
+
373
+ | Class | When |
374
+ |---|---|
375
+ | `Anticaptcha::InvalidTaskError` | a required parameter is missing or out of range, nothing was sent |
376
+ | `Anticaptcha::NetworkError` | the API could not be reached |
377
+ | `Anticaptcha::BadResponseError` | the API answered with something unexpected, see `#raw` |
378
+ | `Anticaptcha::ApiError` | the API answered with a non-zero `errorId`, see `#error_code` |
379
+ | `Anticaptcha::TimeoutError` | the task was still unsolved when the waiting limit ran out |
380
+
381
+ ```ruby
382
+ begin
383
+ solution = ac.solve_recaptcha_v2(website_url: url, website_key: key)
384
+ puts solution.g_recaptcha_response
385
+ rescue Anticaptcha::ApiError => e
386
+ # https://anti-captcha.com/apidoc/errors
387
+ retry if e.retryable?
388
+ warn "#{e.error_code}: #{e.description}"
389
+ rescue Anticaptcha::Error => e
390
+ warn e.message
391
+ end
392
+ ```
393
+
394
+ ### Reading the solution
395
+ `Solution` wraps the API's `solution` object. Readers for fields a task type does not fill return `nil`:
396
+
397
+ ```ruby
398
+ solution.text # image captchas
399
+ solution.token # FunCaptcha, Turnstile, Prosopo, Friendly Captcha, Altcha, Amazon
400
+ solution.g_recaptcha_response # Recaptcha, hCaptcha
401
+ solution.user_agent # worker's user-agent
402
+ solution.cookies # AntiGate, AntiBotCookie
403
+ solution.cookie_header # the same cookies as a ready "name=value; ..." string
404
+ solution.coordinates # ImageToCoordinates
405
+ solution.task_id # for the report_* methods
406
+ solution.cost # what the task cost, in US dollars
407
+ solution.raw # the whole hash, for anything not listed above
408
+ solution["someNewField"] # any field by its API name
409
+ ```
410
+
411
+ ### Other settings
412
+ ```ruby
413
+ ac = Anticaptcha.new("API_KEY_HERE", soft_id: 1187, verbose: false)
414
+
415
+ ac.connection_timeout = 30 # seconds per HTTP call to the API
416
+ ac.first_attempt_waiting_interval = 5 # seconds before the first status request
417
+ ac.normal_waiting_interval = 5 # seconds between the following ones
418
+ ac.max_waiting_time = 300 # seconds before giving up on the task
419
+
420
+ ac.last_task_info # full getTaskResult response of the last task
421
+ ```
422
+
423
+ A task type this gem does not wrap yet can still be sent by hand:
424
+ ```ruby
425
+ solution = ac.solve_task(
426
+ "type" => "SomeNewTaskProxyless",
427
+ "websiteURL" => "https://www.website.com/"
428
+ )
429
+ ```
430
+
431
+ ### Running the examples and tests
432
+ ```bash
433
+ git clone https://github.com/anti-captcha/anticaptcha-ruby.git
434
+ cd anticaptcha-ruby
435
+
436
+ # unit tests, they need no API key and no network
437
+ rake test
438
+
439
+ # put your API key into examples/solve.rb first
440
+ ruby examples/solve.rb image
441
+ ```
442
+ Run the example without an argument to see the full list.