Skip to content

Commit

Permalink
made kasada actually work
Browse files Browse the repository at this point in the history
  • Loading branch information
ghaph committed Feb 8, 2023
1 parent d9b027c commit 98433c9
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 64 deletions.
163 changes: 100 additions & 63 deletions acmethods.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,67 @@ func antiCaptchaMethods(solver *Solver, preferredDomain string) *solveMethods {
return int(taskId.(float64)), nil
}

// parseResponse returns should continue, solution, error
parseResponse := func(body map[string]interface{}) (bool, *Solution, error) {
errMsg, hasError := body["errorDescription"]
if hasError && errMsg != nil {
return false, nil, errors.New(errMsg.(string))
}

status := body["status"]

switch status {
case "processing":
return true, nil, nil
case "ready":
solution, hasSolution := body["solution"].(map[string]interface{})
if !hasSolution {
return false, nil, errors.New("no solution")
}

// response can either be gRecaptchaResponse or token
response := solution["gRecaptchaResponse"]

if response == nil {
response = solution["token"]
}

if response == nil {
response = solution["x-kpsdk-ct"]
}

if response == nil {
if solver.Verbose {
fmt.Println(body)
}

return false, nil, errors.New("no solution text")
}

ip := ""
cost := ""

rIP, hasIP := body["ip"]
if hasIP && rIP != nil {
ip = rIP.(string)
}

rCost, hasCost := body["cost"]
if hasCost && rCost != nil {
cost = rCost.(string)
}

return false, &Solution{
Text: response.(string),
RawSolution: solution,
IP: ip,
Cost: cost,
}, nil
default:
return false, nil, errors.New("unknown status")
}
}

// keeps retrying until it has returned error or solved
getResponse := func(taskId int) (*Solution, error) {
for {
Expand All @@ -84,64 +145,17 @@ func antiCaptchaMethods(solver *Solver, preferredDomain string) *solveMethods {
continue
}

errMsg, hasError := body["errorDescription"]
if hasError && errMsg != nil {
return nil, errors.New(errMsg.(string))
shouldContinue, sol, err := parseResponse(body)
if err != nil {
return nil, err
}

status := body["status"]

switch status {
case "processing":
if shouldContinue {
continue
case "ready":
solution, hasSolution := body["solution"].(map[string]interface{})
if !hasSolution {
return nil, errors.New("no solution")
}

// response can either be gRecaptchaResponse or token
response := solution["gRecaptchaResponse"]

if response == nil {
response = solution["token"]
}

if response == nil {
response = solution["x-kpsdk-ct"]
}

if response == nil {
if solver.Verbose {
fmt.Println(body)
}

return nil, errors.New("no solution text")
}

ip := ""
cost := ""

rIP, hasIP := body["ip"]
if hasIP && rIP != nil {
ip = rIP.(string)
}

rCost, hasCost := body["cost"]
if hasCost && rCost != nil {
cost = rCost.(string)
}

return &Solution{
TaskId: taskId,
Text: response.(string),
RawSolution: solution,
IP: ip,
Cost: cost,
}, nil
default:
return nil, errors.New("unknown status")
}

sol.TaskId = taskId
return sol, nil
}
}

Expand Down Expand Up @@ -328,24 +342,47 @@ func antiCaptchaMethods(solver *Solver, preferredDomain string) *solveMethods {
// kasada method
if solver.service == CapSolver {
methods.Kasada = func(o KasadaOptions) (*KasadaSolution, error) {
if o.Proxy == nil {
return nil, errors.New("proxy is required")
}

taskData := map[string]interface{}{
"type": "AntiKasadaTask",
"pageURL": o.PageURL,
"cd": o.DetailedCD,
"onlyCD": o.OnlyCD,
"version": o.Version,
"userAgent": o.UserAgent,
"pageURL": o.PageURL,
"cd": o.DetailedCD,
"onlyCD": o.OnlyCD,
}

if o.Proxy != nil {
taskData["proxy"] = o.Proxy.String()
applyProxy(taskData, o.Proxy, "AntiKasadaTask")

if o.Version != "" {
taskData["version"] = o.Version
}

if o.UserAgent != "" {
taskData["userAgent"] = o.UserAgent
}

sol, err := createResponse(taskData)
// send request to /kasada/invoke
payload := map[string]interface{}{
"clientKey": solver.ApiKey,
"task": taskData,
"appId": "B7E57F27-0AD3-434D-A5B7-CF9EE7D093EF",
}

body, err := postJSON(domain()+"/kasada/invoke", payload)
if err != nil {
return nil, err
}

_, sol, err := parseResponse(body)
if err != nil {
return nil, err
}

if sol == nil {
return nil, errors.New("no solution")
}

kpsdkCD := ""
kpsdkCT := ""
userAgent := ""
Expand Down
5 changes: 4 additions & 1 deletion captchas.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,12 @@ type FunCaptchaOptions struct {
Data string
}

// KasadaOptions Make sure to set the proxy as its required
type KasadaOptions struct {
PageURL string
Proxy *Proxy

// Proxy is required
Proxy *Proxy

// DetailedCD Enable if you need more detailed x-kpsdk-cd, including params such as duration, st and rst
DetailedCD bool
Expand Down
10 changes: 10 additions & 0 deletions proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ func NewProxy(t ProxyType, address string, port int, login *ProxyLogon) *Proxy {
}
}

// String only returns the proxy address and port
func (p *Proxy) String() string {
if p == nil {
return ""
Expand All @@ -64,6 +65,15 @@ func (p *Proxy) String() string {
return p.login.String() + p.address + ":" + strconv.Itoa(p.port)
}

// FullString returns the proxy address, port and type
func (p *Proxy) FullString() string {
if p == nil {
return ""
}

return p.pType + "://" + p.login.String() + p.address + ":" + strconv.Itoa(p.port)
}

func (pl *ProxyLogon) String() string {
if pl == nil {
return ""
Expand Down

0 comments on commit 98433c9

Please sign in to comment.