Utiliser le SDK Go dans un serveur net/http
Créez un seul client solvethree partagé, renvoyez l’identifiant de tâche depuis une requête POST authentifiée et récupérez son statut via une requête GET distincte. N’appelez pas Solve dans le gestionnaire de création : cette intégration permet à l’appelant d’attendre le résultat sans maintenir la requête d’origine ouverte.
Sur cette page
Configurez le serveur et la cible
- 1.
Installez le SDK Go
Utilisez Go 1.22 ou une version ultérieure. Dans un module Go initialisé, installez le SDK officiel avec
go get solvethree.com/[email protected]. Enregistrez l’exemple ci-dessous sousmain.go. - 2.
Configurer l’environnement serveur
Définissez
SOLVETHREE_API_KEYsur la clé API de votre espace de travail etINTEGRATION_KEYsur un secret distinct pour les appelants de ce serveur interne. DéfinissezCAPTCHA_SITEsur le nom d’hôte cible etSOLVETHREE_PROXYsur l’URL du proxy HTTP ou HTTPS utilisé pour la résolution. Conservez les deux clés sur des serveurs de confiance. - 3.
Préparez la cible configurée
Assurez-vous que le site dispose d’un profil actif accessible à votre espace de travail ; consultez la configuration des profils de site. L’exemple fixe l’action à
login. Remplacez-la par l’action attendue par votre cible avant de lancer le serveur. Fournir un nom d’hôte et une action ne crée pas de profil.
package main
import (
"context"
"encoding/json"
"errors"
"log"
"net/http"
"os"
"time"
solvethree "solvethree.com/sdk"
)
func main() {
client, err := solvethree.NewClient(os.Getenv("SOLVETHREE_API_KEY"), nil)
if err != nil { log.Fatal(err) }
secret := os.Getenv("INTEGRATION_KEY")
if secret == "" { log.Fatal("Set INTEGRATION_KEY") }
authorize := func(w http.ResponseWriter, r *http.Request) bool {
if r.Header.Get("X-Integration-Key") != secret { http.Error(w, "Unauthorized", 401); return false }
return true
}
respond := func(w http.ResponseWriter, result *solvethree.TaskResult, err error) {
w.Header().Set("Content-Type", "application/json")
if err != nil {
var recovery *solvethree.Error
w.WriteHeader(http.StatusBadGateway)
ids := map[string]string{"error": "Solver request failed"}
if errors.As(err, &recovery) { ids["requestId"] = recovery.RequestID; ids["taskId"] = recovery.TaskID }
_ = json.NewEncoder(w).Encode(ids)
return
}
_ = json.NewEncoder(w).Encode(result)
}
mux := http.NewServeMux()
mux.HandleFunc("POST /captcha/tasks", func(w http.ResponseWriter, r *http.Request) {
if !authorize(w,r) { return }
input := solvethree.TaskRequest{Site: os.Getenv("CAPTCHA_SITE"), Action:"login",
Proxy:os.Getenv("SOLVETHREE_PROXY"), RequestID:r.Header.Get("X-Request-ID")}
if err := input.Validate(); err != nil { http.Error(w,"Invalid task input",400);return }
ctx,cancel := context.WithTimeout(r.Context(),20*time.Second);defer cancel()
zero:=0
result,err:=client.CreateTask(ctx,input,&zero)
respond(w,result,err)
})
mux.HandleFunc("GET /captcha/tasks/{id}", func(w http.ResponseWriter, r *http.Request) {
if !authorize(w,r) { return }
ctx,cancel:=context.WithTimeout(r.Context(),25*time.Second);defer cancel()
result,err:=client.GetTask(ctx,r.PathValue("id"),15000)
respond(w,result,err)
})
server:=&http.Server{Addr:"127.0.0.1:3000", Handler:mux, ReadHeaderTimeout:5*time.Second}
log.Fatal(server.ListenAndServe())
}Exécutez le module avec go run .. Le serveur écoute sur 127.0.0.1:3000. Il utilise le routeur standard net/http de Go ; aucun framework n’est donc nécessaire. Le client SDK est créé une seule fois et peut être utilisé simultanément en toute sécurité.
La tâche utilise le mode reCAPTCHA par défaut enterprise-v3. Elle fournit un nom d’hôte de site, une action et un seul proxy, et non un type ou une url. Le corps du POST n’est pas utilisé ; les appelants ne peuvent donc pas sélectionner des cibles ou des proxys arbitraires.
Envoyez un POST et conservez l’identifiant de tâche
Envoyez POST /captcha/tasks avec l’en-tête X-Integration-Key. Envoyez également un X-Request-ID généré par l’appelant afin de pouvoir récupérer la tâche si la connexion se termine avant la réception de son identifiant. Utilisez 1–64 lettres ASCII, chiffres, traits de soulignement ou traits d’union.
Le gestionnaire valide la tâche configurée, puis appelle CreateTask avec une valeur d’attente nulle. Il demande la création de la tâche sans attendre la fin de la résolution. Son contexte de 20 secondes limite la durée d’attente de cette requête HTTP ; ce n’est pas un délai maximal de résolution.
En cas de réussite, le gestionnaire renvoie le résultat de tâche du SDK. Enregistrez son identifiant de tâche et utilisez la route GET pour les vérifications suivantes. Ne considérez pas un POST réussi comme un jeton utilisable.
Les deux routes nécessitent la clé d’intégration. Il s’agit d’une interface interne de confiance, et non d’une autorisation par utilisateur : les appelants détenant cette clé partagent l’accès via l’espace de travail configuré.
Récupérez la tâche existante par GET jusqu’à sa fin
Envoyez GET /captcha/tasks/{id} avec le même en-tête de clé d’intégration. Le gestionnaire appelle uniquement GetTask ; il ne crée jamais de tâche de remplacement. Il demande jusqu’à 15 secondes d’attente dans un contexte de requête de 25 secondes.
pendingousolving: conservez le même identifiant de tâche et récupérez-la à nouveau.ready: lisez la solution. C’est le seul statut contenant un résultat utilisable.failed: arrêtez les interrogations et examinezerrorCodeeterror. Corrigez la cause avant de décider de créer une autre tâche.
Vérifiez le statut de la réponse HTTP avant de décoder un résultat de tâche réussi. Dans ce serveur, les requêtes non autorisées renvoient 401, les paramètres de tâche non valides renvoient 400 et les erreurs de requête du SDK renvoient 502. Une tâche renvoyée avec le statut failed est un résultat différent d’un échec de requête HTTP.
Récupérez une tâche après un dépassement de délai sans lancer une autre résolution
Un dépassement de délai ne prouve pas que la création a échoué. L’annulation du contexte de requête arrête l’attente locale, pas la tâche distante. Le SDK ne réessaie jamais automatiquement le POST de création.
- 1.
Si vous avez un identifiant de tâche, récupérez la tâche
Utilisez la route GET avec cet identifiant. En cas d’erreur du SDK, la réponse d’erreur JSON de l’exemple inclut
taskIdetrequestIdlorsque le SDK les expose. - 2.
Si vous n’avez que l’identifiant de requête, rejouez la création d’origine
Renvoyez le POST avec le même
X-Request-IDet des paramètres de tâche inchangés. Cela implique de conserver le nom d’hôte, l’action et le proxy configurés. Le même identifiant de requête et la même requête de tâche permettent de récupérer la tâche existante ; des paramètres différents avec cet identifiant provoquent un conflit. - 3.
Conservez l’identifiant avant la première requête
Le SDK génère un identifiant de requête si aucun n’est fourni, mais un appelant déconnecté peut ne jamais le recevoir. Choisir et conserver
X-Request-IDavant le POST évite de dépendre de la réponse d’erreur pour la récupération.
Utilisez le résultat prêt avec le même proxy
Ce serveur renvoie le résultat ; le SDK ne l’envoie pas à la cible. Votre code d’envoi doit utiliser le jeton, l’identité de navigateur userAgent et secChUa renvoyée, ainsi que le proxy ayant permis la résolution. Dans cet exemple à proxy unique, continuez à utiliser le proxy configuré plutôt que de changer d’adresse IP après la résolution.
Une tâche ready signifie qu’une solution a été générée, et non que la cible a accepté la requête de votre application. Si l’envoi échoue, examinez le jeton envoyé, l’identité, le proxy et la requête cible avant de payer une autre résolution.
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.