Utiliser le SDK Go dans un serveur net/http

Par solvethree5 min de lecture

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. 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 sous main.go.

  2. 2.

    Configurer l’environnement serveur

    Définissez SOLVETHREE_API_KEY sur la clé API de votre espace de travail et INTEGRATION_KEY sur un secret distinct pour les appelants de ce serveur interne. Définissez CAPTCHA_SITE sur le nom d’hôte cible et SOLVETHREE_PROXY sur l’URL du proxy HTTP ou HTTPS utilisé pour la résolution. Conservez les deux clés sur des serveurs de confiance.

  3. 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.

Go net/http · créer et récupérer des tâches
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.

  • pending ou solving : 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 examinez errorCode et error. 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. 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 taskId et requestId lorsque le SDK les expose.

  2. 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-ID et 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. 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-ID avant 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.

Lancez votre première tâche.

Démarrez avec $5 de crédit dans votre espace de travail.

Créer un espace de travail
Utiliser le SDK Go dans un serveur net/http · solvethree