Resolva reCAPTCHA Enterprise com Ruby

Por solvethree4 min de leitura

Use Net::HTTP do Ruby para criar uma tarefa reCAPTCHA Enterprise e consultar seu status até que esteja pronta ou falhe. O exemplo abaixo chama a API REST do solvethree diretamente; ele não exige um SDK Ruby.

Nesta página

Configure o site e o ambiente

  1. 1.

    Ative o perfil do site

    Configure o hostname de destino no console do solvethree e verifique se o perfil dele está ativo no seu espaço de trabalho. Enviar um hostname e uma ação não cria um perfil. Consulte a configuração de perfil de site.

  2. 2.

    Defina as variáveis de ambiente

    Defina SOLVETHREE_API_KEY com a chave de API do seu espaço de trabalho e SOLVETHREE_PROXY com a URL do proxy HTTP ou HTTPS que você também usará ao enviar o token ao destino. Mantenha a chave no servidor.

  3. 3.

    Altere os dados de entrada do exemplo

    Substitua accounts.example.com pelo hostname de destino — não por uma URL completa — e substitua login pela ação exigida por esse destino. A solicitação usa um único proxy; não adicione também proxyCandidates. Omita type e url. Omitir recaptchaType seleciona o padrão, enterprise-v3.

Salve o exemplo como solve.rb e execute-o com Ruby após definir essas variáveis. Ele carrega net/http, json e securerandom; JSON trata o corpo da solicitação e as respostas da API.

Crie uma única vez e consulte pelo ID da tarefa

Ruby · uma criação e consultas periódicas finitas
require 'net/http'
require 'json'
require 'securerandom'

api = 'https://api.solvethree.com/v1'
input = {site: 'accounts.example.com', action: 'login', proxy: ENV.fetch('SOLVETHREE_PROXY'), requestId: SecureRandom.uuid}
deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + 180
call = lambda do |method, path, body = nil|
  remaining = deadline - Process.clock_gettime(Process::CLOCK_MONOTONIC)
  raise 'Local deadline reached' if remaining <= 0
  uri = URI(api + path)
  request = method == :post ? Net::HTTP::Post.new(uri) : Net::HTTP::Get.new(uri)
  request['Authorization'] = 'Bearer ' + ENV.fetch('SOLVETHREE_API_KEY')
  request['Accept'] = 'application/json'
  if body
    request['Content-Type'] = 'application/json'
    request.body = JSON.generate(body)
  end
  # Net::HTTP's own proxy configuration is separate from input[:proxy].
  http = Net::HTTP.new(uri.hostname, uri.port, nil)
  http.use_ssl = uri.scheme == 'https'
  http.open_timeout = [10, remaining].min
  http.read_timeout = [25, remaining].min
  http.write_timeout = [25, remaining].min
  http.max_retries = 0
  response = http.request(request)
  raise "API HTTP #{response.code}" unless response.is_a?(Net::HTTPSuccess)
  JSON.parse(response.body)
end

task_id = nil
begin
  result = call.call(:post, '/tasks?waitMs=0', input)
  task_id = result.fetch('id')
  while %w[pending solving].include?(result.fetch('status'))
    result = call.call(:get, '/tasks/' + URI.encode_www_form_component(task_id) + '?waitMs=15000')
    sleep(1) if %w[pending solving].include?(result.fetch('status'))
  end
  raise "Task failed: #{result['errorCode']}" unless result['status'] == 'ready'
  puts "Ready task: #{task_id}"
  # Submit result['solution']['token'] with its userAgent/secChUa and original proxy.
rescue StandardError => error
  warn "Recovery requestId=#{input[:requestId]} taskId=#{task_id || 'unknown'}"
  raise error
end

O script envia uma única solicitação de criação, salva o ID da tarefa retornado e consulta essa tarefa enquanto seu status for pending ou solving. Apenas ready fornece uma solução utilizável. Toda resposta deve ter um status HTTP de sucesso antes que seu corpo seja interpretado como dados de sucesso.

HTTPS é habilitado explicitamente. As novas tentativas automáticas são desabilitadas, e os redirecionamentos são rejeitados pela verificação de status HTTP em vez de serem seguidos. O proxy no corpo da tarefa é usado na resolução; ele não configura a conexão do Ruby com a API do solvethree.

O prazo monotônico compartilhado dá às consultas um limite local de 180 segundos. Os tempos limite de conexão, leitura e escrita são limitados pelo tempo restante no início de cada solicitação. Trate esse limite como um limite de consulta, não como um temporizador de cancelamento rígido para uma solicitação em andamento. A documentação do Net::HTTP do Ruby descreve as configurações individuais de tempo limite.

Envie o token com sua identidade de navegador

O exemplo exibe o ID da tarefa pronta, não o token. Leia solution.token no resultado pronto e coloque-o no campo de token esperado pela solicitação ao destino. Não envie o ID da tarefa no lugar dele.

Use o valor retornado de solution.userAgent no cabeçalho User-Agent e o de solution.secChUa em Sec-CH-UA. Envie ao destino pretendido pelo mesmo proxy fornecido a esta tarefa. Não substitua a identidade retornada por cabeçalhos de um navegador sem relação com ela.

Uma tarefa pronta significa que o solvethree gerou uma solução. Verifique a resposta do destino separadamente para determinar se ele aceitou a solicitação da sua aplicação.

Trate falhas sem criar tarefas duplicadas

O script lança um erro HTTP da API.

Inspecione a resposta HTTP sem sucesso. Esse é um erro no nível da solicitação, não um resultado terminal da tarefa.

Experimente: Diagnostique essa resposta antes de tentar novamente. Não envie repetidamente dados de entrada inválidos sem alterá-los.

A tarefa chega ao status failed.

Inspecione tanto errorCode quanto error no resultado. A mensagem lançada pelo exemplo inclui apenas errorCode.

Experimente: Pare de consultar essa tarefa e corrija a causa informada. Resoluções com falha são reembolsadas; uma falha não significa necessariamente crédito insuficiente.

A criação excede o tempo limite antes de um ID de tarefa ser recebido.

Guarde o requestId de recuperação gravado na saída de erro padrão. Um tempo limite excedido não prova que a criação falhou.

Experimente: Recupere enviando a solicitação de tarefa idêntica com o mesmo ID de solicitação. Não basta executar o script novamente: uma nova execução gera um novo ID e pode criar outra tarefa.

A consulta atinge o prazo local ou perde a conexão.

Guarde o ID da tarefa e o ID da solicitação registrados no log.

Experimente: Consulte o ID da tarefa conhecida antes de criar outra tarefa. Uma exceção local não é um status terminal da tarefa.

Para permitir a recuperação após reinicializações do processo, guarde o ID da solicitação e os dados de entrada originais da tarefa antes de enviar o POST e, depois, guarde o ID da tarefa assim que ele for retornado. Reutilizar um ID de solicitação com dados de entrada idênticos retorna a tarefa existente; alterar os dados mantendo esse ID causa um conflito. Consulte tratamento de erros da API para a próxima etapa de diagnóstico.

Execute sua primeira tarefa.

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

Criar um espaço de trabalho
Resolva reCAPTCHA Enterprise com Ruby · solvethree