Résoudre reCAPTCHA Enterprise avec Go
Installez solvethree.com/sdk et appelez Solve avec votre nom d’hôte cible, l’action et le proxy. Le SDK crée la tâche une seule fois et interroge périodiquement son résultat. Votre application envoie ensuite le jeton à la cible.
Sur cette page
Installer et configurer le SDK
Utilisez Go 1.22+. Dans votre module Go, exécutez :
go get solvethree.com/sdk@v0.1.0- Définissez
SOLVETHREE_API_KEYsur la clé API de votre espace de travail etSOLVETHREE_PROXYsur l’URL de votre proxy HTTP(S). Conservez ces deux valeurs dans la configuration du serveur. - Créez un profil actif pour le nom d’hôte cible dans votre espace de travail. Consultez la configuration du profil de site.
- Remplacez
accounts.example.cometloginpar le nom d’hôte et l’action utilisés par votre cible.Siteaccepte un nom d’hôte, sans schéma ni chemin.
Résoudre une tâche
Enregistrez ce code dans main.go et exécutez go run ..
package main
import (
"context"
"fmt"
"log"
"os"
"time"
solvethree "solvethree.com/sdk"
)
func main() {
client, err := solvethree.NewClient(os.Getenv("SOLVETHREE_API_KEY"), nil)
if err != nil { log.Fatal(err) }
ctx, cancel := context.WithTimeout(context.Background(), 180*time.Second)
defer cancel()
input := solvethree.TaskRequest{Site: "accounts.example.com", Action: "login", Proxy: os.Getenv("SOLVETHREE_PROXY")}
result, err := client.Solve(ctx, input, solvethree.SolveOptions{})
if err != nil { log.Fatal(err) }
fmt.Println("Ready task:", result.ID)
// Submit result.Solution.Token with its browser identity and original proxy.
}Le contexte limite l’attente locale à 180 secondes. Solve renvoie un TaskResult prêt ou une erreur ; il n’est pas nécessaire de l’entourer d’une autre boucle d’interrogation. Cette requête utilise le mode Enterprise v3 par défaut. Pour la version v3 standard, définissez RecaptchaType: "v3". Ne renseignez pas Type ni URL pour reCAPTCHA.
Envoyer le jeton à votre cible
Envoyez result.Solution.Token dans le champ CAPTCHA de l’application. La valeur result.ID affichée identifie la tâche ; ce n’est pas le jeton.
Utilisez result.Solution.UserAgent comme User-Agent et result.Solution.SecChUA comme sec-ch-ua. Faites passer la requête cible par le proxy ayant permis la résolution, sélectionné avec solvethree.SuccessfulProxy(input, result).
Incluez les autres champs de formulaire, les cookies et la valeur CSRF de l’application, puis vérifiez sa réponse. Le SDK renvoie une solution ; il n’envoie pas la requête à l’application à votre place.
Conserver les identifiants si l’attente est interrompue
L’annulation du contexte arrête l’attente locale, pas le travail distant. *solvethree.Error expose RequestID et TaskID. Récupérez une tâche connue avec GetTask ; si sa création est incertaine, renvoyez exactement les paramètres d’origine avec le même RequestID.
Pour permettre la récupération après un redémarrage du processus, attribuez et enregistrez RequestID avec les paramètres de la tâche avant sa création. Une erreur *TaskFailedError est définitive : examinez son ErrorCode et récupérez la tâche pour obtenir le texte de l’erreur. Corrigez la cause avant de lancer une autre résolution.
Alternative : appeler l’API REST avec la bibliothèque standard
Si vous préférez gérer les appels HTTP vous-même, cette version utilise directement net/http. Choisissez cette version ou l’exemple avec le SDK ci-dessus ; exécuter les deux crée deux tâches. Les structures de réponse présentées ici sont propres à cet exemple autonome ; leurs noms de champs diffèrent donc de ceux des types du SDK.
package main
import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"os"
"time"
)
type Task struct {
ID string `json:"id"`
Status string `json:"status"`
ErrorCode string `json:"errorCode"`
Error string `json:"error"`
Solution struct {
Token string `json:"token"`
UserAgent string `json:"userAgent"`
SecChUa string `json:"secChUa"`
} `json:"solution"`
}
func main() {
key, proxy := os.Getenv("SOLVETHREE_API_KEY"), os.Getenv("SOLVETHREE_PROXY")
if key == "" || proxy == "" { panic("Set SOLVETHREE_API_KEY and SOLVETHREE_PROXY") }
ctx, cancel := context.WithTimeout(context.Background(), 180*time.Second)
defer cancel()
client := &http.Client{Timeout: 30*time.Second}
api := func(method, path string, body []byte) (Task, error) {
var task Task
req, err := http.NewRequestWithContext(ctx, method, "https://api.solvethree.com/v1"+path, bytes.NewReader(body))
if err != nil { return task, err }
req.Header.Set("Authorization", "Bearer "+key)
req.Header.Set("Content-Type", "application/json")
response, err := client.Do(req)
if err != nil { return task, err }
defer response.Body.Close()
if response.StatusCode < 200 || response.StatusCode >= 300 { return task, fmt.Errorf("API HTTP %d", response.StatusCode) }
err = json.NewDecoder(response.Body).Decode(&task)
return task, err
}
requestID := fmt.Sprintf("go-%d", time.Now().UnixNano())
body, err := json.Marshal(map[string]string{
"site":"accounts.example.com", "action":"login", "proxy":proxy, "requestId":requestID,
})
if err != nil { panic(err) }
// Persist requestID and body before creation if this must survive a restart.
task, err := api(http.MethodPost, "/tasks?waitMs=0", body)
if err != nil { panic(fmt.Errorf("request %s: %w", requestID, err)) }
for task.Status == "pending" || task.Status == "solving" {
task, err = api(http.MethodGet, "/tasks/"+url.PathEscape(task.ID)+"?waitMs=15000", nil)
if err != nil { panic(err) }
if task.Status == "pending" || task.Status == "solving" {
select { case <-ctx.Done(): panic(ctx.Err()); case <-time.After(time.Second): }
}
}
if task.Status != "ready" { panic("Task failed: "+task.ErrorCode+": "+task.Error) }
solution := task.Solution
_ = solution // Apply token and returned browser identity using the same proxy.
fmt.Println("Ready task:", task.ID)
}Sources et référence de l’API
Lancez votre première tâche.
Démarrez avec $5 de crédit dans votre espace de travail.