two_captcha 1.3.2 → 1.7.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.
- checksums.yaml +5 -5
- data/Changelog.md +9 -0
- data/README.md +86 -9
- data/lib/two_captcha/client.rb +97 -24
- data/lib/two_captcha/errors.rb +6 -0
- data/lib/two_captcha/version.rb +1 -1
- data/spec/lib/client_spec.rb +18 -0
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9d9f28e64ed32b2c3bb8973f14bea2dbb15828550806d0306e6bdbdf07815562
|
4
|
+
data.tar.gz: eaa46657370a298929c7e5f49104abb3f696a74cddeddb8f1052a1f3c2140b8d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc567f2ecf5c0771e1b1ca7cade9c44a33abe2a224256132d2d8326798b998f5b8750fdbb489995c320a705f68ed7d9bb685450c87174c71389d987eb06258a0
|
7
|
+
data.tar.gz: dac73380663bc6471b233db9b30a6d2be296b27fa92131a3beaf54f7a155d503658c7ad53accf1e500eb50704413bd9af931793f6ccc200251dce157f5dbe1f3
|
data/Changelog.md
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# TwoCaptcha Changes
|
2
|
+
|
3
|
+
### 1.4.0
|
4
|
+
|
5
|
+
* **breaking changes:**
|
6
|
+
* The method "decode_recaptcha_v2" now always return a TwoCaptcha::Captcha
|
7
|
+
object. It was returning a string when successful.
|
8
|
+
* enhancements:
|
9
|
+
* Add tests to solve RecaptchaV2 with the preferred method.
|
data/README.md
CHANGED
@@ -66,10 +66,13 @@ Or install it yourself as:
|
|
66
66
|
captcha = client.captcha('130920620') # with 130920620 as the captcha id
|
67
67
|
```
|
68
68
|
|
69
|
-
4. **Report incorrectly
|
69
|
+
4. **Report incorrectly (for refund) or correctly (useful for reCAPTCHA v3) solved captcha**
|
70
70
|
|
71
71
|
```ruby
|
72
|
-
client.report!('130920620') # with 130920620 as the captcha id
|
72
|
+
client.report!('130920620', 'reportbad') # with 130920620 as the captcha id
|
73
|
+
# return true if successfully reported
|
74
|
+
|
75
|
+
client.report!('256892751', 'reportgood') # with 256892751 as the captcha id
|
73
76
|
# return true if successfully reported
|
74
77
|
```
|
75
78
|
|
@@ -96,17 +99,18 @@ Or install it yourself as:
|
|
96
99
|
# return an XML string with the current service load.
|
97
100
|
```
|
98
101
|
|
99
|
-
##
|
102
|
+
## reCAPTCHA v2 (e.g. "No CAPTCHA reCAPTCHA")
|
100
103
|
|
101
104
|
There are two ways of solving captchas similar to
|
102
105
|
[reCAPTCHA v2](https://support.google.com/recaptcha/?hl=en#6262736).
|
103
106
|
|
104
107
|
### (Prefered) Sending the `googlekey` and `pageurl` parameters
|
105
108
|
|
106
|
-
This method requires no browser emulation. You can send two parameters that
|
109
|
+
This method requires no browser emulation. You can send two parameters that
|
110
|
+
identify the website in which the captcha is found.
|
107
111
|
|
108
|
-
Please read the oficial documentation
|
109
|
-
more information.
|
112
|
+
Please read the [oficial documentation](https://2captcha.com/newapi-recaptcha-en)
|
113
|
+
for more information.
|
110
114
|
|
111
115
|
```ruby
|
112
116
|
options = {
|
@@ -114,13 +118,16 @@ more information.
|
|
114
118
|
pageurl: 'http://example.com/example=1'
|
115
119
|
}
|
116
120
|
|
117
|
-
client.decode_recaptcha_v2(options)
|
121
|
+
captcha = client.decode_recaptcha_v2(options)
|
122
|
+
captcha.text # Solution of the captcha
|
123
|
+
captcha.id # Numeric ID of the captcha solved by TwoCaptcha
|
118
124
|
```
|
119
125
|
|
120
|
-
The
|
126
|
+
The solution (`captcha.text`) will be a code that validates the form, like the
|
127
|
+
following:
|
121
128
|
|
122
129
|
```ruby
|
123
|
-
"
|
130
|
+
"1JJHJ_VuuHAqJKxcaasbTsqw-L1Sm4gD57PTeaEr9-MaETG1vfu2H5zlcwkjsRoZoHxx6V9yUDw8Ig-hYD8kakmSnnjNQd50w_Y_tI3aDLp-s_7ZmhH6pcaoWWsid5hdtMXyvrP9DscDuCLBf7etLle8caPWSaYCpAq9DOTtj5NpSg6-OeCJdGdkjsakFUMeGeqmje87wSajcjmdjl_w4XZBY2zy8fUH6XoAGZ6AeCTulIljBQDObQynKDd-rutPvKNxZasDk-LbhTfw508g1lu9io6jnvm3kbAdnkfZ0x0PkGiUMHU7hnuoW6bXo2Yn_Zt5tDWL7N7wFtY6B0k7cTy73f8er508zReOuoyz2NqL8smDCmcJu05ajkPGt20qzpURMwHaw"
|
124
131
|
```
|
125
132
|
|
126
133
|
### Sending the challenge image
|
@@ -161,6 +168,76 @@ The response will be a simple text:
|
|
161
168
|
'61267'
|
162
169
|
```
|
163
170
|
|
171
|
+
## reCAPTCHA v3
|
172
|
+
|
173
|
+
This method requires no browser emulation. You can send four parameters that
|
174
|
+
identify the website in which the CAPTCHA is found and the minimum score
|
175
|
+
(0.3, 0.5 or 0.7) you desire.
|
176
|
+
|
177
|
+
**It's strongly recommended to use a minimum score of 0.3 as higher scores are extremely rare.**
|
178
|
+
|
179
|
+
Please read the [oficial documentation](https://2captcha.com/2captcha-api#solving_recaptchav3)
|
180
|
+
for more information.
|
181
|
+
|
182
|
+
```ruby
|
183
|
+
options = {
|
184
|
+
googlekey: 'xyz',
|
185
|
+
pageurl: 'http://example.com/example=1',
|
186
|
+
action: 'verify',
|
187
|
+
min_score: 0.3
|
188
|
+
}
|
189
|
+
|
190
|
+
captcha = client.decode_recaptcha_v3(options)
|
191
|
+
captcha.text # Solution of the captcha
|
192
|
+
captcha.id # Numeric ID of the captcha solved by TwoCaptcha
|
193
|
+
```
|
194
|
+
|
195
|
+
The solution (`captcha.text`) will be a code that validates the form, like the
|
196
|
+
following:
|
197
|
+
|
198
|
+
```ruby
|
199
|
+
"1JJHJ_VuuHAqJKxcaasbTsqw-L1Sm4gD57PTeaEr9-MaETG1vfu2H5zlcwkjsRoZoHxx6V9yUDw8Ig-hYD8kakmSnnjNQd50w_Y_tI3aDLp-s_7ZmhH6pcaoWWsid5hdtMXyvrP9DscDuCLBf7etLle8caPWSaYCpAq9DOTtj5NpSg6-OeCJdGdkjsakFUMeGeqmje87wSajcjmdjl_w4XZBY2zy8fUH6XoAGZ6AeCTulIljBQDObQynKDd-rutPvKNxZasDk-LbhTfw508g1lu9io6jnvm3kbAdnkfZ0x0PkGiUMHU7hnuoW6bXo2Yn_Zt5tDWL7N7wFtY6B0k7cTy73f8er508zReOuoyz2NqL8smDCmcJu05ajkPGt20qzpURMwHaw"
|
200
|
+
```
|
201
|
+
|
202
|
+
## hCaptcha
|
203
|
+
|
204
|
+
This method allows you to solve hCaptcha.
|
205
|
+
|
206
|
+
There are two methods available:
|
207
|
+
|
208
|
+
- `decode_hcaptcha`: solves hCaptcha CAPTCHAs. It doesn't raise exceptions.
|
209
|
+
- `decode_hcaptcha!`: solves hCaptcha CAPTCHAs. It may raise an error if something goes wrong.
|
210
|
+
|
211
|
+
**Send the `sitekey` and `pageurl` parameters**
|
212
|
+
|
213
|
+
This method requires no browser emulation. You can send two parameters that
|
214
|
+
identify the website in which the CAPTCHA is found.
|
215
|
+
|
216
|
+
```ruby
|
217
|
+
options = {
|
218
|
+
sitekey: 'xyz',
|
219
|
+
pageurl: 'http://example.com/example=1'
|
220
|
+
}
|
221
|
+
|
222
|
+
captcha = client.decode_hcaptcha!(options)
|
223
|
+
captcha.text # Solution of the captcha
|
224
|
+
```
|
225
|
+
|
226
|
+
## Using proxy or other custom options
|
227
|
+
|
228
|
+
You are allowed to use custom options like `proxy`, `proxytype` or `userAgent` whenever the 2Captcha API supports it. Example:
|
229
|
+
|
230
|
+
```ruby
|
231
|
+
options = {
|
232
|
+
sitekey: 'xyz',
|
233
|
+
pageurl: 'http://example.com/example=1',
|
234
|
+
proxy: 'login:password@123.123.123.123:3128',
|
235
|
+
userAgent: 'user agent'
|
236
|
+
}
|
237
|
+
|
238
|
+
captcha = client.decode_hcaptcha!(options)
|
239
|
+
```
|
240
|
+
|
164
241
|
## Notes
|
165
242
|
|
166
243
|
#### Thread-safety
|
data/lib/two_captcha/client.rb
CHANGED
@@ -18,9 +18,9 @@ module TwoCaptcha
|
|
18
18
|
# @return [TwoCaptcha::Client] A Client instance.
|
19
19
|
#
|
20
20
|
def initialize(key, options = {})
|
21
|
-
self.key
|
22
|
-
self.timeout
|
23
|
-
self.polling
|
21
|
+
self.key = key
|
22
|
+
self.timeout = options[:timeout] || 60
|
23
|
+
self.polling = options[:polling] || 5
|
24
24
|
end
|
25
25
|
|
26
26
|
# Decode the text from an image (i.e. solve a captcha).
|
@@ -105,30 +105,102 @@ module TwoCaptcha
|
|
105
105
|
|
106
106
|
fail(TwoCaptcha::GoogleKey) if options[:googlekey].empty?
|
107
107
|
|
108
|
-
|
109
|
-
|
110
|
-
googlekey: options[:googlekey],
|
111
|
-
pageurl: options[:pageurl]
|
112
|
-
}
|
108
|
+
upload_options = { method: 'userrecaptcha' }.merge(options)
|
109
|
+
decoded_captcha = upload(upload_options)
|
113
110
|
|
114
|
-
|
115
|
-
|
111
|
+
# pool untill the answer is ready
|
112
|
+
while decoded_captcha.text.to_s.empty?
|
113
|
+
sleep([polling, 10].max) # sleep at least 10 seconds
|
114
|
+
decoded_captcha = captcha(decoded_captcha.id)
|
115
|
+
fail TwoCaptcha::Timeout if (Time.now - started_at) > timeout
|
116
|
+
end
|
117
|
+
|
118
|
+
decoded_captcha
|
119
|
+
end
|
120
|
+
|
121
|
+
#
|
122
|
+
# Solve reCAPTCHA v3.
|
123
|
+
#
|
124
|
+
# @param [Hash] options Options hash. Check docs for the method decode!.
|
125
|
+
#
|
126
|
+
# @return [TwoCaptcha::Captcha] The solution of the given captcha.
|
127
|
+
#
|
128
|
+
def decode_recaptcha_v3(options = {})
|
129
|
+
decode_recaptcha_v3!(options)
|
130
|
+
rescue TwoCaptcha::Error => ex
|
131
|
+
TwoCaptcha::Captcha.new
|
132
|
+
end
|
133
|
+
|
134
|
+
#
|
135
|
+
# Solve reCAPTCHA v3.
|
136
|
+
#
|
137
|
+
# @param [Hash] options Options hash.
|
138
|
+
# @option options [String] :googlekey The open key of the site in which recaptcha is installed.
|
139
|
+
# @option options [String] :pageurl The URL of the page where the recaptcha is encountered.
|
140
|
+
# @option options [String] :action The action paramenter present on the page that uses recaptcha.
|
141
|
+
# @option options [String] :min_score The minimum score necessary to pass the challenge.
|
142
|
+
#
|
143
|
+
# @return [TwoCaptcha::Captcha] The solution of the given captcha.
|
144
|
+
#
|
145
|
+
def decode_recaptcha_v3!(options = {})
|
146
|
+
started_at = Time.now
|
116
147
|
|
117
|
-
|
118
|
-
action: 'get',
|
119
|
-
json: '1',
|
120
|
-
id: captcha_id
|
121
|
-
}
|
148
|
+
fail(TwoCaptcha::GoogleKey) if options[:googlekey].empty?
|
122
149
|
|
123
|
-
|
150
|
+
upload_options = {
|
151
|
+
method: 'userrecaptcha',
|
152
|
+
version: 'v3',
|
153
|
+
}.merge(options)
|
154
|
+
decoded_captcha = upload(upload_options)
|
124
155
|
|
125
|
-
|
126
|
-
|
127
|
-
|
156
|
+
# pool untill the answer is ready
|
157
|
+
while decoded_captcha.text.to_s.empty?
|
158
|
+
sleep([polling, 10].max) # sleep at least 10 seconds
|
159
|
+
decoded_captcha = captcha(decoded_captcha.id)
|
128
160
|
fail TwoCaptcha::Timeout if (Time.now - started_at) > timeout
|
129
161
|
end
|
130
162
|
|
131
|
-
|
163
|
+
decoded_captcha
|
164
|
+
end
|
165
|
+
|
166
|
+
#
|
167
|
+
# Solve hCaptcha.
|
168
|
+
#
|
169
|
+
# @param [Hash] options Options hash. Check docs for the method decode_hcaptcha!.
|
170
|
+
#
|
171
|
+
# @return [TwoCaptcha::Captcha] The solution of the given captcha.
|
172
|
+
#
|
173
|
+
def decode_hcaptcha(options = {})
|
174
|
+
decode_hcaptcha!(options)
|
175
|
+
rescue TwoCaptcha::Error => ex
|
176
|
+
TwoCaptcha::Captcha.new
|
177
|
+
end
|
178
|
+
|
179
|
+
#
|
180
|
+
# Solve hCaptcha.
|
181
|
+
#
|
182
|
+
# @param [Hash] options Options hash.
|
183
|
+
# @option options [String] :sitekey The key of the site in which hCaptcha is installed.
|
184
|
+
# @option options [String] :pageurl The URL of the page where the recaptcha is encountered.
|
185
|
+
#
|
186
|
+
# @return [TwoCaptcha::Captcha] The solution of the given captcha.
|
187
|
+
#
|
188
|
+
def decode_hcaptcha!(options = {})
|
189
|
+
started_at = Time.now
|
190
|
+
|
191
|
+
fail(TwoCaptcha::SiteKey) if options[:sitekey].empty?
|
192
|
+
|
193
|
+
upload_options = { method: 'hcaptcha' }.merge(options)
|
194
|
+
decoded_captcha = upload(upload_options)
|
195
|
+
|
196
|
+
# pool untill the answer is ready
|
197
|
+
while decoded_captcha.text.to_s.empty?
|
198
|
+
sleep([polling, 10].max) # sleep at least 10 seconds
|
199
|
+
decoded_captcha = captcha(decoded_captcha.id)
|
200
|
+
fail TwoCaptcha::Timeout if (Time.now - started_at) > timeout
|
201
|
+
end
|
202
|
+
|
203
|
+
decoded_captcha
|
132
204
|
end
|
133
205
|
|
134
206
|
# Upload a captcha to 2Captcha.
|
@@ -139,8 +211,8 @@ module TwoCaptcha
|
|
139
211
|
#
|
140
212
|
def upload(options = {})
|
141
213
|
args = {}
|
142
|
-
args[:body] = options[:raw64]
|
143
|
-
args[:method] = 'base64'
|
214
|
+
args[:body] = options[:raw64] if options[:raw64]
|
215
|
+
args[:method] = options[:method] || 'base64'
|
144
216
|
args.merge!(options)
|
145
217
|
response = request('in', :multipart, args)
|
146
218
|
|
@@ -176,11 +248,12 @@ module TwoCaptcha
|
|
176
248
|
# Report incorrectly solved captcha for refund.
|
177
249
|
#
|
178
250
|
# @param [Integer] id Numeric ID of the captcha.
|
251
|
+
# @param [Integer] action 'reportbad' (default) or 'reportgood'.
|
179
252
|
#
|
180
253
|
# @return [Boolean] true if correctly reported
|
181
254
|
#
|
182
|
-
def report!(captcha_id)
|
183
|
-
response = request('res', :get, action:
|
255
|
+
def report!(captcha_id, action = 'reportbad')
|
256
|
+
response = request('res', :get, action: action, id: captcha_id)
|
184
257
|
response == 'OK_REPORT_RECORDED'
|
185
258
|
end
|
186
259
|
|
data/lib/two_captcha/errors.rb
CHANGED
@@ -26,6 +26,12 @@ module TwoCaptcha
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
+
class SiteKey < Error
|
30
|
+
def initialize
|
31
|
+
super('Missing sitekey parameter')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
29
35
|
class WrongUserKey < Error
|
30
36
|
def initialize
|
31
37
|
super('Wrong “key” parameter format, it should contain 32 symbols')
|
data/lib/two_captcha/version.rb
CHANGED
data/spec/lib/client_spec.rb
CHANGED
@@ -92,4 +92,22 @@ describe TwoCaptcha::Client do
|
|
92
92
|
it { expect(@captcha.id).to match(/[0-9]{9}/) }
|
93
93
|
end
|
94
94
|
end
|
95
|
+
|
96
|
+
context 'image reCAPTCHA v2' do
|
97
|
+
before(:all) { @client = TwoCaptcha.new(key) }
|
98
|
+
|
99
|
+
describe '#decode_recaptcha_v2!' do
|
100
|
+
before(:all) do
|
101
|
+
options = {
|
102
|
+
googlekey: '6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-',
|
103
|
+
pageurl: 'https://www.google.com/recaptcha/api2/demo'
|
104
|
+
}
|
105
|
+
@captcha = @client.decode_recaptcha_v2!(options)
|
106
|
+
end
|
107
|
+
|
108
|
+
it { expect(@captcha).to be_a(TwoCaptcha::Captcha) }
|
109
|
+
it { expect(@captcha.text.size).to be > 50 } # not perfect, I know
|
110
|
+
it { expect(@captcha.id).to match(/[0-9]{9}/) }
|
111
|
+
end
|
112
|
+
end
|
95
113
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: two_captcha
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rafael Barbolo
|
8
8
|
- Rafael Ivan Garcia
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-11-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -64,6 +64,7 @@ files:
|
|
64
64
|
- ".rspec"
|
65
65
|
- ".travis.yml"
|
66
66
|
- CODE_OF_CONDUCT.md
|
67
|
+
- Changelog.md
|
67
68
|
- Gemfile
|
68
69
|
- LICENSE.txt
|
69
70
|
- README.md
|
@@ -87,7 +88,7 @@ homepage: https://github.com/infosimples/two_captcha
|
|
87
88
|
licenses:
|
88
89
|
- MIT
|
89
90
|
metadata: {}
|
90
|
-
post_install_message:
|
91
|
+
post_install_message:
|
91
92
|
rdoc_options: []
|
92
93
|
require_paths:
|
93
94
|
- lib
|
@@ -102,9 +103,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
102
103
|
- !ruby/object:Gem::Version
|
103
104
|
version: '0'
|
104
105
|
requirements: []
|
105
|
-
|
106
|
-
|
107
|
-
signing_key:
|
106
|
+
rubygems_version: 3.1.4
|
107
|
+
signing_key:
|
108
108
|
specification_version: 4
|
109
109
|
summary: Ruby API for 2Captcha (Captcha Solver as a Service)
|
110
110
|
test_files:
|