ruby-2captcha 1.1.6 → 1.2.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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec_status +16 -7
  3. data/.ruby-version +1 -1
  4. data/Gemfile.lock +1 -1
  5. data/README.md +198 -4
  6. data/README.ru.md +203 -0
  7. data/api_2captcha.gemspec +1 -1
  8. data/examples/alibaba_example.rb +16 -0
  9. data/examples/altcha_example.rb +12 -0
  10. data/examples/amazon_waf_example.rb +14 -0
  11. data/examples/basilisk_example.rb +15 -0
  12. data/examples/binance_example.rb +17 -0
  13. data/examples/canvas_example.rb +13 -0
  14. data/examples/captchafox_example.rb +20 -0
  15. data/examples/capy_example.rb +11 -0
  16. data/examples/cloudflare_turnstile_example.rb +15 -0
  17. data/examples/coordinates_example.rb +12 -0
  18. data/examples/cut_captcha_example.rb +11 -0
  19. data/examples/cyber_siara_example.rb +10 -0
  20. data/examples/datadome_example.rb +12 -0
  21. data/examples/drag_drop_example.rb +24 -0
  22. data/examples/friendly_captcha_example.rb +10 -0
  23. data/examples/funcaptcha_example.rb +10 -0
  24. data/examples/geetest_example.rb +12 -0
  25. data/examples/geetest_v4_example.rb +10 -0
  26. data/examples/hcaptcha_example.rb +10 -0
  27. data/examples/hunt_example.rb +17 -0
  28. data/examples/key_captcha_example.rb +13 -0
  29. data/examples/lemin_example.rb +12 -0
  30. data/examples/media/drag_drop/background.jpeg +0 -0
  31. data/examples/media/drag_drop/image1.jpeg +0 -0
  32. data/examples/media/drag_drop/image2.jpeg +0 -0
  33. data/examples/media/temu/body.png +0 -0
  34. data/examples/media/temu/part1.png +0 -0
  35. data/examples/media/temu/part2.png +0 -0
  36. data/examples/media/temu/part3.png +0 -0
  37. data/examples/mt_captcha_example.rb +10 -0
  38. data/examples/normal_captcha_example.rb +4 -2
  39. data/examples/prosopo_example.rb +16 -0
  40. data/examples/recaptcha_v2_example.rb +1 -1
  41. data/examples/recaptcha_v3_example.rb +18 -0
  42. data/examples/rotate_example.rb +13 -0
  43. data/examples/temu_example.rb +28 -0
  44. data/examples/text_example.rb +10 -0
  45. data/examples/tspd_example.rb +19 -0
  46. data/examples/vkcaptcha_example.ru +10 -0
  47. data/examples/vkimage_example.rb +10 -0
  48. data/examples/yandex_example.rb +10 -0
  49. data/examples/yidun_example.rb +15 -0
  50. data/howto.txt +8 -0
  51. data/lib/api_2captcha/client.rb +53 -1
  52. data/lib/api_2captcha/version.rb +1 -1
  53. metadata +48 -7
@@ -0,0 +1,12 @@
1
+ require 'api_2captcha'
2
+
3
+ client = Api2Captcha.new("YOUR_API_KEY")
4
+
5
+ result = client.coordinates({
6
+ image: 'path/to/captcha.jpg',
7
+ lang: 'en',
8
+ hint_image: 'path/to/hint.jpg',
9
+ hint_text: 'Connect the dots'
10
+ })
11
+
12
+ puts "Result: #{result.inspect}"
@@ -0,0 +1,11 @@
1
+ require 'api_2captcha'
2
+
3
+ client = Api2Captcha.new("YOUR_API_KEY")
4
+
5
+ result = client.cutcaptcha({
6
+ misery_key: "a1488b66da00bf332a1488993a5443c79047e752",
7
+ api_key: "SAb83IIB",
8
+ pageurl: "https://example.cc/foo/bar.html"
9
+ })
10
+
11
+ puts "Result: #{result.inspect}"
@@ -0,0 +1,10 @@
1
+ require 'api_2captcha'
2
+
3
+ client = Api2Captcha.new("YOUR_API_KEY")
4
+
5
+ result = client.cyber_siara({
6
+ pageurl: "https://test.com",
7
+ master_url_id: "12333-3123123"
8
+ })
9
+
10
+ puts "Result: #{result.inspect}"
@@ -0,0 +1,12 @@
1
+ require 'api_2captcha'
2
+
3
+ client = Api2Captcha.new("YOUR_API_KEY")
4
+
5
+ result = client.data_dome({
6
+ pageurl: "https://test.com",
7
+ captcha_url: "https://test.com/captcha/",
8
+ proxytype: "http",
9
+ proxy: "proxyuser:strongPassword@123.123.123.123:3128"
10
+ })
11
+
12
+ puts "Result: #{result.inspect}"
@@ -0,0 +1,24 @@
1
+ require_relative "../lib/api_2captcha"
2
+
3
+ client = Api2Captcha.new(ARGV[0])
4
+
5
+ # NOTE: images below are placeholder illustrations, not a real captcha demo.
6
+ backgroundFile = File.expand_path("../media/drag_drop/background.jpeg", __FILE__)
7
+ image1File = File.expand_path("../media/drag_drop/image1.jpeg", __FILE__)
8
+ image2File = File.expand_path("../media/drag_drop/image2.jpeg", __FILE__)
9
+
10
+ backgroundStr = Base64.strict_encode64(File.binread(backgroundFile))
11
+ image1Str = Base64.strict_encode64(File.binread(image1File))
12
+ image2Str = Base64.strict_encode64(File.binread(image2File))
13
+
14
+ begin
15
+ result = client.drag_drop({
16
+ body: backgroundStr,
17
+ images: [image1Str, image2Str],
18
+ textinstructions: "Drag the images to proper position"
19
+ })
20
+ rescue StandardError => e
21
+ puts(e)
22
+ end
23
+
24
+ puts "Result: #{result.inspect}"
@@ -0,0 +1,10 @@
1
+ require 'api_2captcha'
2
+
3
+ client = Api2Captcha.new("YOUR_API_KEY")
4
+
5
+ result = client.friendly({
6
+ pageurl: "https://example.com",
7
+ sitekey: "2FZFEVS1FZCGQ9"
8
+ })
9
+
10
+ puts "Result: #{result.inspect}"
@@ -0,0 +1,10 @@
1
+ require 'api_2captcha'
2
+
3
+ client = Api2Captcha.new("YOUR_API_KEY")
4
+
5
+ result = client.funcaptcha({
6
+ publickey: "69A21A01-CC7B-B9C6-0F9A-E7FA06677FFC",
7
+ pageurl: "https://mysite.com/page/with/funcaptcha",
8
+ surl: "https://client-api.arkoselabs.com"})
9
+
10
+ puts "Result: #{result.inspect}"
@@ -0,0 +1,12 @@
1
+ require 'api_2captcha'
2
+
3
+ client = Api2Captcha.new("YOUR_API_KEY")
4
+
5
+ result = client.geetest({
6
+ gt: 'f1ab2cdefa3456789012345b6c78d90e',
7
+ api_server: 'api-na.geetest.com',
8
+ challenge: '12345678abc90123d45678ef90123a456b',
9
+ pageurl: 'https://www.site.com/page/'
10
+ })
11
+
12
+ puts "Result: #{result.inspect}"
@@ -0,0 +1,10 @@
1
+ require 'api_2captcha'
2
+
3
+ client = Api2Captcha.new("YOUR_API_KEY")
4
+
5
+ result = client.geetest_v4({
6
+ captcha_id: 'e392e1d7fd421dc63325744d5a2b9c73',
7
+ pageurl: 'https://www.site.com/page/'
8
+ })
9
+
10
+ puts "Result: #{result.inspect}"
@@ -0,0 +1,10 @@
1
+ require 'api_2captcha'
2
+
3
+ client = Api2Captcha.new("YOUR_API_KEY")
4
+
5
+ result = client.hcaptcha({
6
+ sitekey: '10000000-ffff-ffff-ffff-000000000001',
7
+ pageurl: 'https://www.site.com/page/'
8
+ })
9
+
10
+ puts "Result: #{result.inspect}"
@@ -0,0 +1,17 @@
1
+ require_relative "../lib/api_2captcha"
2
+
3
+ client = Api2Captcha.new(ARGV[0])
4
+
5
+ begin
6
+ result = client.hunt({
7
+ pageurl: "https://example.com/page-with-hunt",
8
+ api_get_lib: "https://example.com/hd-api/external/apps/app-id/api.js",
9
+ userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
10
+ proxytype: "http",
11
+ proxy: "proxyuser:strongPassword@123.123.123.123:3128"
12
+ })
13
+ rescue StandardError => e
14
+ puts(e)
15
+ end
16
+
17
+ puts "Result: #{result.inspect}"
@@ -0,0 +1,13 @@
1
+ require 'api_2captcha'
2
+
3
+ client = Api2Captcha.new("YOUR_API_KEY")
4
+
5
+ result = client.keycaptcha({
6
+ s_s_c_user_id: 10,
7
+ s_s_c_session_id: '493e52c37c10c2bcdf4a00cbc9ccd1e8',
8
+ s_s_c_web_server_sign: '9006dc725760858e4c0715b835472f22-pz-',
9
+ s_s_c_web_server_sign2: '2ca3abe86d90c6142d5571db98af6714',
10
+ pageurl: 'https://www.keycaptcha.ru/demo-magnetic/'
11
+ })
12
+
13
+ puts "Result: #{result.inspect}"
@@ -0,0 +1,12 @@
1
+ require 'api_2captcha'
2
+
3
+ client = Api2Captcha.new("YOUR_API_KEY")
4
+
5
+ result = client.lemin({
6
+ captcha_id: 'CROPPED_1abcd2f_a1234b567c890d12ef3a456bc78d901d',
7
+ div_id: 'lemin-cropped-captcha',
8
+ pageurl: 'https://www.site.com/page/',
9
+ api_server: "https://api.leminnow.com/"
10
+ })
11
+
12
+ puts "Result: #{result.inspect}"
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,10 @@
1
+ require 'api_2captcha'
2
+
3
+ client = Api2Captcha.new("YOUR_API_KEY")
4
+
5
+ result = client.mt_captcha({
6
+ pageurl: "https://service.mtcaptcha.com/mtcv1/demo/index.html",
7
+ sitekey: "MTPublic-DemoKey9M"
8
+ })
9
+
10
+ puts "Result: #{result.inspect}"
@@ -1,9 +1,11 @@
1
1
  require 'api_2captcha'
