ruby-2captcha 1.0.3 → 1.0.5
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 +4 -4
- data/.ruby-version +1 -1
- data/README.md +1 -2
- data/README.ru.md +3 -1
- data/lib/api_2captcha/client.rb +219 -217
- data/lib/api_2captcha/version.rb +1 -1
- data/lib/api_2captcha.rb +3 -3
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6cc7d94f83479f1d8c57bb4cf2315a2fcb04475a7c9f2ca170b09648d95d830e
|
4
|
+
data.tar.gz: 759ff2de9c3fed201fcb467e52b4fe2c0d24af9c006596ed58002c3b2f7b42b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c9f92edcd7270fa86a6fcc287734596c8a9de31bb491451ab2569adb3d555c104716436cfb386dab9d95e0a4bb747a85e6a4dfc7ff705c4ae2b31689e8615ad
|
7
|
+
data.tar.gz: 71bd866a8dfe6e82b49abe66537ec7d2b0bcdef58e6e2bace9f9fc024a0e21e071aaa021cca517a31bf2f1d2b3296c94ece3485a76dab9d2d92190aab86c84aa
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
2.6.0
|
data/README.md
CHANGED
@@ -34,7 +34,6 @@ A Ruby client for the 2Captcha API.
|
|
34
34
|
- [Error handling](#error-handling)
|
35
35
|
|
36
36
|
## Installation
|
37
|
-
|
38
37
|
Add this line to your application's Gemfile:
|
39
38
|
|
40
39
|
```bash
|
@@ -56,7 +55,7 @@ $ gem install ruby-2captcha
|
|
56
55
|
To use the api2captcha gem, you'll need to import the module and create a Client instance. Here's an example:
|
57
56
|
|
58
57
|
```ruby
|
59
|
-
require '
|
58
|
+
require 'api_2captcha'
|
60
59
|
|
61
60
|
client = Api2Captcha.new("YOUR_API_KEY")
|
62
61
|
```
|
data/README.ru.md
CHANGED
@@ -32,7 +32,6 @@ Ruby-клиент для API 2Captcha.
|
|
32
32
|
- [Обработка ошибок](#error-handling)
|
33
33
|
|
34
34
|
## Установка
|
35
|
-
|
36
35
|
Автоматическая установка гема с помощью Bundler. Добавьте следующую строку в ваш Gemfile:
|
37
36
|
```ruby
|
38
37
|
gem 'ruby-2captcha'
|
@@ -54,7 +53,10 @@ gem install ruby-2captcha
|
|
54
53
|
Описание всех необходимых параметров для настройки установленного гема.
|
55
54
|
|
56
55
|
Экземпляр класса Api2Captcha можно создать следующим образом:
|
56
|
+
|
57
57
|
```ruby
|
58
|
+
require 'api_2captcha'
|
59
|
+
|
58
60
|
client = Api2Captcha.new("YOUR_API_KEY")
|
59
61
|
```
|
60
62
|
|
data/lib/api_2captcha/client.rb
CHANGED
@@ -5,277 +5,279 @@ require 'json'
|
|
5
5
|
require 'base64'
|
6
6
|
require 'open-uri'
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
def solve(method, params = {}, file_path = nil, return_id: false)
|
30
|
-
params["method"] = method
|
31
|
-
params["key"] = @api_key
|
32
|
-
params["soft_id"] = @soft_id
|
33
|
-
params["json"] = 1
|
34
|
-
|
35
|
-
if @callback
|
36
|
-
params["pingback"] = @callback
|
37
|
-
return_id = true
|
8
|
+
module Api2Captcha
|
9
|
+
class Client
|
10
|
+
DEFAULT_DOMAIN = "2captcha.com"
|
11
|
+
BASE_URL_FORMAT = "https://%s"
|
12
|
+
|
13
|
+
attr_reader :api_key, :soft_id
|
14
|
+
|
15
|
+
attr_accessor :domain, :callback,
|
16
|
+
:default_timeout,
|
17
|
+
:recaptcha_timeout,
|
18
|
+
:polling_interval
|
19
|
+
|
20
|
+
def initialize(api_key, soft_id = 0, callback = nil)
|
21
|
+
@api_key = api_key
|
22
|
+
@soft_id = soft_id
|
23
|
+
@callback = callback
|
24
|
+
@default_timeout = 120
|
25
|
+
@recaptcha_timeout = 600
|
26
|
+
@polling_interval = 10
|
27
|
+
@domain = DEFAULT_DOMAIN
|
38
28
|
end
|
39
29
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
30
|
+
def solve(method, params = {}, file_path = nil, return_id: false)
|
31
|
+
params["method"] = method
|
32
|
+
params["key"] = @api_key
|
33
|
+
params["soft_id"] = @soft_id
|
34
|
+
params["json"] = 1
|
45
35
|
|
46
|
-
|
47
|
-
|
48
|
-
|
36
|
+
if @callback
|
37
|
+
params["pingback"] = @callback
|
38
|
+
return_id = true
|
39
|
+
end
|
49
40
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
method = arg.delete(:method) || "POST"
|
55
|
-
solve(method, arg, return_id: true)
|
56
|
-
else
|
57
|
-
raise ArgumentError, "Invalid arguments of the send method"
|
41
|
+
complete_params = get_params(params)
|
42
|
+
captcha_id = send_request(complete_params)
|
43
|
+
return captcha_id if return_id
|
44
|
+
get_result(captcha_id)
|
58
45
|
end
|
59
|
-
end
|
60
46
|
|
61
|
-
|
62
|
-
|
63
|
-
|
47
|
+
def send(*args)
|
48
|
+
raise ArgumentError,
|
49
|
+
"Invalid arguments of the send method" unless args.size == 1
|
64
50
|
|
65
|
-
|
66
|
-
|
51
|
+
arg = args.first
|
52
|
+
if arg.is_a?(String)
|
53
|
+
solve("POST", {}, arg, return_id: true)
|
54
|
+
elsif arg.is_a?(Hash)
|
55
|
+
method = arg.delete(:method) || "POST"
|
56
|
+
solve(method, arg, return_id: true)
|
57
|
+
else
|
58
|
+
raise ArgumentError, "Invalid arguments of the send method"
|
59
|
+
end
|
60
|
+
end
|
67
61
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
62
|
+
def get_result(captcha_id)
|
63
|
+
uri = URI("#{base_url}/res.php?key=#{@api_key}&action=get&id=#{captcha_id}&json=1")
|
64
|
+
start_time = Time.now
|
65
|
+
|
66
|
+
loop do
|
67
|
+
response = make_request(uri)
|
68
|
+
|
69
|
+
case response
|
70
|
+
when Net::HTTPSuccess
|
71
|
+
response_json = JSON.parse(response.body)
|
72
|
+
if response_json["status"] == 1
|
73
|
+
return response_json["request"]
|
74
|
+
elsif response_json["request"] == "CAPCHA_NOT_READY"
|
75
|
+
sleep(polling_interval)
|
76
|
+
else
|
77
|
+
raise ApiException, "API Error: #{response_json["request"]}"
|
78
|
+
end
|
75
79
|
else
|
76
|
-
raise
|
80
|
+
raise NetworkException, "Network Error: #{response.code.to_i}"
|
77
81
|
end
|
78
|
-
else
|
79
|
-
raise NetworkException, "Network Error: #{response.code.to_i}"
|
80
|
-
end
|
81
82
|
|
82
|
-
|
83
|
+
raise TimeoutException, "Timeout" if Time.now - start_time > default_timeout
|
84
|
+
end
|
83
85
|
end
|
84
|
-
end
|
85
86
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
87
|
+
def report(captcha_id, is_correct)
|
88
|
+
report = is_correct ? "reportgood" : "reportbad"
|
89
|
+
uri = URI("#{base_url}/res.php?key=#{@api_key}&action=#{report}&id=#{captcha_id}")
|
90
|
+
make_request(uri)
|
91
|
+
end
|
91
92
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
93
|
+
def get_balance
|
94
|
+
response = make_res_request({ "action" => "getbalance" }, "getbalance")
|
95
|
+
return response["request"].to_f
|
96
|
+
end
|
96
97
|
|
97
|
-
|
98
|
-
|
99
|
-
|
98
|
+
def normal(params)
|
99
|
+
solve("post", params)
|
100
|
+
end
|
100
101
|
|
101
|
-
|
102
|
-
|
103
|
-
|
102
|
+
def text(params)
|
103
|
+
solve("textcaptcha", params)
|
104
|
+
end
|
104
105
|
|
105
|
-
|
106
|
-
|
107
|
-
|
106
|
+
def recaptcha_v2(params)
|
107
|
+
solve("userrecaptcha", params)
|
108
|
+
end
|
108
109
|
|
109
|
-
|
110
|
-
|
111
|
-
|
110
|
+
def recaptcha_v3(params)
|
111
|
+
solve("userrecaptcha", params)
|
112
|
+
end
|
112
113
|
|
113
|
-
|
114
|
-
|
115
|
-
|
114
|
+
def funcaptcha(params)
|
115
|
+
solve("funcaptcha", params)
|
116
|
+
end
|
116
117
|
|
117
|
-
|
118
|
-
|
119
|
-
|
118
|
+
def geetest(params)
|
119
|
+
solve("geetest", params)
|
120
|
+
end
|
120
121
|
|
121
|
-
|
122
|
-
|
123
|
-
|
122
|
+
def hcaptcha(params)
|
123
|
+
solve("hcaptcha", params)
|
124
|
+
end
|
124
125
|
|
125
|
-
|
126
|
-
|
127
|
-
|
126
|
+
def keycaptcha(params)
|
127
|
+
solve("keycaptcha", params)
|
128
|
+
end
|
128
129
|
|
129
|
-
|
130
|
-
|
131
|
-
|
130
|
+
def capy(params)
|
131
|
+
solve("capy", params)
|
132
|
+
end
|
132
133
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
134
|
+
def grid(params)
|
135
|
+
params["recaptcha"] = 1
|
136
|
+
solve("post", params)
|
137
|
+
end
|
137
138
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
139
|
+
def canvas(params)
|
140
|
+
params["recaptcha"] = 1
|
141
|
+
params["canvas"] = 1
|
142
|
+
solve("post", params)
|
143
|
+
end
|
143
144
|
|
144
|
-
|
145
|
-
|
145
|
+
def coordinates(params)
|
146
|
+
params["coordinatescaptcha"] = 1
|
146
147
|
|
147
|
-
|
148
|
-
|
148
|
+
solve("post", params)
|
149
|
+
end
|
149
150
|
|
150
|
-
|
151
|
-
|
152
|
-
|
151
|
+
def rotate(params)
|
152
|
+
solve("rotatecaptcha", params)
|
153
|
+
end
|
153
154
|
|
154
|
-
|
155
|
-
|
156
|
-
|
155
|
+
def geetest_v4(params)
|
156
|
+
solve("geetest_v4", params)
|
157
|
+
end
|
157
158
|
|
158
|
-
|
159
|
-
|
160
|
-
|
159
|
+
def lemin(params)
|
160
|
+
solve("lemin", params)
|
161
|
+
end
|
161
162
|
|
162
|
-
|
163
|
-
|
164
|
-
|
163
|
+
def turnstile(params)
|
164
|
+
solve("turnstile", params)
|
165
|
+
end
|
165
166
|
|
166
|
-
|
167
|
-
|
168
|
-
|
167
|
+
def amazon_waf(params)
|
168
|
+
solve("amazon_waf", params)
|
169
|
+
end
|
169
170
|
|
170
|
-
|
171
|
-
|
172
|
-
|
171
|
+
def audio(params)
|
172
|
+
audio = params.delete(:audio)
|
173
|
+
audio_content = File.file?(audio) ? File.binread(audio) : audio
|
173
174
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
175
|
+
params = params.merge(
|
176
|
+
"body" => Base64.strict_encode64(audio_content),
|
177
|
+
"lang" => params[:lang]
|
178
|
+
)
|
179
|
+
solve("audio", params)
|
180
|
+
end
|
180
181
|
|
181
|
-
|
182
|
-
|
183
|
-
|
182
|
+
def yandex(params)
|
183
|
+
solve("yandex", params)
|
184
|
+
end
|
184
185
|
|
185
|
-
|
186
|
+
private
|
186
187
|
|
187
|
-
|
188
|
-
|
189
|
-
|
188
|
+
def base_url
|
189
|
+
BASE_URL_FORMAT % @domain
|
190
|
+
end
|
190
191
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
192
|
+
def send_request(params)
|
193
|
+
uri = URI("#{base_url}/in.php")
|
194
|
+
req = Net::HTTP::Post.new(uri)
|
195
|
+
req.content_type = 'application/json'
|
196
|
+
req.body = params.to_json
|
197
|
+
captcha_id = get_captcha_id(make_request(uri, req))
|
198
|
+
end
|
198
199
|
|
199
|
-
|
200
|
-
|
201
|
-
|
200
|
+
def get_params(params)
|
201
|
+
params[:image].nil? ? params : file_params(params)
|
202
|
+
end
|
202
203
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
204
|
+
def file_params(params)
|
205
|
+
image = params.delete(:image)
|
206
|
+
hint_image = params.delete(:hint_image)
|
207
|
+
|
208
|
+
image_content = get_image_content(image)
|
209
|
+
hint_image_content = get_image_content(hint_image) if hint_image
|
210
|
+
result_params = {
|
211
|
+
"method" => "base64",
|
212
|
+
"body" => Base64.strict_encode64(image_content),
|
213
|
+
"filename" => File.basename(image),
|
214
|
+
"ext" => File.extname(image).delete(".")
|
215
|
+
}
|
216
|
+
|
217
|
+
result_params["imginstructions"] = Base64.strict_encode64(hint_image_content) if hint_image_content
|
218
|
+
params.merge(result_params)
|
219
|
+
end
|
219
220
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
221
|
+
def get_image_content(image)
|
222
|
+
return download_image(image) if image.start_with?('http')
|
223
|
+
return File.binread(image) if File.file?(image)
|
224
|
+
image
|
225
|
+
end
|
225
226
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
227
|
+
def download_image(url)
|
228
|
+
response = URI.open(url)
|
229
|
+
if response.status[0] != '200'
|
230
|
+
raise StandardError, "File could not be downloaded from url: #{url}"
|
231
|
+
end
|
232
|
+
response.read
|
230
233
|
end
|
231
|
-
response.read
|
232
|
-
end
|
233
234
|
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
235
|
+
def handle_response(captcha_id)
|
236
|
+
captcha_result = get_result(captcha_id) if @callback.nil?
|
237
|
+
@callback&.call(captcha_id)
|
238
|
+
captcha_result
|
239
|
+
end
|
239
240
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
241
|
+
def get_captcha_id(response)
|
242
|
+
case response
|
243
|
+
when Net::HTTPSuccess
|
244
|
+
response_json = JSON.parse(response.body.strip)
|
245
|
+
if response_json["status"] == 1
|
246
|
+
response_json["request"]
|
247
|
+
else
|
248
|
+
raise ApiException, "API Error: #{response_json["error_text"]}"
|
249
|
+
end
|
246
250
|
else
|
247
|
-
raise
|
251
|
+
raise NetworkException, "Network Error: #{response.code.to_i}"
|
248
252
|
end
|
249
|
-
|
250
|
-
raise
|
253
|
+
rescue JSON::ParserError => e
|
254
|
+
raise "Failed to parse response: #{e.message}"
|
251
255
|
end
|
252
|
-
rescue JSON::ParserError => e
|
253
|
-
raise "Failed to parse response: #{e.message}"
|
254
|
-
end
|
255
256
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
257
|
+
def make_request(uri, req = nil)
|
258
|
+
if req.nil?
|
259
|
+
Net::HTTP.get_response(uri)
|
260
|
+
else
|
261
|
+
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
|
262
|
+
http.request(req)
|
263
|
+
end
|
262
264
|
end
|
263
265
|
end
|
264
|
-
end
|
265
266
|
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
267
|
+
def make_res_request(request, action)
|
268
|
+
uri = URI("#{base_url}/res.php?key=#{@api_key}&action=#{action}&json=1")
|
269
|
+
req = Net::HTTP::Post.new(uri)
|
270
|
+
req.content_type = 'application/json'
|
271
|
+
req.body = request.to_json
|
271
272
|
|
272
|
-
|
273
|
+
response = make_request(uri, req)
|
273
274
|
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
275
|
+
case response
|
276
|
+
when Net::HTTPSuccess
|
277
|
+
return JSON.parse(response.body)
|
278
|
+
else
|
279
|
+
raise Api2Captcha::NetworkException, "Network Error: #{response.code.to_i}"
|
280
|
+
end
|
279
281
|
end
|
280
282
|
end
|
281
283
|
end
|
data/lib/api_2captcha/version.rb
CHANGED
data/lib/api_2captcha.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
3
|
+
require_relative 'api_2captcha/api2captcha_exceptions'
|
4
|
+
require_relative 'api_2captcha/client'
|
5
|
+
require_relative 'api_2captcha/version'
|
4
6
|
|
5
7
|
module Api2Captcha
|
6
|
-
require_relative 'api_2captcha/api2captcha_exceptions'
|
7
8
|
def self.new(*args)
|
8
9
|
Client.new(*args)
|
9
10
|
end
|
10
11
|
end
|
11
12
|
|
12
|
-
require 'api_2captcha/client'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-2captcha
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- 2captcha.com
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-07-03 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Ruby package for easy integration with the API of 2captcha captcha solving
|
14
14
|
service to bypass recaptcha, hcaptcha, funcaptcha, geetest and solve any other captchas.
|
@@ -57,7 +57,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
57
57
|
- !ruby/object:Gem::Version
|
58
58
|
version: '0'
|
59
59
|
requirements: []
|
60
|
-
rubygems_version: 3.
|
60
|
+
rubygems_version: 3.0.1
|
61
61
|
signing_key:
|
62
62
|
specification_version: 4
|
63
63
|
summary: 2Captcha API wrapper for Ruby.
|