-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
twocaptcha.go
131 lines (113 loc) · 3.71 KB
/
twocaptcha.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package twocaptcha
import (
"errors"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strings"
"time"
)
var requestURL string = "https://2captcha.com/in.php"
var responseURL string = "https://2captcha.com/res.php"
//Client main
type Client struct {
APIKey string
Client *http.Client
}
//SolveImageCaptcha solve image captcha, return answer, id, error
func (c *Client) SolveImageCaptcha(base64Str string) (string, string, error) {
req := url.Values{}
req.Add("method", "base64")
req.Add("body", base64Str)
req.Add("soft_id", "2099")
id, err := c.sendRequest(req, requestURL, 20, 5*time.Second)
if err != nil {
return "", id, fmt.Errorf("SolveImageCaptcha Send New Request: [%s]", err.Error())
}
resp := url.Values{}
resp.Add("action", "get")
resp.Add("id", id)
result, err := c.sendRequest(resp, responseURL, 20, 5*time.Second)
if err != nil {
return "", id, fmt.Errorf("SolveImageCaptcha Send Request to Get Result: [%s]", err.Error())
}
return result, id, nil
}
//SolveRecaptchaV2 solve recaptcha v2, return answer, id, error
func (c *Client) SolveRecaptchaV2(siteURL, recaptchaKey string) (string, string, error) {
req := url.Values{}
req.Add("googlekey", recaptchaKey)
req.Add("pageurl", siteURL)
req.Add("method", "userrecaptcha")
req.Add("soft_id", "2099")
id, err := c.sendRequest(req, requestURL, 20, 5*time.Second)
if err != nil {
return "", id, fmt.Errorf("SolveRecaptchaV2 Send New Request: [%s]", err.Error())
}
resp := url.Values{}
resp.Add("id", id)
resp.Add("action", "get")
result, err := c.sendRequest(resp, responseURL, 20, 5*time.Second)
if err != nil {
return "", id, fmt.Errorf("SolveRecaptchaV2 Send Request to Get Result: [%s]", err.Error())
}
return result, id, nil
}
//ReportAnswer report answer
func (c *Client) ReportAnswer(isGood bool, id string) error {
req := url.Values{}
action := ""
if isGood {
action = "reportgood"
} else {
action = "reportbad"
}
req.Add("action", action)
req.Add("id", id)
resp, err := c.Client.Get(fmt.Sprintf("%s?key=%s&action=%s&id=%s", responseURL, c.APIKey, action, id))
if err != nil {
return fmt.Errorf("ReportAnswer Send New Request: [%s]", err.Error())
}
defer resp.Body.Close()
bodyContent, err := ioutil.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("ReportAnswer Read Response: [%s]", err.Error())
}
content := string(bodyContent)
if !strings.Contains(content, "OK_REPORT_RECORDED") {
return fmt.Errorf("ReportAnswer: Unknown Response [%s] Received", content)
}
return nil
}
func (c *Client) sendRequest(form url.Values, URL string, retry int, delay time.Duration) (string, error) {
if retry <= 0 {
return "", errors.New("Retry is 0")
}
if form.Get("key") == "" {
form.Add("key", c.APIKey)
} else {
time.Sleep(delay)
}
req, err := http.NewRequest("POST", URL, strings.NewReader(form.Encode()))
if err != nil {
return "", fmt.Errorf("Failed to initiate TwoCaptcha request, please try again. Error Message: %s", err.Error())
}
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
resp, err := c.Client.Do(req)
if err != nil {
return "", fmt.Errorf("Error encountered while sending TwoCaptcha request, please try again. Error Message: %s", err.Error())
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("Error encountered while reading TwoCaptcha response, please try again. Error Message: %s", err.Error())
}
resp.Body.Close()
stringBody := string(body)
if strings.Contains(stringBody, "OK|") { //Captcha Solved with answer
return string(body[3:]), nil
} else if strings.Contains(stringBody, "CAPCHA_NOT_READY") { //Captcha response not yet ready
return c.sendRequest(form, URL, retry-1, delay)
}
return "", fmt.Errorf("Error response from 2Captcha: %s", stringBody)
}