2
2
 
3
- client = Api2Captcha.new("YOUR_API_KEY")
3
+ client = Api2Captcha.new(ARGV[0])
4
+
5
+ image_absolute_path = File.expand_path("../media/normal_2.jpg", __FILE__)
4
6
 
5
7
  result = client.normal({
6
- image: './media/normal_2.jpg',
8
+ image: image_absolute_path,
7
9
  })
8
10
 
9
11
  puts "Result: #{result.inspect}"
@@ -0,0 +1,16 @@
1
+
2
+ require_relative '../lib/api_2captcha'
3
+
4
+ client = Api2Captcha.new(ARGV[0])
5
+
6
+ begin
7
+ result = client.prosopo({
8
+ pageurl: "https://www.twickets.live/",
9
+ sitekey: "5EZVvsHMrKCFKp5NYNoTyDjTjetoVo1Z4UNNbTwJf1GfN6Xm",
10
+ })
11
+ rescue StandardError => e
12
+ puts(e)
13
+ end
14
+
15
+
16
+ puts "Result: #{result.inspect}"
@@ -1,6 +1,6 @@
1
1
  require 'api_2captcha'
2
2
 
3
- client = Api2Captcha.new("YOUR_API_KEY")
3
+ client = Api2Captcha.new(ARGV[0])
4
4
 
