├── LICENSE
├── README.md
├── api2captcha.go
├── examples
├── AmazonWAFExample.go
├── AtbCAPTCHAExample.go
├── AudioExample.go
├── CanvasExample.go
├── CapyExample.go
├── CloudflareTurnstileExample.go
├── CoordinatesExample.go
├── CutCaptchaExample.go
├── CyberSiARAExample.go
├── DataDomeExample.go
├── FriendlyCaptchaExample.go
├── FriendlyExample.go
├── FunCaptchaExample.go
├── GeeTestExample.go
├── GeeTestV4Example.go
├── GridExample.go
├── KeyCaptchaExample.go
├── LeminExample.go
├── MTCaptchaExample.go
├── NormalExample.go
├── ReCaptchaExample.go
├── RotateExample.go
├── TencentExample.go
├── TextExample.go
├── YandexExample.go
├── assets
│ ├── audio-en.mp3
│ ├── canvas.jpg
│ ├── grid.jpg
│ ├── normal.jpg
│ └── rotate.jpg
└── internal
│ └── Helper.go
└── go.mod
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 2captcha
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.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | # Golang Module for 2Captcha API
11 | The easiest way to quickly integrate [2Captcha] into your code to automate solving of any type of captcha.
12 | Examples of API requests for different captcha types are available on the [Golang captcha solver](https://2captcha.com/lang/go) page.
13 | - [Golang Module for 2Captcha API](#golang-module-for-2captcha-api)
14 | - [Installation](#installation)
15 | - [Configuration](#configuration)
16 | - [Client instance options](#client-instance-options)
17 | - [Solve captcha](#solve-captcha)
18 | - [Captcha options](#captcha-options)
19 | - [Basic example](#basic-example)
20 | - [Normal Captcha](#normal-captcha)
21 | - [Text Captcha](#text-captcha)
22 | - [reCAPTCHA v2](#recaptcha-v2)
23 | - [reCAPTCHA v3](#recaptcha-v3)
24 | - [reCAPTCHA Enterprise](#recaptcha-enterprise)
25 | - [FunCaptcha](#funcaptcha)
26 | - [GeeTest](#geetest)
27 | - [GeeTest V4](#geetest-v4)
28 | - [KeyCaptcha](#keycaptcha)
29 | - [Capy](#capy)
30 | - [Grid](#grid)
31 | - [Canvas](#canvas)
32 | - [ClickCaptcha](#clickcaptcha)
33 | - [Rotate](#rotate)
34 | - [Amazon WAF](#amazon-waf)
35 | - [Cloudflare Turnstile](#cloudflare-turnstile)
36 | - [Lemin Cropped Captcha](#lemin-cropped-captcha)
37 | - [CyberSiARA](#cybersiara)
38 | - [DataDome](#datadome)
39 | - [MTCaptcha](#mtcaptcha)
40 | - [Yandex](#yandex)
41 | - [Tencent](#tencent)
42 | - [atbCAPTCHA](#atbcaptcha)
43 | - [Cutcaptcha](#cutcaptcha)
44 | - [Friendly Captcha](#friendly-captcha)
45 | - [Audio Captcha](#audio-captcha)
46 | - [Other methods](#other-methods)
47 | - [send / getResult](#send--getresult)
48 | - [balance](#balance)
49 | - [report](#report)
50 | - [Proxies](#proxies)
51 | - [Examples](#examples)
52 | - [Get in touch](#get-in-touch)
53 | - [Join the team 👪](#join-the-team-)
54 | - [License](#license)
55 | - [Graphics and Trademarks](#graphics-and-trademarks)
56 |
57 | ## Installation
58 | To install the api client, use this:
59 |
60 | ```bash
61 | go get -u github.com/2captcha/2captcha-go
62 | ```
63 |
64 | ## Configuration
65 |
66 | Import the module like this:
67 | ```go
68 | import (
69 | "github.com/2captcha/2captcha-go"
70 | )
71 | ```
72 | `Client` instance can be created like this:
73 | ```go
74 | client := api2captcha.NewClient("YOUR_API_KEY")
75 | ```
76 | There are few options that can be configured:
77 | ```go
78 | client.SoftId = 123
79 | client.Callback = "https://your.site/result-receiver"
80 | client.DefaultTimeout = 120
81 | client.RecaptchaTimeout = 600
82 | client.PollingInterval = 100
83 | ```
84 |
85 | ### Client instance options
86 |
87 | |Option|Default value|Description|
88 | |---|---|---|
89 | |soft_id|4583|Your software ID obtained after publishing in [2captcha software catalog]|
90 | |callback|-|URL of your web-sever that receives the captcha recognition result. The URl should be first registered in [pingback settings] of your account|
91 | |default_timeout|120|Timeout in seconds for all captcha types except reCAPTCHA. Defines how long the module tries to get the answer from `res.php` API endpoint|
92 | |recaptcha_timeout|600|Timeout for reCAPTCHA in seconds. Defines how long the module tries to get the answer from `res.php` API endpoint|
93 | |polling_interval|10|Interval in seconds between requests to `res.php` API endpoint, setting values less than 5 seconds is not recommended|
94 |
95 | > **IMPORTANT:** once *callback URL* is defined for `client` instance, all methods return only the captcha ID and DO NOT poll the API to get the result. The result will be sent to the callback URL.
96 |
97 | To get the answer manually use [GetResult method](#send--getresult)
98 |
99 | ## Solve captcha
100 | When you submit any image-based captcha use can provide additional options to help 2captcha workers to solve it properly.
101 |
102 | ### Captcha options
103 | |Option|Default Value|Description|
104 | |---|---|---|
105 | |numeric|0|Defines if captcha contains numeric or other symbols [see more info in the API docs][post options]|
106 | |min_len|0|minimal answer length|
107 | |max_len|0|maximum answer length|
108 | |phrase|0|defines if the answer contains multiple words or not|
109 | |case_sensitive|0|defines if the answer is case sensitive|
110 | |calc|0|defines captcha requires calculation|
111 | |lang|-|defines the captcha language, see the [list of supported languages] |
112 | |hint_img|-|an image with hint shown to workers with the captcha|
113 | |hint_text|-|hint or task text shown to workers with the captcha|
114 |
115 | Below you can find basic examples for every captcha type, check out the code below.
116 |
117 | ### Basic example
118 | Example below shows a basic solver call example with error handling.
119 |
120 | ```go
121 | captcha := api2captcha.Normal{
122 | File: "/path/to/normal.jpg",
123 | }
124 |
125 | code, err := client.Solve(captcha.ToRequest())
126 | if err != nil {
127 | if err == api2captcha.ErrTimeout {
128 | log.Fatal("Timeout");
129 | } else if err == api2captcha.ErrApi {
130 | log.Fatal("API error");
131 | } else if err == api2captcha.ErrNetwork {
132 | log.Fatal("Network error");
133 | } else {
134 | log.Fatal(err);
135 | }
136 | }
137 | fmt.Println("code "+code)
138 | ```
139 |
140 | ### Normal Captcha
141 |
142 | [API method description.](https://2captcha.com/2captcha-api#solving_normal_captcha)
143 |
144 | To bypass a normal captcha (distorted text on image) use the following method. This method also can be used to recognize any text on the image.
145 |
146 | ```go
147 | captcha:= api2captcha.Normal{
148 | File: "/path/to/normal.jpg",
149 | Numeric: 4,
150 | MinLen: 4,
151 | MaxLen: 20,
152 | Phrase: true,
153 | CaseSensitive: true,
154 | Lang: "en",
155 | HintImgFile: "/path/to/hint.jpg",
156 | HintText: "Type red symbols",
157 | }
158 | ```
159 |
160 | ### Text Captcha
161 |
162 | [API method description.](https://2captcha.com/2captcha-api#solving_text_captcha)
163 |
164 | This method can be used to bypass a captcha that requires to answer a question provided in clear text.
165 |
166 | ```go
167 | captcha:= api2captcha.Text{
168 | Text: "If tomorrow is Saturday, what day is today?",
169 | Lang: "en",
170 | }
171 | ```
172 |
173 | ### reCAPTCHA v2
174 |
175 | [API method description.](https://2captcha.com/2captcha-api#solving_recaptchav2_new)
176 |
177 | Use this method to solve reCAPTCHA V2 and obtain a token to bypass the protection.
178 |
179 | ```go
180 | captcha := api2captcha.ReCaptcha{
181 | SiteKey: "6Le-wvkSVVABCPBMRTvw0Q4Muexq1bi0DJwx_mJ-",
182 | Url: "https://mysite.com/page/with/recaptcha",
183 | Invisible: true,
184 | Action: "verify",
185 | }
186 | req := captcha.ToRequest()
187 | req.SetProxy("HTTPS", "login:password@IP_address:PORT")
188 | code, err := client.Solve(req)
189 | ```
190 |
191 | ### reCAPTCHA v3
192 |
193 | [API method description.](https://2captcha.com/2captcha-api#solving_recaptchav3)
194 |
195 | This method provides reCAPTCHA V3 solver and returns a token.
196 |
197 | ```go
198 | captcha := api2captcha.ReCaptcha{
199 | SiteKey: "6Le-wvkSVVABCPBMRTvw0Q4Muexq1bi0DJwx_mJ-",
200 | Url: "https://mysite.com/page/with/recaptcha",
201 | Version: "v3",
202 | Action: "verify",
203 | Score: 0.3,
204 | }
205 | req := captcha.ToRequest()
206 | req.SetProxy("HTTPS", "login:password@IP_address:PORT")
207 | code, err := client.Solve(req)
208 | ```
209 |
210 | ### reCAPTCHA Enterprise
211 |
212 | [API method description.](https://2captcha.com/2captcha-api#solving_recaptcha_enterprise)
213 |
214 | reCAPTCHA Enterprise can be used as reCAPTCHA V2 and reCAPTCHA V3. Below is a usage example for both versions.
215 |
216 | ```go
217 | // reCAPTCHA V2
218 | captcha:= api2captcha.ReCaptcha({
219 | SiteKey: "6Le-wvkSVVABCPBMRTvw0Q4Muexq1bi0DJwx_mJ-",
220 | Url: "https://mysite.com/page/with/recaptcha",
221 | Invisible: true,
222 | Action: "verify",
223 | Enterprise: true,
224 | })
225 |
226 | // reCAPTCHA V3
227 | captcha := api2captcha.ReCaptcha{
228 | SiteKey: "6Le-wvkSVVABCPBMRTvw0Q4Muexq1bi0DJwx_mJ-",
229 | Url: "https://mysite.com/page/with/recaptcha",
230 | Version: "v3",
231 | Action: "verify",
232 | Score: 0.3,
233 | Enterprise: true,
234 | }
235 |
236 | req := captcha.ToRequest()
237 | req.SetProxy("HTTPS", "login:password@IP_address:PORT")
238 | code, err := client.Solve(req)
239 | ```
240 |
241 | ### FunCaptcha
242 |
243 | [API method description.](https://2captcha.com/2captcha-api#solving_funcaptcha_new)
244 |
245 | FunCaptcha (Arkoselabs) solving method. Returns a token.
246 |
247 | ```go
248 | captcha := api2captcha.FunCaptcha{
249 | SiteKey: "69A21A01-CC7B-B9C6-0F9A-E7FA06677FFC",
250 | Url: "https://mysite.com/page/with/funcaptcha",
251 | Surl: "https://client-api.arkoselabs.com",
252 | UserAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36",
253 | Data: map[string]string{"anyKey":"anyValue"},
254 | }
255 | req := captcha.ToRequest()
256 | req.SetProxy("HTTPS", "login:password@IP_address:PORT")
257 | code, err := client.Solve(req)
258 | ```
259 |
260 | ### GeeTest
261 |
262 | [API method description.](https://2captcha.com/2captcha-api#solving_geetest)
263 |
264 | Method to solve GeeTest puzzle captcha. Returns a set of tokens as JSON.
265 |
266 | ```go
267 | captcha := api2captcha.GeeTest{
268 | GT: "f2ae6cadcf7886856696502e1d55e00c",
269 | ApiServer: "api-na.geetest.com",
270 | Challenge: "12345678abc90123d45678ef90123a456b",
271 | Url: "https://mysite.com/captcha.html",
272 | }
273 | req := captcha.ToRequest()
274 | req.SetProxy("HTTPS", "login:password@IP_address:PORT")
275 | code, err := client.Solve(req)
276 | ```
277 |
278 | ### GeeTest V4
279 |
280 | [API method description.](https://2captcha.com/2captcha-api#geetest-v4)
281 |
282 | Use this method to solve GeeTest v4. Returns the response in JSON.
283 |
284 | ```go
285 | captcha:= api2captcha.GeeTestV4{
286 | CaptchaId: "e392e1d7fd421dc63325744d5a2b9c73",
287 | Url: "https://www.site.com/page/",
288 | }
289 | ```
290 |
291 | ### KeyCaptcha
292 |
293 | [API method description.](https://2captcha.com/2captcha-api#solving_keycaptcha)
294 |
295 | Token-based method to solve KeyCaptcha.
296 |
297 | ```go
298 | captcha:= api2captcha.KeyCaptcha{
299 | UserId: 10,
300 | SessionId: "493e52c37c10c2bcdf4a00cbc9ccd1e8",
301 | WebServerSign: "9006dc725760858e4c0715b835472f22",
302 | WebServerSign2: "9006dc725760858e4c0715b835472f22",
303 | Url: "https://www.keycaptcha.ru/demo-magnetic/",
304 | }
305 | req := captchaToRequest()
306 | req.SetProxy("HTTPS", "login:password@IP_address:PORT")
307 | code, err := client.Solve(req)
308 | ```
309 |
310 | ### Capy
311 |
312 | [API method description.](https://2captcha.com/2captcha-api#solving_capy)
313 |
314 | Token-based method to bypass Capy puzzle captcha.
315 |
316 | ```go
317 | captcha:= api2captcha.Capy{
318 | SiteKey: "PUZZLE_Abc1dEFghIJKLM2no34P56q7rStu8v",
319 | Url: "https://www.mysite.com/captcha/",
320 | }
321 | req := captchaToRequest()
322 | req.SetProxy("HTTPS", "login:password@IP_address:PORT")
323 | code, err := client.Solve(req)
324 | ```
325 |
326 | ### Grid
327 |
328 | [API method description.](https://2captcha.com/2captcha-api#grid)
329 |
330 | Grid method is originally called Old reCAPTCHA V2 method. The method can be used to bypass any type of captcha where you can apply a grid on image and need to click specific grid boxes. Returns numbers of boxes.
331 |
332 | ```go
333 | captcha:= api2captcha.Grid{
334 | File: "path/to/captcha.jpg",
335 | Rows: 3,
336 | Cols: 3,
337 | PreviousId: 0,
338 | CanSkip: false,
339 | Lang: "en",
340 | HintImageFile: "path/to/hint.jpg",
341 | HintText: "Select all images with an Orange",
342 | }
343 | ```
344 |
345 | ### Canvas
346 |
347 | [API method description.](https://2captcha.com/2captcha-api#canvas)
348 |
349 | Canvas method can be used when you need to draw a line around an object on image. Returns a set of points' coordinates to draw a polygon.
350 |
351 | ```go
352 | captcha:= api2captcha.Canvas{
353 | File: "path/to/captcha.jpg",
354 | PreviousId: 0,
355 | CanSkip: false,
356 | Lang: "en",
357 | HintImageFile: "path/to/hint.jpg",
358 | HintText: "Draw around apple",
359 | }
360 | ```
361 |
362 | ### ClickCaptcha
363 |
364 | [API method description.](https://2captcha.com/2captcha-api#coordinates)
365 |
366 | ClickCaptcha method returns coordinates of points on captcha image. Can be used if you need to click on particular points on the image.
367 |
368 | ```go
369 | captcha:= api2captcha.Coordinates{
370 | File: "path/to/captcha.jpg",
371 | Lang: "en",
372 | HintImageFile: "path/to/hint.jpg",
373 | HintText: "Connect the dots",
374 | }
375 | ```
376 |
377 | ### Rotate
378 |
379 | [API method description.](https://2captcha.com/2captcha-api#solving_rotatecaptcha)
380 |
381 | This method can be used to solve a captcha that asks to rotate an object. Mostly used to bypass FunCaptcha. Returns the rotation angle.
382 |
383 | ```go
384 | captcha:= api2captcha.Rotate{
385 | File: "path/to/captcha.jpg",
386 | Angle: 15,
387 | Lang: "en",
388 | HintImageFile: "path/to/hint.jpg",
389 | HintText: "Put the images in the correct way",
390 | }
391 | ```
392 |
393 | ### Amazon WAF
394 |
395 | [API method description.](https://2captcha.com/2captcha-api#amazon-waf)
396 |
397 | Use this method to solve Amazon WAF Captcha also known as AWS WAF Captcha is a part of Intelligent threat mitigation for Amazon AWS. Returns JSON with the token.
398 |
399 | ```go
400 | captcha:= api2captcha.AmazonWAF {
401 | Iv: "CgAHbCe2GgAAAAAj",
402 | SiteKey: "0x1AAAAAAAAkg0s2VIOD34y5",
403 | Url: "https://non-existent-example.execute-api.us-east-1.amazonaws.com/latest",
404 | Context: "9BUgmlm48F92WUoqv97a49ZuEJJ50TCk9MVr3C7WMtQ0X6flVbufM4n8mjFLmbLVAPgaQ1Jydeaja94iAS49ljb",
405 | ChallengeScript: "https://41bcdd4fb3cb.610cd090.us-east-1.token.awswaf.com/41bcdd4fb3cb/0d21de737ccb/cd77baa6c832/challenge.js"
406 | CaptchaScript: "https://41bcdd4fb3cb.610cd090.us-east-1.captcha.awswaf.com/41bcdd4fb3cb/0d21de737ccb/cd77baa6c832/captcha.js"
407 | }
408 | ```
409 |
410 | ### Cloudflare Turnstile
411 |
412 | [API method description.](https://2captcha.com/2captcha-api#turnstile)
413 |
414 | Use this method to solve Cloudflare Turnstile. Returns JSON with the token.
415 |
416 | ```go
417 | captcha:= api2captcha.CloudflareTurnstile{
418 | SiteKey: "0x1AAAAAAAAkg0s2VIOD34y5",
419 | Url: "http://mysite.com/",
420 | }
421 | ```
422 |
423 | ### Lemin Cropped Captcha
424 |
425 | [API method description.](https://2captcha.com/2captcha-api#lemin)
426 |
427 | Use this method to solve Lemin Captcha challenge. Returns JSON with answer containing the following values: answer, challenge_id.
428 |
429 | ```go
430 | captcha:= Lemin{
431 | CaptchaId: "CROPPED_3dfdd5c_d1872b526b794d83ba3b365eb15a200b",
432 | Url: "https://www.site.com/page/",
433 | DivId: "lemin-cropped-captcha",
434 | ApiServer: "api.leminnow.com",
435 | }
436 | ```
437 |
438 | ### CyberSiARA
439 |
440 | [API method description.](https://2captcha.com/2captcha-api#cybersiara)
441 |
442 | Use this method to solve CyberSiARA and obtain a token to bypass the protection.
443 | ```go
444 | captcha:= api2captcha.CyberSiARA{
445 | MasterUrlId: "12333-3123123",
446 | Url: "https://test.com",
447 | UserAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36",
448 | }
449 | ```
450 |
451 | ### DataDome
452 |
453 | [API method description.](https://2captcha.com/2captcha-api#datadome)
454 |
455 | Use this method to solve DataDome and obtain a token to bypass the protection.
456 |
457 | > [!IMPORTANT]
458 | > To solve the DataDome captcha, you must use a proxy. It is recommended to use [residential proxies].
459 |
460 |
461 | ```go
462 | captcha:= api2captcha.DataDome{
463 | Url: "https://test.com",
464 | CaptchaUrl: "https://test.com/captcha/",
465 | Proxytype: "http",
466 | Proxy: "proxyuser:strongPassword@123.123.123.123:3128",
467 | UserAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36",
468 | }
469 | ```
470 |
471 | ### MTCaptcha
472 |
473 | [API method description.](https://2captcha.com/2captcha-api#mtcaptcha)
474 |
475 | Use this method to solve MTCaptcha and obtain a token to bypass the protection.
476 | ```go
477 | captcha:= api2captcha.MTCaptcha{
478 | Url: "https://service.mtcaptcha.com/mtcv1/demo/index.html",
479 | SiteKey: "MTPublic-DemoKey9M",
480 | }
481 | ```
482 |
483 | ### Yandex
484 | Use this method to solve Yandex and obtain a token to bypass the protection.
485 | ```go
486 | captcha:= api2captcha.Yandex{
487 | Url: "https://example.com",
488 | SiteKey: "Y5Lh0tiycconMJGsFd3EbbuNKSp1yaZESUOIHfeV",
489 | }
490 | ```
491 |
492 | ### Tencent
493 |
494 | [API method description.](https://2captcha.com/2captcha-api#tencent)
495 |
496 | Use this method to solve Tencent and obtain a token to bypass the protection.
497 | ```go
498 | tencentCaptcha := api2captcha.Tencent{
499 | AppId: "2092215077",
500 | Url: "http://lcec.lclog.cn/cargo/NewCargotracking?blno=BANR01XMHB0004&selectstate=BLNO",
501 | }
502 | ```
503 |
504 | ### atbCAPTCHA
505 |
506 | [API method description.](https://2captcha.com/2captcha-api#atb-captcha)
507 |
508 | Use this method to solve atbCAPTCHA and obtain a token to bypass the protection.
509 | ```go
510 | atbCaptcha := api2captcha.AtbCAPTCHA{
511 | AppId: "af23e041b22d000a11e22a230fa8991c",
512 | Url: "https://www.playzone.vip/",
513 | ApiServer: "https://cap.aisecurius.com",
514 | }
515 | ```
516 |
517 | ### Cutcaptcha
518 |
519 | [API method description.](https://2captcha.com/2captcha-api#cutcaptcha)
520 |
521 | Use this method to solve Cutcaptcha and obtain a token to bypass the protection.
522 | ```go
523 | captcha:= api2captcha.Cutcaptcha{
524 | MiseryKey: "a1488b66da00bf332a1488993a5443c79047e752",
525 | DataApiKey: "SAb83IIB",
526 | Url: "https://example.cc/foo/bar.html",
527 | }
528 | ```
529 |
530 | ### Friendly Captcha
531 |
532 | [API method description.](https://2captcha.com/2captcha-api#friendly-captcha)
533 |
534 | Use this method to solve Friendly Captcha and obtain a token to bypass the protection.
535 | ```go
536 | captcha:= api2captcha.Friendly{
537 | Url: "https://example.com",
538 | SiteKey: "2FZFEVS1FZCGQ9",
539 | }
540 | ```
541 |
542 | ### Audio Captcha
543 |
544 | [API method description.](https://2captcha.com/2captcha-api#audio)
545 |
546 | Use this method to solve Audio captcha and obtain a token to bypass the protection.
547 | ```go
548 | audio := api2captcha.Audio{
549 | Base64: fileBase64Str,
550 | Lang: "en",
551 | }
552 | ```
553 |
554 | ## Other methods
555 |
556 | ### Send / GetResult
557 | These methods can be used for manual captcha submission and answer polling.
558 |
559 | ```go
560 | id, err := client.Send(captchaToRequest())
561 | if err != nil {
562 | log.Fatal(err);
563 | }
564 |
565 | time.Sleep(10 * time.Second)
566 |
567 | code, err := client.GetResult(id)
568 | if err != nil {
569 | log.Fatal(err);
570 | }
571 |
572 | if code == nil {
573 | log.Fatal("Not ready")
574 | }
575 |
576 | fmt.Println("code "+*code)
577 | ```
578 |
579 | ### balance
580 |
581 | [API method description.](https://2captcha.com/2captcha-api#additional-methods)
582 |
583 | Use this method to get your account's balance
584 |
585 | ```go
586 | balance, err := client.GetBalance()
587 | if err != nil {
588 | log.Fatal(err);
589 | }
590 | ```
591 | ### report
592 |
593 | [API method description.](https://2captcha.com/2captcha-api#complain)
594 |
595 | Use this method to report good or bad captcha answer.
596 |
597 | ```go
598 | err := client.Report(id, true) // solved correctly
599 | err := client.Report(id, false) // solved incorrectly
600 | ```
601 |
602 | ## Error Handling
603 |
604 | When using the 2Captcha API, it's important to handle errors properly to ensure smooth interaction with the service. Below is an example of error handling in the `2captcha-go` library:
605 |
606 | ```go
607 | func main() {
608 | result, err := client.Text("If tomorrow is Saturday, what day is today?")
609 | if err != nil {
610 | switch e := err.(type) {
611 | case *api.ValidationException:
612 | // Invalid parameters passed
613 | log.Fatalf("Validation error: %v", e)
614 | case *api.NetworkException:
615 | // Network error occurred
616 | log.Fatalf("Network error: %v", e)
617 | case *api.ApiException:
618 | // API responded with an error
619 | log.Fatalf("API error: %v", e)
620 | case *api.TimeoutException:
621 | // CAPTCHA is not solved within the expected time
622 | log.Fatalf("Timeout error: %v", e)
623 | default:
624 | // Unknown error
625 | log.Fatalf("Unexpected error: %v", err)
626 | }
627 | }
628 |
629 | fmt.Printf("CAPTCHA solved! Result: %s\n", result.Text)
630 | }
631 | ```
632 |
633 | ## Proxies
634 | You can pass your proxy as an additional argument for methods: recaptcha, funcaptcha, geetest, geetest v4, keycaptcha, capy puzzle, lemin, turnstile, amazon waf, CyberSiARA, DataDome, MTCaptcha and etc. The proxy will be forwarded to the API to solve the captcha.
635 |
636 | We have our own proxies that we can offer you. [Buy residential proxies](https://2captcha.com/proxy/residential-proxies) for avoid restrictions and blocks. [Quick start](https://2captcha.com/proxy?openAddTrafficModal=true).
637 |
638 | ## Examples
639 |
640 | Examples of solving all supported captcha types are located in the [examples] directory.
641 |
642 | ## Get in touch
643 |
644 |
645 |
646 |
647 | ## Join the team 👪
648 |
649 | There are many ways to contribute, of which development is only one! Find your next job. Open positions: AI experts, scrapers, developers, technical support, and much more! 😍
650 |
651 |
652 |
653 | ## License
654 |
655 | The code in this repository is licensed under the MIT License. See the [LICENSE](./LICENSE) file for more details.
656 |
657 | ### Graphics and Trademarks
658 |
659 | The graphics and trademarks included in this repository are not covered by the MIT License. Please contact support for permissions regarding the use of these materials.
660 |
661 |
662 |
663 | [2Captcha]: https://2captcha.com/
664 | [2captcha software catalog]: https://2captcha.com/software
665 | [pingback settings]: https://2captcha.com/setting/pingback
666 | [post options]: https://2captcha.com/2captcha-api#normal_post
667 | [list of supported languages]: https://2captcha.com/2captcha-api#language
668 | [residential proxies]: https://2captcha.com/proxy/residential-proxies
669 | [examples]: ./examples/
670 |
--------------------------------------------------------------------------------
/api2captcha.go:
--------------------------------------------------------------------------------
1 | package api2captcha
2 |
3 | import (
4 | "bytes"
5 | "errors"
6 | "io"
7 | "mime/multipart"
8 | "net/http"
9 | "net/url"
10 | "os"
11 | "path/filepath"
12 | "strconv"
13 | "strings"
14 | "time"
15 | )
16 |
17 | const (
18 | BaseURL = "https://2captcha.com"
19 | DefaultSoftId = 4583
20 | )
21 |
22 | type (
23 | Request struct {
24 | Params map[string]string
25 | Files map[string]string
26 | }
27 |
28 | Client struct {
29 | BaseURL *url.URL
30 | ApiKey string
31 | SoftId int
32 | Callback string
33 | DefaultTimeout int
34 | RecaptchaTimeout int
35 | PollingInterval int
36 |
37 | httpClient *http.Client
38 | }
39 |
40 | Canvas struct {
41 | File string
42 | Base64 string
43 | PreviousId int
44 | CanSkip bool
45 | Lang string
46 | HintText string
47 | HintImageBase64 string
48 | HintImageFile string
49 | }
50 |
51 | Capy struct {
52 | SiteKey string
53 | Url string
54 | ApiServer string
55 | }
56 |
57 | Coordinates struct {
58 | File string
59 | Base64 string
60 | Lang string
61 | HintText string
62 | HintImageBase64 string
63 | HintImageFile string
64 | }
65 |
66 | FunCaptcha struct {
67 | SiteKey string
68 | Url string
69 | Surl string
70 | UserAgent string
71 | Data map[string]string
72 | }
73 |
74 | GeeTest struct {
75 | GT string
76 | Challenge string
77 | Url string
78 | ApiServer string
79 | }
80 |
81 | Grid struct {
82 | File string
83 | Base64 string
84 | Rows int
85 | Cols int
86 | PreviousId int
87 | CanSkip bool
88 | Lang string
89 | HintText string
90 | HintImageBase64 string
91 | HintImageFile string
92 | }
93 |
94 | HCaptcha struct {
95 | SiteKey string
96 | Url string
97 | }
98 |
99 | KeyCaptcha struct {
100 | UserId int
101 | SessionId string
102 | WebServerSign string
103 | WebServerSign2 string
104 | Url string
105 | }
106 |
107 | Normal struct {
108 | File string
109 | Base64 string
110 | Phrase bool
111 | CaseSensitive bool
112 | Calc bool
113 | Numberic int
114 | MinLen int
115 | MaxLen int
116 | Lang string
117 | HintText string
118 | HintImageBase64 string
119 | HintImageFile string
120 | }
121 |
122 | ReCaptcha struct {
123 | SiteKey string
124 | Url string
125 | Invisible bool
126 | Enterprise bool
127 | Version string
128 | Action string
129 | DataS string
130 | Score float64
131 | }
132 |
133 | Rotate struct {
134 | Base64 string
135 | File string
136 | Files []string
137 | Angle int
138 | Lang string
139 | HintText string
140 | HintImageBase64 string
141 | HintImageFile string
142 | }
143 |
144 | Text struct {
145 | Text string
146 | Lang string
147 | }
148 |
149 | AmazonWAF struct {
150 | Iv string
151 | SiteKey string
152 | Url string
153 | Context string
154 | ChallengeScript string
155 | CaptchaScript string
156 | }
157 |
158 | GeeTestV4 struct {
159 | CaptchaId string
160 | Url string
161 | ApiServer string
162 | Challenge string
163 | }
164 |
165 | Lemin struct {
166 | CaptchaId string
167 | DivId string
168 | Url string
169 | ApiServer string
170 | }
171 |
172 | CloudflareTurnstile struct {
173 | SiteKey string
174 | Url string
175 | Data string
176 | PageData string
177 | Action string
178 | UserAgent string
179 | }
180 |
181 | CyberSiARA struct {
182 | MasterUrlId string
183 | Url string
184 | UserAgent string
185 | }
186 |
187 | DataDome struct {
188 | Url string
189 | CaptchaUrl string
190 | Proxytype string
191 | Proxy string
192 | UserAgent string
193 | }
194 |
195 | MTCaptcha struct {
196 | SiteKey string
197 | Url string
198 | }
199 |
200 | Yandex struct {
201 | Url string
202 | SiteKey string
203 | }
204 |
205 | Friendly struct {
206 | Url string
207 | SiteKey string
208 | }
209 |
210 | CutCaptcha struct {
211 | MiseryKey string
212 | DataApiKey string
213 | Url string
214 | }
215 |
216 | Tencent struct {
217 | AppId string
218 | Url string
219 | }
220 |
221 | AtbCAPTCHA struct {
222 | AppId string
223 | ApiServer string
224 | Url string
225 | }
226 |
227 | Audio struct {
228 | Base64 string
229 | Lang string
230 | }
231 | )
232 |
233 | var (
234 | ErrNetwork = errors.New("api2captcha: Network failure")
235 | ErrApi = errors.New("api2captcha: API error")
236 | ErrTimeout = errors.New("api2captcha: Request timeout")
237 | )
238 |
239 | func NewClient(apiKey string) *Client {
240 | base, _ := url.Parse(BaseURL)
241 | return &Client{
242 | BaseURL: base,
243 | ApiKey: apiKey,
244 | SoftId: DefaultSoftId,
245 | DefaultTimeout: 120,
246 | PollingInterval: 10,
247 | RecaptchaTimeout: 600,
248 | httpClient: http.DefaultClient,
249 | }
250 | }
251 |
252 | func NewClientExt(apiKey string, client *http.Client) *Client {
253 | base, _ := url.Parse(BaseURL)
254 | return &Client{
255 | BaseURL: base,
256 | ApiKey: apiKey,
257 | DefaultTimeout: 120,
258 | PollingInterval: 10,
259 | RecaptchaTimeout: 600,
260 | httpClient: client,
261 | }
262 | }
263 |
264 | func (c *Client) res(req Request) (*string, error) {
265 |
266 | rel := &url.URL{Path: "/res.php"}
267 | uri := c.BaseURL.ResolveReference(rel)
268 |
269 | req.Params["key"] = c.ApiKey
270 | c.httpClient.Timeout = time.Duration(c.DefaultTimeout) * time.Second
271 |
272 | var resp *http.Response = nil
273 |
274 | values := url.Values{}
275 | for key, val := range req.Params {
276 | values.Add(key, val)
277 | }
278 | uri.RawQuery = values.Encode()
279 |
280 | var err error = nil
281 | resp, err = c.httpClient.Get(uri.String())
282 | if err != nil {
283 | return nil, ErrNetwork
284 | }
285 |
286 | defer resp.Body.Close()
287 | body := &bytes.Buffer{}
288 | _, err = body.ReadFrom(resp.Body)
289 | if err != nil {
290 | return nil, err
291 | }
292 | data := body.String()
293 |
294 | if resp.StatusCode != http.StatusOK {
295 | return nil, ErrApi
296 | }
297 |
298 | if strings.HasPrefix(data, "ERROR_") {
299 | return nil, ErrApi
300 | }
301 |
302 | return &data, nil
303 | }
304 |
305 | func (c *Client) resAction(action string) (*string, error) {
306 | req := Request{
307 | Params: map[string]string{"action": action},
308 | }
309 |
310 | return c.res(req)
311 | }
312 |
313 | func (c *Client) Send(req Request) (string, error) {
314 |
315 | rel := &url.URL{Path: "/in.php"}
316 | uri := c.BaseURL.ResolveReference(rel)
317 |
318 | req.Params["key"] = c.ApiKey
319 |
320 | c.httpClient.Timeout = time.Duration(c.DefaultTimeout) * time.Second
321 |
322 | var resp *http.Response = nil
323 | if req.Files != nil && len(req.Files) > 0 {
324 |
325 | body := &bytes.Buffer{}
326 | writer := multipart.NewWriter(body)
327 |
328 | for name, path := range req.Files {
329 | file, err := os.Open(path)
330 | if err != nil {
331 | return "", err
332 | }
333 | defer file.Close()
334 |
335 | part, err := writer.CreateFormFile(name, filepath.Base(path))
336 | if err != nil {
337 | return "", err
338 | }
339 | _, err = io.Copy(part, file)
340 | }
341 |
342 | for key, val := range req.Params {
343 | _ = writer.WriteField(key, val)
344 | }
345 |
346 | err := writer.Close()
347 | if err != nil {
348 | return "", err
349 | }
350 |
351 | request, err := http.NewRequest("POST", uri.String(), body)
352 | if err != nil {
353 | return "", err
354 | }
355 |
356 | request.Header.Set("Content-Type", writer.FormDataContentType())
357 |
358 | resp, err = c.httpClient.Do(request)
359 | if err != nil {
360 | return "", ErrNetwork
361 | }
362 | } else {
363 | values := url.Values{}
364 | for key, val := range req.Params {
365 | values.Add(key, val)
366 | }
367 |
368 | var err error = nil
369 | resp, err = c.httpClient.PostForm(uri.String(), values)
370 | if err != nil {
371 | return "", ErrNetwork
372 | }
373 | }
374 |
375 | defer resp.Body.Close()
376 | body := &bytes.Buffer{}
377 | _, err := body.ReadFrom(resp.Body)
378 | if err != nil {
379 | return "", err
380 | }
381 | data := body.String()
382 |
383 | if resp.StatusCode != http.StatusOK {
384 | return "", ErrApi
385 | }
386 |
387 | if strings.HasPrefix(data, "ERROR_") {
388 | return "", ErrApi
389 | }
390 |
391 | if !strings.HasPrefix(data, "OK|") {
392 | return "", ErrApi
393 | }
394 |
395 | return data[3:], nil
396 | }
397 |
398 | func (c *Client) Solve(req Request) (string, string, error) {
399 | if c.Callback != "" {
400 | _, ok := req.Params["pingback"]
401 | if !ok {
402 | // set default pingback
403 | req.Params["pingback"] = c.Callback
404 | }
405 | }
406 |
407 | pingback, hasPingback := req.Params["pingback"]
408 | if pingback == "" {
409 | delete(req.Params, "pingback")
410 | hasPingback = false
411 | }
412 |
413 | _, ok := req.Params["soft_id"]
414 | if c.SoftId != 0 && !ok {
415 | req.Params["soft_id"] = strconv.FormatInt(int64(c.SoftId), 10)
416 | }
417 |
418 | id, err := c.Send(req)
419 | if err != nil {
420 | return "", "", err
421 | }
422 |
423 | // don't wait for result if Callback is used
424 | if hasPingback {
425 | return "", id, nil
426 | }
427 |
428 | timeout := c.DefaultTimeout
429 | if req.Params["method"] == "userrecaptcha" {
430 | timeout = c.RecaptchaTimeout
431 | }
432 |
433 | token, err := c.WaitForResult(id, timeout, c.PollingInterval)
434 | if err != nil {
435 | return "", "", err
436 | }
437 |
438 | return token, id, nil
439 | }
440 |
441 | func (c *Client) WaitForResult(id string, timeout int, interval int) (string, error) {
442 |
443 | start := time.Now()
444 | now := start
445 | for now.Sub(start) < (time.Duration(timeout) * time.Second) {
446 |
447 | time.Sleep(time.Duration(interval) * time.Second)
448 |
449 | code, err := c.GetResult(id)
450 | if err == nil && code != nil {
451 | return *code, nil
452 | }
453 |
454 | // ignore network errors
455 | if err != nil && err != ErrNetwork {
456 | return "", err
457 | }
458 |
459 | now = time.Now()
460 | }
461 |
462 | return "", ErrTimeout
463 | }
464 |
465 | func (c *Client) GetResult(id string) (*string, error) {
466 | req := Request{
467 | Params: map[string]string{"action": "get", "id": id},
468 | }
469 |
470 | data, err := c.res(req)
471 | if err != nil {
472 | return nil, err
473 | }
474 |
475 | if *data == "CAPCHA_NOT_READY" {
476 | return nil, nil
477 | }
478 |
479 | if !strings.HasPrefix(*data, "OK|") {
480 | return nil, ErrApi
481 | }
482 |
483 | reply := (*data)[3:]
484 | return &reply, nil
485 | }
486 |
487 | func (c *Client) GetBalance() (float64, error) {
488 | data, err := c.resAction("getbalance")
489 | if err != nil {
490 | return 0.0, err
491 | }
492 |
493 | return strconv.ParseFloat(*data, 64)
494 | }
495 |
496 | func (c *Client) Report(id string, correct bool) error {
497 | req := Request{
498 | Params: map[string]string{"id": id},
499 | }
500 | if correct {
501 | req.Params["action"] = "reportgood"
502 | } else {
503 | req.Params["action"] = "reportbad"
504 | }
505 |
506 | _, err := c.res(req)
507 | return err
508 | }
509 |
510 | func (req *Request) SetProxy(proxyType string, uri string) {
511 | req.Params["proxytype"] = proxyType
512 | req.Params["proxy"] = uri
513 | }
514 |
515 | func (req *Request) SetSoftId(softId int) {
516 | req.Params["soft_id"] = strconv.FormatInt(int64(softId), 10)
517 | }
518 |
519 | func (req *Request) SetCallback(callback string) {
520 | req.Params["pingback"] = callback
521 | }
522 |
523 | func (c *Canvas) ToRequest() Request {
524 | req := Request{
525 | Params: map[string]string{"canvas": "1", "recaptcha": "1"},
526 | Files: map[string]string{},
527 | }
528 | if c.File != "" {
529 | req.Files["file"] = c.File
530 | req.Params["method"] = "post"
531 | }
532 | if c.Base64 != "" {
533 | req.Params["body"] = c.Base64
534 | req.Params["method"] = "base64"
535 | }
536 | if c.PreviousId != 0 {
537 | req.Params["previousID"] = strconv.FormatInt(int64(c.PreviousId), 10)
538 | }
539 | if c.CanSkip {
540 | req.Params["can_no_answer"] = "1"
541 | }
542 | if c.Lang != "" {
543 | req.Params["lang"] = c.Lang
544 | }
545 | if c.HintText != "" {
546 | req.Params["textinstructions"] = c.HintText
547 | }
548 | if c.HintImageBase64 != "" {
549 | req.Params["imginstructions"] = c.HintImageBase64
550 | }
551 | if c.HintImageFile != "" {
552 | req.Files["imginstructions"] = c.HintImageFile
553 | }
554 |
555 | return req
556 | }
557 |
558 | func (c *Normal) ToRequest() Request {
559 | req := Request{
560 | Params: map[string]string{},
561 | Files: map[string]string{},
562 | }
563 | if c.File != "" {
564 | req.Files["file"] = c.File
565 | req.Params["method"] = "post"
566 | }
567 | if c.Base64 != "" {
568 | req.Params["body"] = c.Base64
569 | req.Params["method"] = "base64"
570 | }
571 |
572 | if c.Phrase {
573 | req.Params["phrase"] = "1"
574 | }
575 | if c.CaseSensitive {
576 | req.Params["regsense"] = "1"
577 | }
578 | if c.Calc {
579 | req.Params["calc"] = "1"
580 | }
581 | if c.Numberic != 0 {
582 | req.Params["numeric"] = strconv.FormatInt(int64(c.Numberic), 10)
583 | }
584 | if c.MinLen != 0 {
585 | req.Params["min_len"] = strconv.FormatInt(int64(c.MinLen), 10)
586 | }
587 | if c.MaxLen != 0 {
588 | req.Params["max_len"] = strconv.FormatInt(int64(c.MaxLen), 10)
589 | }
590 |
591 | if c.Lang != "" {
592 | req.Params["lang"] = c.Lang
593 | }
594 | if c.HintText != "" {
595 | req.Params["textinstructions"] = c.HintText
596 | }
597 | if c.HintImageBase64 != "" {
598 | req.Params["imginstructions"] = c.HintImageBase64
599 | }
600 | if c.HintImageFile != "" {
601 | req.Files["imginstructions"] = c.HintImageFile
602 | }
603 |
604 | return req
605 | }
606 |
607 | func (c *Capy) ToRequest() Request {
608 | req := Request{
609 | Params: map[string]string{"method": "capy"},
610 | }
611 | if c.SiteKey != "" {
612 | req.Params["captchakey"] = c.SiteKey
613 | }
614 | if c.Url != "" {
615 | req.Params["pageurl"] = c.Url
616 | }
617 | if c.ApiServer != "" {
618 | req.Params["api_server"] = c.ApiServer
619 | }
620 |
621 | return req
622 | }
623 |
624 | func (c *Coordinates) ToRequest() Request {
625 | req := Request{
626 | Params: map[string]string{"coordinatescaptcha": "1"},
627 | Files: map[string]string{},
628 | }
629 | if c.File != "" {
630 | req.Files["file"] = c.File
631 | }
632 | if c.Base64 != "" {
633 | req.Params["body"] = c.Base64
634 | }
635 | if c.Lang != "" {
636 | req.Params["lang"] = c.Lang
637 | }
638 | if c.HintText != "" {
639 | req.Params["textinstructions"] = c.HintText
640 | }
641 | if c.HintImageBase64 != "" {
642 | req.Params["imginstructions"] = c.HintImageBase64
643 | }
644 | if c.HintImageFile != "" {
645 | req.Files["imginstructions"] = c.HintImageFile
646 | }
647 |
648 | return req
649 | }
650 |
651 | func (c *FunCaptcha) ToRequest() Request {
652 | req := Request{
653 | Params: map[string]string{"method": "funcaptcha"},
654 | }
655 | if c.SiteKey != "" {
656 | req.Params["publickey"] = c.SiteKey
657 | }
658 | if c.Url != "" {
659 | req.Params["pageurl"] = c.Url
660 | }
661 | if c.Surl != "" {
662 | req.Params["surl"] = c.Surl
663 | }
664 | if c.UserAgent != "" {
665 | req.Params["userAgent"] = c.UserAgent
666 | }
667 | if c.Data != nil {
668 | for key, value := range c.Data {
669 | param := "data[" + key + "]"
670 | req.Params[param] = value
671 | }
672 | }
673 |
674 | return req
675 | }
676 |
677 | func (c *GeeTest) ToRequest() Request {
678 | req := Request{
679 | Params: map[string]string{"method": "geetest"},
680 | }
681 | if c.GT != "" {
682 | req.Params["gt"] = c.GT
683 | }
684 | if c.Challenge != "" {
685 | req.Params["challenge"] = c.Challenge
686 | }
687 | if c.Url != "" {
688 | req.Params["pageurl"] = c.Url
689 | }
690 | if c.ApiServer != "" {
691 | req.Params["api_server"] = c.ApiServer
692 | }
693 |
694 | return req
695 | }
696 |
697 | func (c *Grid) ToRequest() Request {
698 | req := Request{
699 | Params: map[string]string{},
700 | Files: map[string]string{},
701 | }
702 | if c.File != "" {
703 | req.Files["file"] = c.File
704 | }
705 | if c.Base64 != "" {
706 | req.Params["body"] = c.Base64
707 | }
708 | if c.Rows != 0 {
709 | req.Params["recaptcharows"] = strconv.FormatInt(int64(c.Rows), 10)
710 | }
711 | if c.Cols != 0 {
712 | req.Params["recaptchacols"] = strconv.FormatInt(int64(c.Cols), 10)
713 | }
714 | if c.PreviousId != 0 {
715 | req.Params["previousID"] = strconv.FormatInt(int64(c.PreviousId), 10)
716 | }
717 | if c.CanSkip {
718 | req.Params["can_no_answer"] = "1"
719 | }
720 | if c.Lang != "" {
721 | req.Params["lang"] = c.Lang
722 | }
723 | if c.HintText != "" {
724 | req.Params["textinstructions"] = c.HintText
725 | }
726 | if c.HintImageBase64 != "" {
727 | req.Params["imginstructions"] = c.HintImageBase64
728 | }
729 | if c.HintImageFile != "" {
730 | req.Files["imginstructions"] = c.HintImageFile
731 | }
732 |
733 | return req
734 | }
735 |
736 | func (c *HCaptcha) ToRequest() Request {
737 | req := Request{
738 | Params: map[string]string{"method": "hcaptcha"},
739 | }
740 | if c.SiteKey != "" {
741 | req.Params["sitekey"] = c.SiteKey
742 | }
743 | if c.Url != "" {
744 | req.Params["pageurl"] = c.Url
745 | }
746 |
747 | return req
748 | }
749 |
750 | func (c *KeyCaptcha) ToRequest() Request {
751 | req := Request{
752 | Params: map[string]string{"method": "keycaptcha"},
753 | }
754 | if c.UserId != 0 {
755 | req.Params["s_s_c_user_id"] = strconv.FormatInt(int64(c.UserId), 10)
756 | }
757 | if c.SessionId != "" {
758 | req.Params["s_s_c_session_id"] = c.SessionId
759 | }
760 | if c.WebServerSign != "" {
761 | req.Params["s_s_c_web_server_sign"] = c.WebServerSign
762 | }
763 | if c.WebServerSign2 != "" {
764 | req.Params["s_s_c_web_server_sign2"] = c.WebServerSign2
765 | }
766 | if c.Url != "" {
767 | req.Params["pageurl"] = c.Url
768 | }
769 |
770 | return req
771 | }
772 |
773 | func (c *ReCaptcha) ToRequest() Request {
774 | req := Request{
775 | Params: map[string]string{"method": "userrecaptcha"},
776 | }
777 | if c.SiteKey != "" {
778 | req.Params["googlekey"] = c.SiteKey
779 | }
780 | if c.Url != "" {
781 | req.Params["pageurl"] = c.Url
782 | }
783 | if c.Invisible {
784 | req.Params["invisible"] = "1"
785 | }
786 | if c.Enterprise {
787 | req.Params["enterprise"] = "1"
788 | }
789 | if c.Version != "" {
790 | req.Params["version"] = c.Version
791 | }
792 | if c.Action != "" {
793 | req.Params["action"] = c.Action
794 | }
795 | if c.DataS != "" {
796 | req.Params["data-s"] = c.DataS
797 | }
798 | if c.Score != 0 {
799 | req.Params["min_score"] = strconv.FormatFloat(c.Score, 'f', -1, 64)
800 | }
801 |
802 | return req
803 | }
804 |
805 | func (c *Rotate) ToRequest() Request {
806 | req := Request{
807 | Params: map[string]string{"method": "rotatecaptcha"},
808 | Files: map[string]string{},
809 | }
810 | if c.File != "" {
811 | req.Files["file"] = c.File
812 | }
813 | if c.Files != nil {
814 | for i := 0; i < len(c.Files); i++ {
815 | name := "file_" + strconv.FormatInt(int64(i)+1, 10)
816 | req.Files[name] = c.Files[i]
817 | }
818 | }
819 | if c.Angle != 0 {
820 | req.Params["angle"] = strconv.FormatInt(int64(c.Angle), 10)
821 | }
822 | if c.Lang != "" {
823 | req.Params["lang"] = c.Lang
824 | }
825 | if c.HintText != "" {
826 | req.Params["textinstructions"] = c.HintText
827 | }
828 | if c.HintImageBase64 != "" {
829 | req.Params["imginstructions"] = c.HintImageBase64
830 | }
831 | if c.HintImageFile != "" {
832 | req.Files["imginstructions"] = c.HintImageFile
833 | }
834 | if c.Base64 != "" {
835 | req.Params["body"] = c.Base64
836 | }
837 | return req
838 | }
839 |
840 | func (c *Text) ToRequest() Request {
841 | req := Request{
842 | Params: map[string]string{"method": "post"},
843 | }
844 | if c.Text != "" {
845 | req.Params["textcaptcha"] = c.Text
846 | }
847 | if c.Lang != "" {
848 | req.Params["lang"] = c.Lang
849 | }
850 |
851 | return req
852 | }
853 |
854 | func (c *AmazonWAF) ToRequest() Request {
855 | req := Request{
856 | Params: map[string]string{"method": "amazon_waf"},
857 | }
858 |
859 | if c.Iv != "" {
860 | req.Params["iv"] = c.Iv
861 | }
862 |
863 | if c.SiteKey != "" {
864 | req.Params["sitekey"] = c.SiteKey
865 | }
866 |
867 | if c.Url != "" {
868 | req.Params["pageurl"] = c.Url
869 | }
870 |
871 | if c.Context != "" {
872 | req.Params["context"] = c.Context
873 | }
874 |
875 | if c.ChallengeScript != "" {
876 | req.Params["challenge_script"] = c.ChallengeScript
877 | }
878 |
879 | if c.CaptchaScript != "" {
880 | req.Params["captcha_script"] = c.CaptchaScript
881 | }
882 |
883 | return req
884 | }
885 |
886 | func (c *GeeTestV4) ToRequest() Request {
887 | req := Request{
888 | Params: map[string]string{"method": "geetest_v4"},
889 | }
890 | if c.CaptchaId != "" {
891 | req.Params["captcha_id"] = c.CaptchaId
892 | }
893 | if c.Url != "" {
894 | req.Params["pageurl"] = c.Url
895 | }
896 |
897 | return req
898 | }
899 |
900 | func (c *Lemin) ToRequest() Request {
901 | req := Request{
902 | Params: map[string]string{"method": "lemin"},
903 | }
904 |
905 | if c.CaptchaId != "" {
906 | req.Params["captcha_id"] = c.CaptchaId
907 | }
908 |
909 | if c.DivId != "" {
910 | req.Params["div_id"] = c.DivId
911 | } else {
912 | req.Params["div_id"] = "lemin-cropped-captcha"
913 | }
914 |
915 | if c.Url != "" {
916 | req.Params["pageurl"] = c.Url
917 | }
918 |
919 | if c.ApiServer != "" {
920 | req.Params["api_server"] = c.ApiServer
921 | }
922 | return req
923 | }
924 |
925 | func (c *CloudflareTurnstile) ToRequest() Request {
926 | req := Request{
927 | Params: map[string]string{"method": "turnstile"},
928 | }
929 |
930 | if c.SiteKey != "" {
931 | req.Params["sitekey"] = c.SiteKey
932 | }
933 | if c.Url != "" {
934 | req.Params["pageurl"] = c.Url
935 | }
936 | if c.Data != "" {
937 | req.Params["data"] = c.Data
938 | }
939 | if c.PageData != "" {
940 | req.Params["pagedata"] = c.PageData
941 | }
942 | if c.Action != "" {
943 | req.Params["action"] = c.Action
944 | }
945 | if c.UserAgent != "" {
946 | req.Params["userAgent"] = c.UserAgent
947 | }
948 |
949 | return req
950 | }
951 |
952 | func (c *CyberSiARA) ToRequest() Request {
953 | req := Request{
954 | Params: map[string]string{"method": "cybersiara"},
955 | }
956 |
957 | if c.MasterUrlId != "" {
958 | req.Params["master_url_id"] = c.MasterUrlId
959 | }
960 | if c.Url != "" {
961 | req.Params["pageurl"] = c.Url
962 | }
963 | if c.UserAgent != "" {
964 | req.Params["userAgent"] = c.UserAgent
965 | }
966 |
967 | return req
968 | }
969 |
970 | func (c *DataDome) ToRequest() Request {
971 | req := Request{
972 | Params: map[string]string{"method": "datadome"},
973 | }
974 |
975 | if c.CaptchaUrl != "" {
976 | req.Params["captcha_url"] = c.CaptchaUrl
977 | }
978 | if c.Url != "" {
979 | req.Params["pageurl"] = c.Url
980 | }
981 | if c.Proxytype != "" {
982 | req.Params["proxytype"] = c.Proxytype
983 | }
984 | if c.Proxy != "" {
985 | req.Params["proxy"] = c.Proxy
986 | }
987 | if c.UserAgent != "" {
988 | req.Params["userAgent"] = c.UserAgent
989 | }
990 |
991 | return req
992 | }
993 |
994 | func (c *MTCaptcha) ToRequest() Request {
995 | req := Request{
996 | Params: map[string]string{"method": "mt_captcha"},
997 | }
998 |
999 | if c.SiteKey != "" {
1000 | req.Params["sitekey"] = c.SiteKey
1001 | }
1002 | if c.Url != "" {
1003 | req.Params["pageurl"] = c.Url
1004 | }
1005 |
1006 | return req
1007 | }
1008 |
1009 | func (c *Yandex) ToRequest() Request {
1010 | req := Request{
1011 | Params: map[string]string{"method": "yandex"},
1012 | }
1013 |
1014 | if c.SiteKey != "" {
1015 | req.Params["sitekey"] = c.SiteKey
1016 | }
1017 | if c.Url != "" {
1018 | req.Params["pageurl"] = c.Url
1019 | }
1020 |
1021 | return req
1022 | }
1023 |
1024 | func (c *Friendly) ToRequest() Request {
1025 | req := Request{
1026 | Params: map[string]string{"method": "friendly_captcha"},
1027 | }
1028 |
1029 | if c.SiteKey != "" {
1030 | req.Params["sitekey"] = c.SiteKey
1031 | }
1032 | if c.Url != "" {
1033 | req.Params["pageurl"] = c.Url
1034 | }
1035 |
1036 | return req
1037 | }
1038 |
1039 | func (c *Tencent) ToRequest() Request {
1040 | req := Request{
1041 | Params: map[string]string{"method": "tencent"},
1042 | }
1043 | if c.AppId != "" {
1044 | req.Params["app_id"] = c.AppId
1045 | }
1046 | if c.Url != "" {
1047 | req.Params["pageurl"] = c.Url
1048 | }
1049 |
1050 | return req
1051 | }
1052 |
1053 | func (c *AtbCAPTCHA) ToRequest() Request {
1054 | req := Request{
1055 | Params: map[string]string{"method": "atb_captcha"},
1056 | }
1057 | if c.AppId != "" {
1058 | req.Params["app_id"] = c.AppId
1059 | }
1060 | if c.Url != "" {
1061 | req.Params["pageurl"] = c.Url
1062 | }
1063 | if c.ApiServer != "" {
1064 | req.Params["api_server"] = c.ApiServer
1065 | }
1066 |
1067 | return req
1068 | }
1069 |
1070 | func (c *CutCaptcha) ToRequest() Request {
1071 | req := Request{
1072 | Params: map[string]string{"method": "cutcaptcha"},
1073 | }
1074 | if c.MiseryKey != "" {
1075 | req.Params["misery_key"] = c.MiseryKey
1076 | }
1077 | if c.Url != "" {
1078 | req.Params["pageurl"] = c.Url
1079 | }
1080 | if c.DataApiKey != "" {
1081 | req.Params["api_key"] = c.DataApiKey
1082 | }
1083 |
1084 | return req
1085 | }
1086 |
1087 | func (c *Audio) ToRequest() Request {
1088 | req := Request{
1089 | Params: map[string]string{"method": "audio"},
1090 | }
1091 | if c.Base64 != "" {
1092 | req.Params["body"] = c.Base64
1093 | }
1094 | if c.Lang != "" {
1095 | req.Params["lang"] = c.Lang
1096 | }
1097 |
1098 | return req
1099 | }
1100 |
--------------------------------------------------------------------------------
/examples/AmazonWAFExample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | api2captcha "github.com/2captcha/2captcha-go"
6 | "os"
7 | )
8 |
9 | func main() {
10 | client := api2captcha.NewClient(os.Args[1])
11 |
12 | amazonWafCaptcha := api2captcha.AmazonWAF{
13 | SiteKey: "AQIDAHjcYu/GjX+QlghicBgQ/7bFaQZ+m5FKCMDnO+vTbNg96AF5H1K/siwSLK7RfstKtN5bAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglg",
14 | Url: "https://non-existent-example.execute-api.us-east-1.amazonaws.com",
15 | Iv: "test_iv",
16 | Context: "test_context",
17 | }
18 |
19 | req := amazonWafCaptcha.ToRequest()
20 |
21 | token, captchaId, err := client.Solve(req)
22 |
23 | fmt.Println("token ::: " + token)
24 | fmt.Println("captchaId ::: " + captchaId)
25 | fmt.Print("error ::: ")
26 | fmt.Println(err)
27 | }
28 |
--------------------------------------------------------------------------------
/examples/AtbCAPTCHAExample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | api2captcha "github.com/2captcha/2captcha-go"
6 | "os"
7 | )
8 |
9 | func main() {
10 | client := api2captcha.NewClient(os.Args[1])
11 |
12 | atbCaptcha := api2captcha.AtbCAPTCHA{
13 | AppId: "af23e041b22d000a11e22a230fa8991c",
14 | Url: "https://www.playzone.vip/",
15 | ApiServer: "https://cap.aisecurius.com",
16 | }
17 |
18 | req := atbCaptcha.ToRequest()
19 |
20 | token, captchaId, err := client.Solve(req)
21 |
22 | fmt.Println("token ::: " + token)
23 | fmt.Println("captchaId ::: " + captchaId)
24 | fmt.Print("error ::: ")
25 | fmt.Println(err)
26 | }
27 |
--------------------------------------------------------------------------------
/examples/AudioExample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/base64"
5 | "fmt"
6 | api2captcha "github.com/2captcha/2captcha-go"
7 | helper "github.com/2captcha/2captcha-go/examples/internal"
8 | "os"
9 | )
10 |
11 | func main() {
12 | client := api2captcha.NewClient(os.Args[1])
13 |
14 | assetsDir := helper.GetAssetsDir(os.Args[0])
15 |
16 | fileName := assetsDir + "/" + "audio-en.mp3"
17 |
18 | bs := helper.ReadFile2BiteSlice(fileName)
19 |
20 | if bs == nil {
21 | return
22 | }
23 |
24 | fileBase64Str := base64.StdEncoding.EncodeToString(bs)
25 |
26 | audio := api2captcha.Audio{
27 | Base64: fileBase64Str,
28 | Lang: "en",
29 | }
30 |
31 | req := audio.ToRequest()
32 |
33 | token, captchaId, err := client.Solve(req)
34 |
35 | fmt.Println("token ::: " + token)
36 | fmt.Println("captchaId ::: " + captchaId)
37 | fmt.Print("error ::: ")
38 | fmt.Println(err)
39 | }
40 |
--------------------------------------------------------------------------------
/examples/CanvasExample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | api2captcha "github.com/2captcha/2captcha-go"
6 | helper "github.com/2captcha/2captcha-go/examples/internal"
7 | "os"
8 | )
9 |
10 | func main() {
11 | client := api2captcha.NewClient(os.Args[1])
12 |
13 | assetsDir := helper.GetAssetsDir(os.Args[0])
14 | fileName := assetsDir + "/" + "canvas.jpg"
15 |
16 | canvasCaptcha := api2captcha.Canvas{
17 | File: fileName,
18 | HintText: "Draw around apple",
19 | }
20 |
21 | req := canvasCaptcha.ToRequest()
22 |
23 | token, captchaId, err := client.Solve(req)
24 |
25 | fmt.Println("token ::: " + token)
26 | fmt.Println("captchaId ::: " + captchaId)
27 | fmt.Print("error ::: ")
28 | fmt.Println(err)
29 | }
30 |
--------------------------------------------------------------------------------
/examples/CapyExample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | api2captcha "github.com/2captcha/2captcha-go"
6 | "os"
7 | )
8 |
9 | func main() {
10 | client := api2captcha.NewClient(os.Args[1])
11 |
12 | capy := api2captcha.Capy{
13 | SiteKey: "PUZZLE_Abc1dEFghIJKLM2no34P56q7rStu8v",
14 | Url: "https://www.mysite.com/captcha/",
15 | ApiServer: "https://jp.api.capy.me/",
16 | }
17 |
18 | req := capy.ToRequest()
19 |
20 | token, captchaId, err := client.Solve(req)
21 |
22 | fmt.Println("token ::: " + token)
23 | fmt.Println("captchaId ::: " + captchaId)
24 | fmt.Print("error ::: ")
25 | fmt.Println(err)
26 | }
27 |
--------------------------------------------------------------------------------
/examples/CloudflareTurnstileExample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | api2captcha "github.com/2captcha/2captcha-go"
6 | "os"
7 | )
8 |
9 | func main() {
10 | client := api2captcha.NewClient(os.Args[1])
11 |
12 | cloudflareTurnstile := api2captcha.CloudflareTurnstile{
13 | SiteKey: "0x4AAAAAAAChNiVJM_WtShFf",
14 | Url: "https://ace.fusionist.io",
15 | }
16 |
17 | req := cloudflareTurnstile.ToRequest()
18 |
19 | token, captchaId, err := client.Solve(req)
20 |
21 | fmt.Println("token ::: " + token)
22 | fmt.Println("captchaId ::: " + captchaId)
23 | fmt.Print("error ::: ")
24 | fmt.Println(err)
25 | }
26 |
--------------------------------------------------------------------------------
/examples/CoordinatesExample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | api2captcha "github.com/2captcha/2captcha-go"
6 | helper "github.com/2captcha/2captcha-go/examples/internal"
7 | "os"
8 | )
9 |
10 | func main() {
11 | client := api2captcha.NewClient(os.Args[1])
12 |
13 | assetsDir := helper.GetAssetsDir(os.Args[0])
14 | fileName := assetsDir + "/" + "grid.jpg"
15 |
16 | coordinates := api2captcha.Coordinates{
17 | File: fileName,
18 | }
19 |
20 | req := coordinates.ToRequest()
21 |
22 | token, captchaId, err := client.Solve(req)
23 |
24 | fmt.Println("token ::: " + token)
25 | fmt.Println("captchaId ::: " + captchaId)
26 | fmt.Print("error ::: ")
27 | fmt.Println(err)
28 | }
29 |
--------------------------------------------------------------------------------
/examples/CutCaptchaExample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | api2captcha "github.com/2captcha/2captcha-go"
6 | "os"
7 | )
8 |
9 | func main() {
10 | client := api2captcha.NewClient(os.Args[1])
11 |
12 | cutCaptcha := api2captcha.CutCaptcha{
13 | MiseryKey: "a1488b66da00bf332a1488993a5443c79047e752",
14 | Url: "https://filecrypt.co/Container/237D4D0995.html",
15 | DataApiKey: "SAb83IIB",
16 | }
17 |
18 | req := cutCaptcha.ToRequest()
19 |
20 | token, captchaId, err := client.Solve(req)
21 |
22 | fmt.Println("token ::: " + token)
23 | fmt.Println("captchaId ::: " + captchaId)
24 | fmt.Print("error ::: ")
25 | fmt.Println(err)
26 | }
27 |
--------------------------------------------------------------------------------
/examples/CyberSiARAExample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | api2captcha "github.com/2captcha/2captcha-go"
6 | "os"
7 | )
8 |
9 | func main() {
10 | client := api2captcha.NewClient(os.Args[1])
11 |
12 | cyberSiARA := api2captcha.CyberSiARA{
13 | MasterUrlId: "tpjOCKjjpdzv3d8Ub2E9COEWKt1vl1Mv",
14 | Url: "https://demo.mycybersiara.com/",
15 | UserAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36\"",
16 | }
17 |
18 | req := cyberSiARA.ToRequest()
19 |
20 | token, captchaId, err := client.Solve(req)
21 |
22 | fmt.Println("token ::: " + token)
23 | fmt.Println("captchaId ::: " + captchaId)
24 | fmt.Print("error ::: ")
25 | fmt.Println(err)
26 | }
27 |
--------------------------------------------------------------------------------
/examples/DataDomeExample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | api2captcha "github.com/2captcha/2captcha-go"
6 | "os"
7 | )
8 |
9 | func main() {
10 | client := api2captcha.NewClient(os.Args[1])
11 |
12 | dataDome := api2captcha.DataDome{
13 | CaptchaUrl: "https://geo.captcha-delivery.com/captcha/?initialCid=AHrlqAAA...P~XFrBVptk&t=fe&referer=https%3A%2F%2Fhexample.com&s=45239&e=c538be..c510a00ea",
14 | Url: "https://example.com/",
15 | Proxy: "username:password@1.2.3.4:5678",
16 | Proxytype: "http",
17 | UserAgent: "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Mobile Safari/537.3",
18 | }
19 |
20 | req := dataDome.ToRequest()
21 |
22 | token, captchaId, err := client.Solve(req)
23 |
24 | fmt.Println("token ::: " + token)
25 | fmt.Println("captchaId ::: " + captchaId)
26 | fmt.Print("error ::: ")
27 | fmt.Println(err)
28 | }
29 |
--------------------------------------------------------------------------------
/examples/FriendlyCaptchaExample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | api2captcha "github.com/2captcha/2captcha-go"
6 | "os"
7 | )
8 |
9 | func main() {
10 | client := api2captcha.NewClient(os.Args[1])
11 |
12 | friendlyCaptcha := api2captcha.Friendly{
13 | SiteKey: "FCMST5VUMCBOCGQ9",
14 | Url: "https://geizhals.de/455973138?fsean=5901747021356",
15 | }
16 |
17 | request := friendlyCaptcha.ToRequest()
18 |
19 | token, captchaId, err := client.Solve(request)
20 |
21 | fmt.Println("token ::: " + token)
22 | fmt.Println("captchaId ::: " + captchaId)
23 | fmt.Print("error ::: ")
24 | fmt.Println(err)
25 | }
26 |
--------------------------------------------------------------------------------
/examples/FriendlyExample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | api2captcha "github.com/2captcha/2captcha-go"
6 | "os"
7 | )
8 |
9 | func main() {
10 | client := api2captcha.NewClient(os.Args[1])
11 |
12 | friendly := api2captcha.Friendly{
13 | SiteKey: "FCMST5VUMCBOCGQ9",
14 | Url: "https://geizhals.de/455973138?fsean=5901747021356",
15 | }
16 |
17 | req := friendly.ToRequest()
18 |
19 | token, captchaId, err := client.Solve(req)
20 |
21 | fmt.Println("token ::: " + token)
22 | fmt.Println("captchaId ::: " + captchaId)
23 | fmt.Print("error ::: ")
24 | fmt.Println(err)
25 | }
26 |
--------------------------------------------------------------------------------
/examples/FunCaptchaExample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | api2captcha "github.com/2captcha/2captcha-go"
6 | "os"
7 | )
8 |
9 | func main() {
10 | client := api2captcha.NewClient(os.Args[1])
11 |
12 | funCaptcha := api2captcha.FunCaptcha{
13 | SiteKey: "69A21A01-CC7B-B9C6-0F9A-E7FA06677FFC",
14 | Url: "https://mysite.com/page/with/funcaptcha",
15 | }
16 |
17 | req := funCaptcha.ToRequest()
18 |
19 | token, captchaId, err := client.Solve(req)
20 |
21 | fmt.Println("token ::: " + token)
22 | fmt.Println("captchaId ::: " + captchaId)
23 | fmt.Print("error ::: ")
24 | fmt.Println(err)
25 | }
26 |
--------------------------------------------------------------------------------
/examples/GeeTestExample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | api2captcha "github.com/2captcha/2captcha-go"
6 | "os"
7 | )
8 |
9 | func main() {
10 | client := api2captcha.NewClient(os.Args[1])
11 |
12 | geeTest := api2captcha.GeeTest{
13 | GT: "f2ae6cadcf7886856696502e1d55e00c",
14 | Url: "https://www.mysite.com/captcha/",
15 | ApiServer: "api-na.geetest.com",
16 | Challenge: "12345678abc90123d45678ef90123a456b",
17 | }
18 |
19 | req := geeTest.ToRequest()
20 |
21 | token, captchaId, err := client.Solve(req)
22 |
23 | fmt.Println("token ::: " + token)
24 | fmt.Println("captchaId ::: " + captchaId)
25 | fmt.Print("error ::: ")
26 | fmt.Println(err)
27 | }
28 |
--------------------------------------------------------------------------------
/examples/GeeTestV4Example.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | api2captcha "github.com/2captcha/2captcha-go"
6 | "os"
7 | )
8 |
9 | func main() {
10 | client := api2captcha.NewClient(os.Args[1])
11 |
12 | geeTestV4 := api2captcha.GeeTestV4{
13 | CaptchaId: "72bf15796d0b69c43867452fea615052",
14 | Url: "https://mysite.com/captcha.html",
15 | Challenge: "12345678abc90123d45678ef90123a456b",
16 | ApiServer: "api-na.geetest.com",
17 | }
18 |
19 | req := geeTestV4.ToRequest()
20 |
21 | token, captchaId, err := client.Solve(req)
22 |
23 | fmt.Println("token ::: " + token)
24 | fmt.Println("captchaId ::: " + captchaId)
25 | fmt.Print("error ::: ")
26 | fmt.Println(err)
27 | }
28 |
--------------------------------------------------------------------------------
/examples/GridExample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | api2captcha "github.com/2captcha/2captcha-go"
6 | helper "github.com/2captcha/2captcha-go/examples/internal"
7 | "os"
8 | )
9 |
10 | func main() {
11 | client := api2captcha.NewClient(os.Args[1])
12 |
13 | assetsDir := helper.GetAssetsDir(os.Args[0])
14 | fileName := assetsDir + "/" + "grid.jpg"
15 |
16 | grid := api2captcha.Grid{
17 | File: fileName,
18 | }
19 |
20 | req := grid.ToRequest()
21 |
22 | token, captchaId, err := client.Solve(req)
23 |
24 | fmt.Println("token ::: " + token)
25 | fmt.Println("captchaId ::: " + captchaId)
26 | fmt.Print("error ::: ")
27 | fmt.Println(err)
28 | }
29 |
--------------------------------------------------------------------------------
/examples/KeyCaptchaExample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | api2captcha "github.com/2captcha/2captcha-go"
6 | "os"
7 | )
8 |
9 | func main() {
10 | client := api2captcha.NewClient(os.Args[1])
11 |
12 | keyCaptcha := api2captcha.KeyCaptcha{
13 | UserId: 10,
14 | SessionId: "493e52c37c10c2bcdf4a00cbc9ccd1e8",
15 | WebServerSign: "9006dc725760858e4c0715b835472f22",
16 | WebServerSign2: "2ca3abe86d90c6142d5571db98af6714",
17 | Url: "https://www.keycaptcha.ru/demo-magnetic/",
18 | }
19 |
20 | req := keyCaptcha.ToRequest()
21 |
22 | token, captchaId, err := client.Solve(req)
23 |
24 | fmt.Println("token ::: " + token)
25 | fmt.Println("captchaId ::: " + captchaId)
26 | fmt.Print("error ::: ")
27 | fmt.Println(err)
28 | }
29 |
--------------------------------------------------------------------------------
/examples/LeminExample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | api2captcha "github.com/2captcha/2captcha-go"
6 | "os"
7 | )
8 |
9 | func main() {
10 | client := api2captcha.NewClient(os.Args[1])
11 |
12 | lemin := api2captcha.Lemin{
13 | CaptchaId: "CROPPED_d3d4d56_73ca4008925b4f83a8bed59c2dd0df6d",
14 | Url: "https://www.site.com/page/",
15 | ApiServer: "api.leminnow.com",
16 | }
17 |
18 | req := lemin.ToRequest()
19 |
20 | token, captchaId, err := client.Solve(req)
21 |
22 | fmt.Println("token ::: " + token)
23 | fmt.Println("captchaId ::: " + captchaId)
24 | fmt.Print("error ::: ")
25 | fmt.Println(err)
26 | }
27 |
--------------------------------------------------------------------------------
/examples/MTCaptchaExample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | api2captcha "github.com/2captcha/2captcha-go"
6 | "os"
7 | )
8 |
9 | func main() {
10 | client := api2captcha.NewClient(os.Args[1])
11 |
12 | mtCaptcha := api2captcha.MTCaptcha{
13 | SiteKey: "MTPublic-KzqLY1cKH",
14 | Url: "https://2captcha.com/demo/mtcaptcha",
15 | }
16 |
17 | req := mtCaptcha.ToRequest()
18 |
19 | token, captchaId, err := client.Solve(req)
20 |
21 | fmt.Println("token ::: " + token)
22 | fmt.Println("captchaId ::: " + captchaId)
23 | fmt.Print("error ::: ")
24 | fmt.Println(err)
25 | }
26 |
--------------------------------------------------------------------------------
/examples/NormalExample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | api2captcha "github.com/2captcha/2captcha-go"
6 | helper "github.com/2captcha/2captcha-go/examples/internal"
7 | "os"
8 | )
9 |
10 | func main() {
11 | client := api2captcha.NewClient(os.Args[1])
12 |
13 | assetsDir := helper.GetAssetsDir(os.Args[0])
14 | fileName := assetsDir + "/" + "normal.jpg"
15 |
16 | normal := api2captcha.Normal{
17 | File: fileName,
18 | }
19 |
20 | req := normal.ToRequest()
21 |
22 | token, captchaId, err := client.Solve(req)
23 |
24 | fmt.Println("token ::: " + token)
25 | fmt.Println("captchaId ::: " + captchaId)
26 | fmt.Print("error ::: ")
27 | fmt.Println(err)
28 | }
29 |
--------------------------------------------------------------------------------
/examples/ReCaptchaExample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | api2captcha "github.com/2captcha/2captcha-go"
6 | "os"
7 | )
8 |
9 | func main() {
10 | client := api2captcha.NewClient(os.Args[1])
11 |
12 | reCaptcha := api2captcha.ReCaptcha{
13 | SiteKey: "6Le-wvkSVVABCPBMRTvw0Q4Muexq1bi0DJwx_mJ-",
14 | Url: "ttps://mysite.com/page/with/recaptcha",
15 | }
16 |
17 | req := reCaptcha.ToRequest()
18 |
19 | token, captchaId, err := client.Solve(req)
20 |
21 | fmt.Println("token ::: " + token)
22 | fmt.Println("captchaId ::: " + captchaId)
23 | fmt.Print("error ::: ")
24 | fmt.Println(err)
25 | }
26 |
--------------------------------------------------------------------------------
/examples/RotateExample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/base64"
5 | "fmt"
6 | api2captcha "github.com/2captcha/2captcha-go"
7 | helper "github.com/2captcha/2captcha-go/examples/internal"
8 | "os"
9 | )
10 |
11 | func main() {
12 | client := api2captcha.NewClient(os.Args[1])
13 |
14 | assetsDir := helper.GetAssetsDir(os.Args[0])
15 |
16 | fileName := assetsDir + "/" + "rotate.jpg"
17 |
18 | bs := helper.ReadFile2BiteSlice(fileName)
19 |
20 | if bs == nil {
21 | return
22 | }
23 |
24 | fileBase64Str := base64.StdEncoding.EncodeToString(bs)
25 |
26 | rotate := api2captcha.Rotate{
27 | Base64: fileBase64Str,
28 | }
29 |
30 | req := rotate.ToRequest()
31 |
32 | token, captchaId, err := client.Solve(req)
33 |
34 | fmt.Println("token ::: " + token)
35 | fmt.Println("captchaId ::: " + captchaId)
36 | fmt.Print("error ::: ")
37 | fmt.Println(err)
38 | }
39 |
--------------------------------------------------------------------------------
/examples/TencentExample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | api2captcha "github.com/2captcha/2captcha-go"
6 | "os"
7 | )
8 |
9 | func main() {
10 | client := api2captcha.NewClient(os.Args[1])
11 |
12 | tencentCaptcha := api2captcha.Tencent{
13 | AppId: "2092215077",
14 | Url: "http://lcec.lclog.cn/cargo/NewCargotracking?blno=BANR01XMHB0004&selectstate=BLNO",
15 | }
16 |
17 | req := tencentCaptcha.ToRequest()
18 |
19 | token, captchaId, err := client.Solve(req)
20 |
21 | fmt.Println("token ::: " + token)
22 | fmt.Println("captchaId ::: " + captchaId)
23 | fmt.Print("error ::: ")
24 | fmt.Println(err)
25 | }
26 |
--------------------------------------------------------------------------------
/examples/TextExample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | api2captcha "github.com/2captcha/2captcha-go"
6 | "os"
7 | )
8 |
9 | func main() {
10 | client := api2captcha.NewClient(os.Args[1])
11 |
12 | text := api2captcha.Text{
13 | Text: "If tomorrow is Saturday, what day is today?",
14 | }
15 |
16 | req := text.ToRequest()
17 |
18 | token, captchaId, err := client.Solve(req)
19 |
20 | fmt.Println("token ::: " + token)
21 | fmt.Println("captchaId ::: " + captchaId)
22 | fmt.Print("error ::: ")
23 | fmt.Println(err)
24 | }
25 |
--------------------------------------------------------------------------------
/examples/YandexExample.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | api2captcha "github.com/2captcha/2captcha-go"
6 | "os"
7 | )
8 |
9 | func main() {
10 | client := api2captcha.NewClient(os.Args[1])
11 |
12 | yandex := api2captcha.Yandex{
13 | SiteKey: "Y5Lh0tiycconMJGsFd3EbbuNKSp1yaZESUOIHfeV",
14 | Url: "https://rutube.ru",
15 | }
16 |
17 | req := yandex.ToRequest()
18 |
19 | token, captchaId, err := client.Solve(req)
20 |
21 | fmt.Println("token ::: " + token)
22 | fmt.Println("captchaId ::: " + captchaId)
23 | fmt.Print("error ::: ")
24 | fmt.Println(err)
25 | }
26 |
--------------------------------------------------------------------------------
/examples/assets/audio-en.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/2captcha/2captcha-go/da20509fedf9592b414601a2755bc4e41f0dc087/examples/assets/audio-en.mp3
--------------------------------------------------------------------------------
/examples/assets/canvas.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/2captcha/2captcha-go/da20509fedf9592b414601a2755bc4e41f0dc087/examples/assets/canvas.jpg
--------------------------------------------------------------------------------
/examples/assets/grid.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/2captcha/2captcha-go/da20509fedf9592b414601a2755bc4e41f0dc087/examples/assets/grid.jpg
--------------------------------------------------------------------------------
/examples/assets/normal.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/2captcha/2captcha-go/da20509fedf9592b414601a2755bc4e41f0dc087/examples/assets/normal.jpg
--------------------------------------------------------------------------------
/examples/assets/rotate.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/2captcha/2captcha-go/da20509fedf9592b414601a2755bc4e41f0dc087/examples/assets/rotate.jpg
--------------------------------------------------------------------------------
/examples/internal/Helper.go:
--------------------------------------------------------------------------------
1 | package internal
2 |
3 | import (
4 | "bufio"
5 | "fmt"
6 | "io"
7 | "log"
8 | "os"
9 | "path/filepath"
10 | )
11 |
12 | func GetAssetsDir(currentDir string) string {
13 | currentDir, err := filepath.Abs(filepath.Dir(currentDir))
14 | assetsDir := currentDir + "/assets"
15 |
16 | if err != nil {
17 | log.Fatal(err)
18 | }
19 | return assetsDir
20 | }
21 |
22 | func ReadFile2BiteSlice(fileName string) []byte {
23 |
24 | file, err := os.Open(fileName)
25 | if err != nil {
26 | fmt.Println(err)
27 | return nil
28 | }
29 | defer file.Close()
30 |
31 | stat, err := file.Stat()
32 | if err != nil {
33 | fmt.Println(err)
34 | return nil
35 | }
36 |
37 | bs := make([]byte, stat.Size())
38 | _, err = bufio.NewReader(file).Read(bs)
39 | if err != nil && err != io.EOF {
40 | fmt.Println(err)
41 | return nil
42 | }
43 | return bs
44 | }
45 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/2captcha/2captcha-go
2 |
3 | go 1.22.4
4 |
--------------------------------------------------------------------------------