deathbycaptcha 5.2.0 → 6.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b7b0ae41ffa4cc961dc9600c23ec9f0e56bf09261fa4766ed2aa1cd686a2a09f
4
- data.tar.gz: 87885c289fce41e9a34696514dc067b62b025a45e89f7728aaf28146beba4111
3
+ metadata.gz: 90fb9bdd5058aa906630d30ddeb9a7cba5300d5c68105928c12fcd5e89eeec63
4
+ data.tar.gz: df094417918661d023db5d2252a546d57dc8d2eb6ef9c9c627b2cde73de54463
5
5
  SHA512:
6
- metadata.gz: 926bfd8b477e4d3888947bfca51521402c0f170c04fb70244b31fc9fa8aea47904f00587ea9f95fe9c9cb62c1c6780164aa59ef1bed19e0ac9e232adf01690a7
7
- data.tar.gz: 72925f985964bf277675ebc86373871f0a3c865eb7996b0eb73bde1900d14d4d8e7b3765d1ced32979c0baae3bed7d762ca8d56de9273ed48e3d42e4452c5251
6
+ metadata.gz: ce58d74f000916cc9084c8f1509c62975eaef9ae5fe6c8193866b8fc2454168437004f83f4dd6f45ae553bca0b67950fc1ff6e378abe33424e91028bf4bf5983
7
+ data.tar.gz: 13b46d8da90a407874bc57dc7a61d4b651e0c98f4151748ec1d8f374b8de73e4707bb93ed3581e1a5fda15dcf46b787e14109007b31505bef69a633ca1049711
data/README.md CHANGED
@@ -1,291 +1,263 @@
1
- Developed by [Infosimples](https://infosimples.com), a brazilian company that
2
- offers [data extraction solutions](https://infosimples.com/en/data-engineering).
3
-
4
- We suggest you to also check [2Captcha.com](http://2captcha.com/?from=1025109)
5
- for a cheaper service. You can find it's gem fully compatible with the
6
- deathbycaptcha gem at https://github.com/infosimples/two_captcha.
7
-
8
- [Contact us](https://infosimples.com/en) if you need enterprise services for
9
- CAPTCHAs solving or Internet automation.
10
-
1
+ > DeathByCaptcha is recommended for solving the most popular CAPTCHA types,
2
+ > such as image to text, reCAPTCHA v2, reCAPTCHA v3, hCaptcha and FunCaptcha.
11
3
 
12
4
  # DeathByCaptcha
13
5
 
14
- DeathByCaptcha is a Ruby API for DeathByCaptcha - http://www.deathbycaptcha.com.
15
-
6
+ DeathByCaptcha is a Ruby API for DeathByCaptcha - http://www.deathbycaptcha.com
16
7
 
17
8
  ## Installation
18
9
 
19
10
  Add this line to your application's Gemfile:
20
11
 
21
12
  ```ruby
22
- gem 'deathbycaptcha', '~> 5.0.0'
13
+ gem 'deathbycaptcha', '~> 6.0.0'
23
14
  ```
24
-
25
15
  And then execute:
26
16
 
27
- $ bundle
17
+ ```bash
18
+ $ bundle
19
+ ````
28
20
 
29
21
  Or install it yourself as:
30
22
 
31
- $ gem install deathbycaptcha
23
+ ```bash
24
+ $ gem install deathbycaptcha
25
+ ````
32
26
 
33
27
  ## Usage
34
28
 
35
- 1. **Create a client**
29
+ ### 1. Create a client
36
30
 
37
- ```ruby
38
- # Create a client (:socket and :http clients are available)
39
- client = DeathByCaptcha.new('myusername', 'mypassword', :http)
40
- ```
31
+ ```ruby
32
+ client = DeathByCaptcha.new('myusername', 'mypassword')
33
+ ```
41
34
 
42
- 2. **Solve a captcha**
35
+ ### 2. Solve a CAPTCHA
43
36
 
44
- There are two methods available: **decode** and **decode!**
45
- * **decode** doesn't raise exceptions.
46
- * **decode!** may raise a *DeathByCaptcha::Error* if something goes wrong.
37
+ There are two types of methods available: `decode_*` and `decode_*!`:
47
38
 
48
- If the solution is not available, an empty captcha object will be returned.
39
+ - `decode_*` does not raise exceptions.
40
+ - `decode_*!` may raise a `DeathByCaptcha::Error` if something goes wrong.
49
41
 
50
- ```ruby
51
- captcha = client.decode!(url: 'http://bit.ly/1xXZcKo')
52
- captcha.text # Solution of the captcha
53
- captcha.id # Numeric ID of the captcha solved by DeathByCaptcha
54
- captcha.is_correct # true if the solution is correct
55
- ```
42
+ If the solution is not available, an empty CAPTCHA object will be returned.
56
43
 
57
- You can also specify *path*, *file*, *raw* and *raw64* when decoding an image.
44
+ ```ruby
45
+ captcha = client.decode_image!(url: 'http://bit.ly/1xXZcKo')
46
+ captcha.text # CAPTCHA solution
47
+ captcha.id # CAPTCHA numeric id
48
+ ```
58
49
 
59
- ```ruby
60
- client.decode!(path: 'path/to/my/captcha/file')
50
+ #### Image CAPTCHA
61
51
 
62
- client.decode!(file: File.open('path/to/my/captcha/file', 'rb'))
52
+ You can specify `url`, `path`, `file`, `raw` and `raw64` when decoding an image.
63
53
 
64
- client.decode!(raw: File.open('path/to/my/captcha/file', 'rb').read)
54
+ ```ruby
55
+ client.decode_image!(url: 'http://bit.ly/1xXZcKo')
56
+ client.decode_image!(path: 'path/to/my/captcha/file')
57
+ client.decode_image!(file: File.open('path/to/my/captcha/file', 'rb'))
58
+ client.decode_image!(raw: File.open('path/to/my/captcha/file', 'rb').read)
59
+ client.decode_image!(raw64: Base64.encode64(File.open('path/to/my/captcha/file', 'rb').read))
60
+ ```
65
61
 
66
- client.decode!(raw64: Base64.encode64(File.open('path/to/my/captcha/file', 'rb').read))
67
- ```
62
+ #### reCAPTCHA v2
68
63
 
69
- > Internally, the gem will always convert any image to raw64 (binary base64
70
- encoded).
64
+ ```ruby
65
+ captcha = client.decode_recaptcha_v2!(
66
+ googlekey: "6Ld2sf4SAAAAAKSgzs0Q13IZhY02Pyo31S2jgOB5",
67
+ pageurl: "https://patrickhlauke.github.io/recaptcha/",
68
+ # proxy: "http://user:password@127.0.0.1:3128", # OPTIONAL
69
+ # proxytype: "HTTP", # OPTIONAL
70
+ )
71
71
 
72
- 3. **Retrieve a previously solved captcha**
72
+ # The response will be a text (token), which you can access with `text` or `token` methods.
73
73
 
74
- ```ruby
75
- captcha = client.captcha('130920620') # with 130920620 as the captcha id
76
- ```
74
+ captcha.text
75
+ "03AOPBWq_RPO2vLzyk0h8gH0cA2X4v3tpYCPZR6Y4yxKy1s3Eo7CHZRQntxrd..."
77
76
 
78
- 4. **Report incorrectly solved captcha for refund**
77
+ captcha.token
78
+ "03AOPBWq_RPO2vLzyk0h8gH0cA2X4v3tpYCPZR6Y4yxKy1s3Eo7CHZRQntxrd..."
79
+ ```
79
80
 
80
- ```ruby
81
- captcha = client.report!('130920620') # with 130920620 as the captcha id
82
- ```
81
+ *Parameters:*
83
82
 
84
- > ***Warning:*** *do not abuse on this method, otherwise you may get banned*
83
+ - `googlekey`: The Google key for the reCAPTCHA.
84
+ - `pageurl`: The URL of the page with the reCAPTCHA challenge.
85
+ - `proxy`: optional parameter. Proxy URL and credentials (if any).
86
+ - `proxytype`: optional parameter. Proxy connection protocol.
85
87
 
86
- 5. **Retrieve your user information (which has the current credit balance)**
88
+ #### reCAPTCHA v3
87
89
 
88
- ```ruby
89
- user = client.user()
90
- user.is_banned # true if the user is banned
91
- user.balance # Credit balance in US cents
92
- user.rate # Captcha rate, i.e. charges for one solved captcha in US cents
93
- user.id # Numeric ID of your account
94
- ```
90
+ ```ruby
91
+ captcha = client.decode_recaptcha_v3!(
92
+ googlekey: "6LdyC2cUAAAAACGuDKpXeDorzUDWXmdqeg-xy696",
93
+ pageurl: "https://recaptcha-demo.appspot.com/recaptcha-v3-request-scores.php",
94
+ action: "examples/v3scores",
95
+ # min_score: 0.3, # OPTIONAL
96
+ # proxy: "http://user:password@127.0.0.1:3128", # OPTIONAL
97
+ # proxytype: "HTTP", # OPTIONAL
98
+ )
95
99
 
96
- 6. **Retrieve DeathByCaptcha server status**
100
+ # The response will be a text (token), which you can access with `text` or `token` methods.
97
101
 
98
- ```ruby
99
- status = client.status()
100
- status.todays_accuracy # Current accuracy of DeathByCaptcha
101
- status.solved_in # Estimated seconds to solve a captcha right now
102
- status.is_service_overloaded # true if DeathByCaptcha is overloaded/unresponsive
103
- ```
102
+ captcha.text
103
+ "03AOPBWq_RPO2vLzyk0h8gH0cA2X4v3tpYCPZR6Y4yxKy1s3Eo7CHZRQntxrd..."
104
104
 
105
- ## New reCAPTCHA
105
+ captcha.token
106
+ "03AOPBWq_RPO2vLzyk0h8gH0cA2X4v3tpYCPZR6Y4yxKy1s3Eo7CHZRQntxrd..."
107
+ ```
106
108
 
107
- > It's currently available only with the :http client.
109
+ *Parameters:*
108
110
 
109
- To solve captchas similar to
110
- [reCAPTCHA v2](https://support.google.com/recaptcha/?hl=en#6262736), you can use
111
- both the DeathByCaptcha's **Coordinates API** or **Image Group API**.
111
+ - `googlekey`: The Google key for the reCAPTCHA.
112
+ - `pageurl`: The URL of the page with the reCAPTCHA challenge.
113
+ - `action`: The action name used by the CAPTCHA.
114
+ - `min_score`: optional parameter. The minimal score needed for the CAPTCHA resolution. Defaults to `0.3`.
115
+ - `proxy`: optional parameter. Proxy URL and credentials (if any).
116
+ - `proxytype`: optional parameter. Proxy connection protocol.
112
117
 
113
- Please, read the oficial documentation at
114
- http://www.deathbycaptcha.com/user/api/newrecaptcha.
118
+ > About the `action` parameter: in order to find out what this is, you need to inspect the JavaScript
119
+ > code of the website looking for a call to the `grecaptcha.execute` function.
120
+ >
121
+ > ```javascript
122
+ > // Example
123
+ > grecaptcha.execute('6Lc2fhwTAAAAAGatXTzFYfvlQMI2T7B6ji8UVV_f', { action: "examples/v3scores" })
124
+ > ````
115
125
 
116
- ### Using the Coordinates API
126
+ #### hCaptcha
117
127
 
118
128
  ```ruby
119
- # Read above all the instructions on how to solve a captcha.
120
- captcha = client.decode!(type: 2, url: 'http://bit.ly/1VCUuzk')
121
- ```
122
-
123
- You should specify arguments with *type = 2* and an image similar to a screenshot of
124
- the captcha. See an example:
125
-
126
- **Captcha (screenshot)**
129
+ captcha = client.decode_h_captcha!(
130
+ sitekey: "56489210-0c02-58c0-00e5-1763b63dc9d4",
131
+ pageurl: "https://www.site.with.hcaptcha/example",
132
+ # proxy: "http://user:password@127.0.0.1:3128", # OPTIONAL
133
+ # proxytype: "HTTP", # OPTIONAL
134
+ )
127
135
 
128
- > the argument is passed as *url*, *path*, *file*, *raw* or *raw64*
136
+ # The response will be a text (token), which you can access with `text` or `token` methods.
129
137
 
130
- ![Example of a captcha based on image clicks](captchas/2.jpg)
138
+ captcha.text
139
+ "P0_eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJwYXNza2V5IjoiNnpWV..."
131
140
 
132
- The response will be an array containing coordinates (x, y) where the human
133
- clicked to solve the captcha. For the captcha above it should look something
134
- like:
141
+ captcha.token
142
+ "P0_eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJwYXNza2V5IjoiNnpWV..."
143
+ ```
135
144
 
136
- ```ruby
137
- # captcha.text
138
- "[[30,143],[241,325]]"
145
+ *Parameters:*
139
146
 
140
- # captcha.coordinates
141
- [[30, 143], [241, 325]]
142
- ```
147
+ - `sitekey`: The site key for the hCatpcha.
148
+ - `pageurl`: The URL of the page with the hCaptcha challenge.
149
+ - `proxy`: optional parameter. Proxy URL and credentials (if any).
150
+ - `proxytype`: optional parameter. Proxy connection protocol.
143
151
 
144
- ### Using the Image Group API
152
+ #### FunCaptcha
145
153
 
146
154
  ```ruby
147
- # Read above all the instructions on how to solve a captcha.
148
- captcha = client.decode!(
149
- type: 3,
150
- url: 'http://bit.ly/1i1CIaB', # single image with the clickable grid
151
- banner: { url: 'http://bit.ly/1JTG4T3' }, # the banner image
152
- banner_text: 'Click all images with bananas' # the banner text
155
+ captcha = client.decode_fun_captcha!(
156
+ publickey: "12345678-0000-1111-2222-123456789012",
157
+ pageurl: "https://www.site.with.funcaptcha/example",
158
+ # proxy: "http://user:password@127.0.0.1:3128", # OPTIONAL
159
+ # proxytype: "HTTP", # OPTIONAL
153
160
  )
154
- ```
155
-
156
- You should specify arguments with *type = 3* and the decomposed captcha as seen in the
157
- example below:
158
-
159
- **Captcha: images grid**
160
-
161
- > the argument is passed as *url*, *path*, *file*, *raw* or *raw64*
162
161
 
163
- ![Example of a grid of a captcha based on image clicks](captchas/3-grid.jpg)
162
+ # The response will be a text (token), which you can access with `text` or `token` methods.
164
163
 
165
- **Captcha: banner**
164
+ captcha.text
165
+ "380633616d817f2b8.2351188603|r=ap-southeast-2|met..."
166
166
 
167
- ![Example of a banner of a captcha based on image clicks](captchas/3-banner.jpg)
167
+ captcha.token
168
+ "380633616d817f2b8.2351188603|r=ap-southeast-2|met..."
169
+ ```
168
170
 
169
- **Captcha: banner text**
171
+ *Parameters:*
170
172
 
171
- > Click all images with bananas
173
+ - `publickey`: The public key for the FunCaptcha.
174
+ - `pageurl`: The URL of the page with the hCaptcha challenge.
175
+ - `proxy`: optional parameter. Proxy URL and credentials (if any).
176
+ - `proxytype`: optional parameter. Proxy connection protocol.
172
177
 
173
- The response will be an array containing the indexes for each image that should
174
- be clicked counting from left to right. For the captcha above it should look
175
- something like:
178
+ ### 3. Retrieve a previously solved CAPTCHA
176
179
 
177
180
  ```ruby
178
- # captcha.text
179
- "[1,9]"
180
-
181
- # captcha.indexes
182
- [1, 9]
181
+ captcha = client.captcha('28624378') # with 28624378 being the CAPTCHA id
183
182
  ```
184
183
 
185
- ## New Recaptcha by Token API
186
-
187
- > It's currently available only with the :http client.
184
+ ### 4. Report an incorrectly solved CAPTCHA for a refund
188
185
 
189
- To solve captchas similar to
190
- [reCAPTCHA v2](https://support.google.com/recaptcha/?hl=en#6262736), you can also use
191
- **Token API**
186
+ ```ruby
187
+ captcha = client.report!('28624378') # with 28624378 being the CAPTCHA id
188
+ ```
192
189
 
193
- Please, read the oficial documentation at
194
- http://deathbycaptcha.com/user/api/newtokenrecaptcha
190
+ > **Warning:** *abusing on this method may get you banned.*
195
191
 
196
- ### Using the Token API
192
+ ### 5. Retrieve your user information and credit balance
197
193
 
198
194
  ```ruby
199
- # Read above all the instructions on how to solve a captcha.
200
- captcha = client.decode!(type: 4, token_params: {
201
- # optional proxy if needed and server verifies
202
- #proxy: "http://127.0.0.1:3128",
203
- #proxytype: "HTTP",
204
- googlekey: "6Ld2sf4SAAAAAKSgzs0Q13IZhY02Pyo31S2jgOB5",
205
- pageurl: "https://patrickhlauke.github.io/recaptcha/"
206
- })
195
+ user = client.user
196
+ user.is_banned # true if the user is banned
197
+ user.balance # Credit balance in USD cents
198
+ user.rate # CAPTCHA rate, i.e. charges for one solved CAPTCHA in USD cents
199
+ user.id # Numeric id of your account
207
200
  ```
208
201
 
209
- You should specify arguments with *type = 4* and an all token params required by DBC API
210
-
211
- The response will be a text (token), which you can access with **text** or **token** method.
202
+ ### 6. Retrieve DeathByCaptcha server status
212
203
 
213
204
  ```ruby
214
- # captcha.text
215
- "03AOPBWq_RPO2vLzyk0h8gH0cA2X4v3tpYCPZR6Y4yxKy1s3Eo7CHZRQntxrd
216
- saD2H0e6S3547xi1FlqJB4rob46J0-wfZMj6YpyVa0WGCfpWzBWcLn7tO_EYs
217
- vEC_3kfLNINWa5LnKrnJTDXTOz-JuCKvEXx0EQqzb0OU4z2np4uyu79lc_Ndv
218
- L0IRFc3Cslu6UFV04CIfqXJBWCE5MY0Ag918r14b43ZdpwHSaVVrUqzCQMCyb
219
- cGq0yxLQf9eSexFiAWmcWLI5nVNA81meTXhQlyCn5bbbI2IMSEErDqceZjf1m
220
- X3M67BhIb4"
221
-
222
- # captcha.token
223
- "03AOPBWq_RPO2vLzyk0h8gH0cA2X4v3tpYCPZR6Y4yxKy1s3Eo7CHZRQntxrd
224
- saD2H0e6S3547xi1FlqJB4rob46J0-wfZMj6YpyVa0WGCfpWzBWcLn7tO_EYs
225
- vEC_3kfLNINWa5LnKrnJTDXTOz-JuCKvEXx0EQqzb0OU4z2np4uyu79lc_Ndv
226
- L0IRFc3Cslu6UFV04CIfqXJBWCE5MY0Ag918r14b43ZdpwHSaVVrUqzCQMCyb
227
- cGq0yxLQf9eSexFiAWmcWLI5nVNA81meTXhQlyCn5bbbI2IMSEErDqceZjf1m
228
- X3M67BhIb4"
205
+ status = client.status
206
+ status.todays_accuracy # Current accuracy of DeathByCaptcha
207
+ status.solved_in # Estimated seconds to solve a CAPTCHA right now
208
+ status.is_service_overloaded # true if DeathByCaptcha is overloaded/unresponsive
229
209
  ```
230
210
 
231
- > Those captchas sometimes took more than 60 seconds to solve
232
- > So consider increasing the client's *timeout*
233
-
234
211
  ## Notes
235
212
 
236
- #### Thread-safety
213
+ ### Thread-safety
237
214
 
238
215
  The API is thread-safe, which means it is perfectly fine to share a client
239
216
  instance between multiple threads.
240
217
 
241
- #### HTTP and Socket clients
218
+ ### HTTP and Socket clients
219
+
220
+ The API supports HTTP (recommended) and socket-based connections.
242
221
 
243
- The API supports HTTP and socket-based connections, with the latter being
244
- recommended for having faster responses and overall better performance. The two
245
- clients have the same methods/interface.
222
+ ```ruby
223
+ # HTTP-based connection.
224
+ client = DeathByCaptcha.new('myusername', 'mypassword')
225
+ # or
226
+ client = DeathByCaptcha.new('myusername', 'mypassword', :http)
227
+
228
+ # Socket-based connection.
229
+ client = DeathByCaptcha.new('myusername', 'mypassword', :socket)
230
+ ```
246
231
 
247
232
  When using the socket client, make sure that outgoing TCP traffic to
248
- **api.dbcapi.me** to the ports in range **8123-8130** is not blocked by your
233
+ `api.dbcapi.me` to the ports in range `8123-8130` is not blocked by your
249
234
  firewall.
250
235
 
251
- > We are currently suggesting developers to use HTTP connection because Socket
252
- > seems to be unstable with older Ruby versions. While we are investigating,
253
- > consider using only HTTP connection.
236
+ > We strongly recommend using the HTTP client (default) because only image
237
+ > CAPTCHAs (`decode_image!`) are supported by the socket client in this gem.
238
+ > Other CAPTCHA types, such as reCAPTCHA v2, reCAPTCHA v3, hCaptcha and FunCaptcha
239
+ > are supported by the HTTP client only.
254
240
 
255
- #### Ruby dependencies
241
+ ### Ruby dependencies
256
242
 
257
- DeathByCaptcha >= 5.0.0 don't require specific dependencies. That saves you
243
+ DeathByCaptcha >= 5.0.0 does not require specific dependencies. That saves you
258
244
  memory and avoid conflicts with other gems.
259
245
 
260
- #### Input image format
246
+ ### Input image format
261
247
 
262
- Any format you use in the decode method (url, file, path, raw, raw64) will
263
- always be converted to a raw64, which is a binary base64 encoded string. So, if
264
- you already have this format available on your side, there's no need to do
265
- convertions before calling the API.
248
+ Any format you use in the `decode_image!` method (`url`, `file`, `path`, `raw` or `raw64`) will
249
+ always be converted to a `raw64`, which is a base64-encoded binary string. So, if
250
+ you already have this format on your end, there is no need for convertions before
251
+ calling the API.
266
252
 
267
253
  > Our recomendation is to never convert your image format, unless needed. Let
268
254
  > the gem convert internally. It may save you resources (CPU, memory and IO).
269
255
 
270
- #### Versioning
271
-
272
- We no longer follow the versioninig system of the official clients of
273
- DeathByCaptcha. We have bumped to version 5.0.0 and will use
274
- [Semantic Versioning](http://semver.org/) from now on.
275
-
276
- #### Upgrade from 4.x to 5.x
277
-
278
- Any 5.x version is incompatible with any 4.x version. Please, review your code
279
- before upgrading.
280
-
281
- #### Ruby versions
282
-
283
- This gem has been tested on the following versions of Ruby:
256
+ ### Versioning
284
257
 
285
- * MRI 2.2.0
286
- * MRI 2.1.5
287
- * MRI 2.0.0
288
- * MRI 1.9.3
258
+ We no longer follow the versioning system of the official clients of
259
+ DeathByCaptcha. From `5.0.0` onwards, we will use
260
+ [Semantic Versioning](http://semver.org/).
289
261
 
290
262
  ## Contributing
291
263
 
@@ -303,4 +275,4 @@ https://github.com/infosimples/deathbycaptcha/graphs/contributors
303
275
 
304
276
  # License
305
277
 
306
- MIT License. Copyright (C) 2011-2015 Infosimples. https://infosimples.com/
278
+ MIT License. Copyright (C) 2011-2022 Infosimples. https://infosimples.com/
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
23
23
  spec.require_paths = ["lib"]
24
24
 
25
- spec.add_development_dependency "bundler", "~> 1.7"
26
- spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "bundler", "~> 2.2.33"
26
+ spec.add_development_dependency "rake", ">= 12.3.3"
27
27
  spec.add_development_dependency "rspec", "~> 3.1"
28
28
  end
@@ -55,20 +55,36 @@ module DeathByCaptcha
55
55
  payload[:captchafile] = "base64:#{options[:raw64]}"
56
56
  payload[:type] = options[:type] if options[:type].to_i > 0
57
57
 
58
- if options[:type].to_i == 3
58
+ case options[:type].to_i
59
+ when 3
59
60
  banner64 = load_captcha(options[:banner])
60
61
  raise DeathByCaptcha::InvalidCaptcha if banner64.to_s.empty?
61
62
 
62
- payload[:banner] = "base64:#{banner64}"
63
- payload[:banner_text] = options[:banner_text].to_s
63
+ payload = {
64
+ banner: "base64:#{banner64}",
65
+ banner_text: options[:banner_text].to_s,
66
+ }
64
67
 
65
- elsif [4, 5].include? options[:type].to_i
68
+ when 4, 5
66
69
  payload = {
67
- type: options[:type].to_i,
70
+ type: options[:type].to_i,
68
71
  token_params: options[:token_params].to_json,
69
72
  }
73
+
74
+ when 6
75
+ payload = {
76
+ type: options[:type].to_i,
77
+ funcaptcha_params: options[:funcaptcha_params].to_json,
78
+ }
79
+
80
+ when 7
81
+ payload = {
82
+ type: options[:type].to_i,
83
+ hcaptcha_params: options[:hcaptcha_params].to_json,
84
+ }
70
85
  end
71
86
 
87
+ payload.merge!(vendor_id: 5)
72
88
  response = perform('captcha', :post_multipart, payload)
73
89
  DeathByCaptcha::Captcha.new(response)
74
90
  end
@@ -99,6 +115,7 @@ module DeathByCaptcha
99
115
  boundary, body = prepare_multipart_data(payload)
100
116
  req.content_type = "multipart/form-data; boundary=#{boundary}"
101
117
  req.body = body
118
+
102
119
  else
103
120
  uri = URI("http://#{self.hostname}/api/#{action}?#{URI.encode_www_form(payload)}")
104
121
  req = Net::HTTP::Get.new(uri.request_uri, headers)
@@ -73,10 +73,11 @@ module DeathByCaptcha
73
73
  #
74
74
  def perform(action, payload = {})
75
75
  payload.merge!(
76
- cmd: action,
77
- version: DeathByCaptcha::API_VERSION,
78
- username: self.username,
79
- password: self.password
76
+ cmd: action,
77
+ version: DeathByCaptcha::API_VERSION,
78
+ username: self.username,
79
+ password: self.password,
80
+ vendor_id: 5,
80
81
  )
81
82
 
82
83
  socket = create_socket()
@@ -25,7 +25,7 @@ module DeathByCaptcha
25
25
  #
26
26
  # @return [DeathByCaptcha::Client] A Socket or HTTP Client instance.
27
27
  #
28
- def self.create(username, password, connection = :socket, options = {})
28
+ def self.create(username, password, connection = :http, options = {})
29
29
  case connection
30
30
  when :socket
31
31
  DeathByCaptcha::Client::Socket.new(username, password, options)
@@ -75,20 +75,22 @@ module DeathByCaptcha
75
75
  # Decode the text from an image (i.e. solve a captcha).
76
76
  #
77
77
  # @param [Hash] options Options hash.
78
- # @option options [String] :url URL of the image to be decoded.
79
- # @option options [String] :path File path of the image to be decoded.
80
- # @option options [File] :file File instance with image to be decoded.
81
- # @option options [String] :raw Binary content of the image to be decoded.
82
- # @option options [String] :raw64 Binary content encoded in base64 of the image to be decoded.
78
+ # @option options [String] :url URL of the image to be decoded.
79
+ # @option options [String] :path File path of the image to be decoded.
80
+ # @option options [File] :file File instance with image to be decoded.
81
+ # @option options [String] :raw Binary content of the image to be decoded.
82
+ # @option options [String] :raw64 Binary content encoded in base64 of the image to be decoded.
83
+ # @option options [String] :type CAPTCHA type.
84
+ # @option options [String] :token_params Parameters for token APIs (reCAPTCHA / hCaptcha).
83
85
  #
84
86
  # @return [DeathByCaptcha::Captcha] The captcha (with solution if an error is not raised).
85
87
  #
86
88
  def decode!(options = {})
87
89
  started_at = Time.now
88
90
 
89
- # don't load image data for Token API v2 & v3
91
+ # Do not load image data for CAPTCHA types other than "image".
90
92
  raw64 = nil
91
- unless [4, 5].include? options[:type]
93
+ if ![4, 5, 6, 7].include?(options[:type])
92
94
  raw64 = load_captcha(options)
93
95
  raise DeathByCaptcha::InvalidCaptcha if raw64.to_s.empty?
94
96
  end
@@ -106,6 +108,74 @@ module DeathByCaptcha
106
108
  decoded_captcha
107
109
  end
108
110
 
111
+ def decode_image(options = {})
112
+ decode!(options)
113
+ rescue DeathByCaptcha::Error
114
+ DeathByCaptcha::Captcha.new
115
+ end
116
+
117
+ def decode_image!(options = {})
118
+ decode!(options.slice(:url, :path, :file, :raw, :raw64))
119
+ end
120
+
121
+ def decode_recaptcha_v2(options = {})
122
+ decode_recaptcha_v2!(options)
123
+ rescue DeathByCaptcha::Error
124
+ DeathByCaptcha::Captcha.new
125
+ end
126
+
127
+ def decode_recaptcha_v2!(options = {})
128
+ options = {
129
+ type: 4, # reCAPTCHA v2
130
+ token_params: options.slice(:googlekey, :pageurl, :proxy, :proxytype),
131
+ }
132
+ decode!(options)
133
+ end
134
+
135
+ def decode_recaptcha_v3(options = {})
136
+ decode_recaptcha_v3!(options)
137
+ rescue DeathByCaptcha::Error
138
+ DeathByCaptcha::Captcha.new
139
+ end
140
+
141
+ def decode_recaptcha_v3!(options = {})
142
+ options = {
143
+ type: 5, # reCAPTCHA v3
144
+ token_params: {
145
+ min_score: 0.3,
146
+ }.merge(options.slice(:googlekey, :pageurl, :action, :min_score, :proxy, :proxytype)),
147
+ }
148
+ decode!(options)
149
+ end
150
+
151
+ def decode_h_captcha(options = {})
152
+ decode_recaptcha_h_captcha!(options)
153
+ rescue DeathByCaptcha::Error
154
+ DeathByCaptcha::Captcha.new
155
+ end
156
+
157
+ def decode_h_captcha!(options = {})
158
+ options = {
159
+ type: 7, # hCaptcha
160
+ hcaptcha_params: options.slice(:sitekey, :pageurl, :proxy, :proxytype),
161
+ }
162
+ decode!(options)
163
+ end
164
+
165
+ def decode_fun_captcha(options = {})
166
+ decode_fun_captcha!(options)
167
+ rescue DeathByCaptcha::Error
168
+ DeathByCaptcha::Captcha.new
169
+ end
170
+
171
+ def decode_fun_captcha!(options = {})
172
+ options = {
173
+ type: 6, # FunCaptcha
174
+ funcaptcha_params: options.slice(:publickey, :pageurl, :proxy, :proxytype),
175
+ }
176
+ decode!(options)
177
+ end
178
+
109
179
  # Retrieve information from an uploaded captcha.
110
180
  #
111
181
  # @param [Integer] captcha_id Numeric ID of the captcha.
@@ -1,4 +1,4 @@
1
1
  module DeathByCaptcha
2
- VERSION = "5.2.0"
2
+ VERSION = "6.0.0"
3
3
  API_VERSION = "DBC/Ruby v#{VERSION}"
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deathbycaptcha
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.2.0
4
+ version: 6.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rafael Barbolo, Rafael Ivan Garcia
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-28 00:00:00.000000000 Z
11
+ date: 2022-09-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.7'
19
+ version: 2.2.33
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.7'
26
+ version: 2.2.33
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: 12.3.3
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: 12.3.3
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement