Use o SDK para Go em um servidor net/http

Por solvethree5 min de leitura

Crie um único cliente solvethree compartilhado, retorne o ID da tarefa de um POST autenticado e consulte seu status por um GET separado. Não chame Solve dentro do handler de criação: esta integração permite que o chamador aguarde o resultado sem manter a requisição original aberta.

Nesta página

Configure o servidor e o alvo

  1. 1.

    Instale o SDK Go

    Use Go 1.22 ou mais recente. Em um módulo Go inicializado, instale o SDK oficial com go get solvethree.com/[email protected]. Salve o exemplo abaixo como main.go.

  2. 2.

    Configure o ambiente do servidor

    Defina SOLVETHREE_API_KEY com a chave de API do seu espaço de trabalho e INTEGRATION_KEY com um segredo separado para os chamadores deste servidor interno. Defina CAPTCHA_SITE com o hostname de destino e SOLVETHREE_PROXY com a URL do proxy HTTP ou HTTPS usado na resolução. Mantenha as duas chaves em servidores confiáveis.

  3. 3.

    Prepare o alvo configurado

    Certifique-se de que o site tenha um perfil ativo disponível para seu espaço de trabalho; consulte a configuração de perfil de site. O exemplo fixa a ação em login. Altere-a para a ação esperada pelo alvo antes de executar o servidor. Fornecer um hostname e uma ação não cria um perfil.

Go net/http · criar e consultar tarefas
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())
}

Execute o módulo com go run .. O servidor escuta em 127.0.0.1:3000. Ele usa o roteador padrão net/http do Go, portanto não é necessário um framework. O cliente SDK é criado uma única vez e pode ser usado com segurança de forma concorrente.

A tarefa usa o modo padrão de reCAPTCHA enterprise-v3. Ela fornece um hostname de site, uma ação e um único proxy — não um type ou url. O corpo do POST não é usado, portanto os chamadores não podem selecionar alvos ou proxies arbitrários.

Faça um POST e guarde o ID da tarefa

Envie POST /captcha/tasks com o cabeçalho X-Integration-Key. Envie também um X-Request-ID gerado pelo chamador para recuperar a tarefa se a conexão terminar antes de você receber o ID dela. Use 1–64 letras ASCII, números, sublinhados ou hífens.

O handler valida a tarefa configurada e chama CreateTask com valor de espera zero. Ele solicita a criação da tarefa sem esperar a resolução terminar. Seu contexto de 20 segundos limita o tempo de espera desta requisição HTTP; não é um tempo limite de resolução.

Em caso de sucesso, o handler retorna o resultado da tarefa do SDK. Salve o ID da tarefa e use a rota GET para as verificações seguintes. Não interprete um POST bem-sucedido como um token utilizável.

As duas rotas exigem a chave de integração. Esta é uma interface interna confiável, não uma autorização por usuário: os chamadores que possuem essa chave compartilham o acesso pelo espaço de trabalho configurado.

Consulte a tarefa existente com GET até ela terminar

Envie GET /captcha/tasks/{id} com o mesmo cabeçalho de chave de integração. O handler chama apenas GetTask; ele nunca cria uma tarefa substituta. Ele solicita até 15 segundos de espera dentro de um contexto de requisição de 25 segundos.

  • pending ou solving: mantenha o mesmo ID de tarefa e consulte-a novamente.
  • ready: leia a solução. Este é o único status com um resultado utilizável.
  • failed: pare as consultas periódicas e inspecione errorCode e error. Corrija a causa antes de decidir se deve criar outra tarefa.

Confira o status da resposta HTTP antes de decodificar um resultado de tarefa bem-sucedido. Neste servidor, requisições não autorizadas retornam 401, dados de tarefa inválidos retornam 400 e erros de requisição do SDK retornam 502. Uma tarefa retornada com status failed é um resultado diferente de uma falha na requisição HTTP.

Recupere uma requisição que excedeu o tempo limite sem criar outra resolução

Um tempo limite excedido não prova que a criação falhou. Cancelar o contexto da requisição interrompe a espera local, não a tarefa remota. O SDK nunca repete automaticamente o POST de criação.

  1. 1.

    Se você tem um ID de tarefa, consulte a tarefa

    Use a rota GET com esse ID. Em caso de erros do SDK, a resposta de erro JSON do exemplo inclui taskId e requestId quando o SDK os disponibiliza.

  2. 2.

    Se você só tem o ID da requisição, repita a criação original

    Envie o POST novamente com o mesmo X-Request-ID e sem alterar os dados da tarefa. Isso significa manter o hostname, a ação e o proxy configurados sem alterações. O mesmo ID de requisição e a mesma requisição de tarefa recuperam a tarefa existente; dados diferentes com esse ID geram conflito.

  3. 3.

    Guarde o ID antes da primeira requisição

    O SDK gera um ID de requisição quando nenhum é fornecido, mas um chamador desconectado pode nunca recebê-lo. Escolher e guardar X-Request-ID antes do POST evita depender da resposta de erro para a recuperação.

Use o resultado pronto com o mesmo proxy

Este servidor retorna o resultado; o SDK não o envia ao alvo. Seu código de envio deve usar o token, a identidade de navegador retornada em userAgent e secChUa e o proxy que teve sucesso. Neste exemplo com um único proxy, continue usando o proxy configurado em vez de trocar de IP após a resolução.

Uma tarefa ready significa que uma solução foi gerada, não que o alvo aceitou a requisição da sua aplicação. Se o envio falhar, inspecione o token enviado, a identidade, o proxy e a requisição ao alvo antes de pagar por outra resolução.

Execute sua primeira tarefa.

Comece com $5 em créditos no espaço de trabalho.

Criar um espaço de trabalho
Use o SDK para Go em um servidor net/http · solvethree