5
5
  result = client.recaptcha_v2({
6
6
  googlekey: '6LfD3PIbAAAAAJs_eEHvoOl75_83eXSqpPSRFJ_u',
@@ -0,0 +1,18 @@
1
+ require_relative '../lib/api_2captcha'
2
+
3
+ client = Api2Captcha.new(ARGV[0])
4
+
5
+ begin
6
+ result = client.recaptcha_v3({
7
+ googlekey: "6LfD3PIbAAAAAJs_eEHvoOl75_83eXSqpPSRFJ_u",
8
+ pageurl: "http://2captcha.com/demo/recaptcha-v3",
9
+ version: "v3",
10
+ score: 0.3,
11
+ action: "verify"
12
+ })
13
+ rescue StandardError => e
14
+ puts(e)
15
+ end
16
+
17
+
18
+ puts "Result: #{result.inspect}"
@@ -0,0 +1,13 @@
1
+ require 'api_2captcha'
2
+
3
+ client = Api2Captcha.new("YOUR_API_KEY")
4
+
5
+ result = client.rotate({
6
+ image: 'path/to/captcha.jpg',
7
+ angle: 40,
8
+ lang: 'en',
9
+ hint_image: 'path/to/hint.jpg',
10
+ hint_text: 'Put the images in the correct way'
11
+ })
12
+
13
+ puts "Result: #{result.inspect}"
@@ -0,0 +1,28 @@
1
+
2
+ require_relative '../lib/api_2captcha'
3
+
4
+ client = Api2Captcha.new(ARGV[0])
5
+
6
+ bodyFile = File.expand_path("../media/temu/body.png", __FILE__)
7
+ part1File = File.expand_path("../media/temu/part1.png", __FILE__)
8
+ part2File = File.expand_path("../media/temu/part2.png", __FILE__)
9
+ part3File = File.expand_path("../media/temu/part3.png", __FILE__)
10
+
11
+ bodyStr = Base64.strict_encode64(File.binread(bodyFile))
12
+ part1Str = Base64.strict_encode64(File.binread(part1File))
13
+ part2Str = Base64.strict_encode64(File.binread(part2File))
14
+ part3Str = Base64.strict_encode64(File.binread(part3File))
15
+
16
+ begin
17
+ result = client.temu({
18
+ body: bodyStr,
19
+ part1: part1Str,
20
+ part2: part2Str,
21
+ part3: part3Str,
22
+ })
23
+ rescue StandardError => e
24
+ puts(e)
25
+ end
26
+
27
+
28
+ puts "Result: #{result.inspect}"
@@ -0,0 +1,10 @@
1
+ require 'api_2captcha'
2
+
3
+ client = Api2Captcha.new("YOUR_API_KEY")
4
+
5
+ result = client.text({
6
+ textcaptcha:'If tomorrow is Saturday, what day is today?',
7
+ lang: "en"
8
+ })
9
+
10
+ puts "Result: #{result.inspect}"
@@ -0,0 +1,19 @@
1
+
2
+ require_relative '../lib/api_2captcha'
3
+
4
+ client = Api2Captcha.new(ARGV[0])
5
+
6
+ begin
7
+ result = client.tspd({
8
+ pageurl: "https://example.com/page-with-tspd",
9
+ tspd_cookie: "TS...",
10
+ html_page_base64: "PGh0bWw+...",
11
+ userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
12
+ proxytype: "http",
13
+ proxy: "proxyuser:strongPassword@123.123.123.123:3128"
14
+ })
15
+ rescue StandardError => e
16
+ puts(e)
17
+ end
18
+
19
+ puts "Result: #{result.inspect}"
@@ -0,0 +1,10 @@
1
+ require 'api_2captcha'
2
+
3
+ client = Api2Captcha.new("YOUR_API_KEY")
4
+
5
+ result = client.vkcaptcha({
6
+ redirect_uri: 'https://id.vk.com/not_robot_captcha?domain=vk.com&session_token=eyJ....HGsc5B4LyvjA&variant=popup&blank=1',
7
+ userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36'
8
+ })
9
+
10
+ puts "Result: #{result.inspect}"
@@ -0,0 +1,10 @@
1
+ require 'api_2captcha'
2
+
3
+ client = Api2Captcha.new("YOUR_API_KEY")
4
+
5
+ result = client.vkimage({
6
+ image: '/9j/4AAQSkZJRgABAQAAAQABAAD/2...',
7
+ steps: '[5,19,14,14,6,4,8...]'
8
+ })
9
+
10
+ puts "Result: #{result.inspect}"
@@ -0,0 +1,10 @@
1
+ require 'api_2captcha'
2
+
3
+ client = Api2Captcha.new("YOUR_API_KEY")
4
+
5
+ result = client.yandex({
6
+ sitekey: 'Y5Lh0tiycconMJGsFd3EbbuNKSp1yaZESUOIHfeV',
7
+ url: "https://rutube.ru"
8
+ })
9
+
10
+ puts "Result: #{result.inspect}"
@@ -0,0 +1,15 @@
1
+
2
+ require_relative '../lib/api_2captcha'
3
+
4
+ client = Api2Captcha.new(ARGV[0])
5
+
6
+ begin
7
+ result = client.yidun({
8
+ pageurl: "https://example.com/page-with-yidun",
9
+ sitekey: "SITE_KEY"
10
+ })
11
+ rescue StandardError => e
12
+ puts(e)
13
+ end
14
+
15
+ puts "Result: #{result.inspect}"
data/howto.txt ADDED
@@ -0,0 +1,8 @@
1
+
2
+ ruby examples/prosopo_example.rb API_KEY
3
+
4
+ API_KEY=API_KEY_123 rspec spec/api_2captcha_spec.rb --tag recaptcha_v3
5
+
6
+ rake spec
7
+ rake -T
8
+ ruby api_2captcha_spec.rb
@@ -134,7 +134,7 @@ module Api2Captcha
134
134
  end
135
135
 
136
136
  def grid(params)
137
- params[:recaptcha] = 1
137
+ params["recaptcha"] = 1
138
138
  solve("post", **params)
139
139
  end
140
140
 
@@ -170,6 +170,14 @@ module Api2Captcha
170
170
  solve("amazon_waf", **params)
171
171
  end
172
172
 
173
+ def vkimage(params)
174
+ solve("vkimage", **params)
175
+ end
176
+
177
+ def vkcaptcha(params)
178
+ solve("vkcaptcha", **params)
179
+ end
180
+
173
181
  def audio(params)
174
182
  audio = params.delete(:audio)
175
183
  audio_content = File.file?(audio) ? File.binread(audio) : audio
@@ -213,6 +221,50 @@ module Api2Captcha
213
221
  solve("atb_captcha", **params)
214
222
  end
215
223
 
224
+ def prosopo(params)
225
+ solve("prosopo", **params)
226
+ end
227
+
228
+ def captchafox(params)
229
+ solve("captchafox", **params)
230
+ end
231
+
232
+ def altcha(params)
233
+ solve("altcha", **params)
234
+ end
235
+
236
+ def temu(params)
237
+ solve("temuimage", **params)
238
+ end
239
+
240
+ def binance(params)
241
+ solve("binance", **params)
242
+ end
243
+
244
+ def hunt(params)
245
+ solve("hunt", **params)
246
+ end
247
+
248
+ def tspd(params)
249
+ solve("tspd", **params)
250
+ end
251
+
252
+ def basilisk(params)
253
+ solve("basilisk", **params)
254
+ end
255
+
256
+ def alibaba(params)
257
+ solve("alibaba", **params)
258
+ end
259
+
260
+ def yidun(params)
261
+ solve("yidun", **params)
262
+ end
263
+
264
+ def drag_drop(params)
265
+ solve("drag_drop", **params)
266
+ end
267
+
216
268
  private
217
269
 
218
270
  def base_url
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Api2Captcha
4
- VERSION = "1.1.6"
4
+ VERSION = "1.2.0"
5
5
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-2captcha
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.6
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - 2captcha.com
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-11-20 00:00:00.000000000 Z
11
+ date: 2026-09-17 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Ruby package for easy integration with the API of 2captcha captcha solving
14
- service to bypass recaptcha, hcaptcha, funcaptcha, geetest and solve any other captchas.
14
+ service to bypass recaptcha, funcaptcha, geetest and solve any other captchas.
15
15
  email:
16
16
  - info@2captcha.com
17
17
  executables: []
@@ -29,16 +29,57 @@ files:
29
29
  - README.ru.md
30
30
  - Rakefile
31
31
  - api_2captcha.gemspec
32
+ - examples/alibaba_example.rb
33
+ - examples/altcha_example.rb
34
+ - examples/amazon_waf_example.rb
32
35
  - examples/atb_captcha_example.rb
33
36
  - examples/audio_example.rb
37
+ - examples/basilisk_example.rb
38
+ - examples/binance_example.rb
39
+ - examples/canvas_example.rb
40
+ - examples/captchafox_example.rb
41
+ - examples/capy_example.rb
42
+ - examples/cloudflare_turnstile_example.rb
43
+ - examples/coordinates_example.rb
44
+ - examples/cut_captcha_example.rb
45
+ - examples/cyber_siara_example.rb
46
+ - examples/datadome_example.rb
47
+ - examples/drag_drop_example.rb
48
+ - examples/friendly_captcha_example.rb
49
+ - examples/funcaptcha_example.rb
50
+ - examples/geetest_example.rb
51
+ - examples/geetest_v4_example.rb
34
52
  - examples/grid_captcha_example.rb
53
+ - examples/hcaptcha_example.rb
54
+ - examples/hunt_example.rb
55
+ - examples/key_captcha_example.rb
56
+ - examples/lemin_example.rb
57
+ - examples/media/drag_drop/background.jpeg
58
+ - examples/media/drag_drop/image1.jpeg
59
+ - examples/media/drag_drop/image2.jpeg
35
60
  - examples/media/example.mp3
36
61
  - examples/media/normal_2.jpg
37
62
  - examples/media/recaptchaGrid4x4.jpg
38
63
  - examples/media/recaptchaGridImginstructions4x4.jpg
64
+ - examples/media/temu/body.png
65
+ - examples/media/temu/part1.png
66
+ - examples/media/temu/part2.png
67
+ - examples/media/temu/part3.png
68
+ - examples/mt_captcha_example.rb
39
69
  - examples/normal_captcha_example.rb
70
+ - examples/prosopo_example.rb
40
71
  - examples/recaptcha_v2_example.rb
72
+ - examples/recaptcha_v3_example.rb
73
+ - examples/rotate_example.rb
74
+ - examples/temu_example.rb
41
75
  - examples/tencent_example.rb
76
+ - examples/text_example.rb
77
+ - examples/tspd_example.rb
78
+ - examples/vkcaptcha_example.ru
79
+ - examples/vkimage_example.rb
80
+ - examples/yandex_example.rb
81
+ - examples/yidun_example.rb
82
+ - howto.txt
42
83
  - lib/api_2captcha.rb
43
84
  - lib/api_2captcha/api2captcha_exceptions.rb
44
85
  - lib/api_2captcha/client.rb
@@ -56,7 +97,7 @@ metadata:
56
97
  keywords: 2captcha, captcha solver, captcha bypass, Ruby, automation, CAPTCHA API,
57
98
  CAPTCHA recognition, anti-captcha, reCAPTCHA, OCR, image recognition, human verification,
58
99
  bot protection, recaptcha
59
- post_install_message:
100
+ post_install_message:
60
101
  rdoc_options: []
61
102
  require_paths:
62
103
  - lib
@@ -71,8 +112,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
71
112
  - !ruby/object:Gem::Version
72
113
  version: '0'
73
114
  requirements: []
74
- rubygems_version: 3.0.1
75
- signing_key:
115
+ rubygems_version: 3.4.1
116
+ signing_key:
76
117
  specification_version: 4
77
118
  summary: 2Captcha API wrapper for Ruby.
78
119
  test_files: []