Use o Guzzle com a API de tarefas de CAPTCHA
Use Guzzle 7 para criar uma tarefa e depois consultar seu ID periodicamente até que ela esteja em ready ou failed. Guarde o requestId se algo der errado: um timeout de conexão não prova que a criação da tarefa falhou.
Esta é uma integração REST, não um SDK oficial de PHP.
Nesta página
Prepare a requisição de reCAPTCHA
- Instale Guzzle 7 com Composer. O comando de instalação aparece no início do exemplo.
- Defina SOLVETHREE_API_KEY como a chave da API do seu workspace e SOLVETHREE_PROXY como a URL do proxy. Mantenha a chave no servidor.
- Crie um perfil ativo para seu site de destino no console antes de solicitar uma resolução. Veja a configuração do perfil do site.
- Substitua accounts.example.com e login pelo hostname e pela ação de destino. O campo site recebe um hostname, não uma URL completa.
O exemplo solicita reCAPTCHA Enterprise v3, o recaptchaType padrão. Não adicione os campos type ou url. Ele fornece um proxy; se você usar proxyCandidates em vez disso, omita proxy por completo.
Crie uma vez e depois consulte periodicamente dentro de um limite fixo de tempo
<?php
// composer require guzzlehttp/guzzle:^7
require __DIR__.'/vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client([
'base_uri' => 'https://api.solvethree.com/v1/',
'headers' => ['Authorization' => 'Bearer '.getenv('SOLVETHREE_API_KEY'), 'Accept' => 'application/json'],
'allow_redirects' => false,
'http_errors' => false,
]);
$input = ['site' => 'accounts.example.com', 'action' => 'login',
'proxy' => getenv('SOLVETHREE_PROXY'), 'requestId' => bin2hex(random_bytes(16))];
$deadline = microtime(true) + 180;
$call = function (string $method, string $path, array $options = []) use ($client, $deadline): array {
$remaining = $deadline - microtime(true);
if ($remaining <= 0) throw new RuntimeException('Local deadline reached');
$response = $client->request($method, $path, $options + ['timeout' => min(25, $remaining), 'connect_timeout' => min(10, $remaining)]);
if ($response->getStatusCode() < 200 || $response->getStatusCode() >= 300) {
throw new RuntimeException('API HTTP '.$response->getStatusCode());
}
return json_decode((string)$response->getBody(), true, 512, JSON_THROW_ON_ERROR);
};
$id = null;
try {
$result = $call('POST', 'tasks?waitMs=0', ['json' => $input]);
$id = $result['id'];
while (in_array($result['status'], ['pending', 'solving'], true)) {
$result = $call('GET', 'tasks/'.rawurlencode($id).'?waitMs=15000');
if (in_array($result['status'], ['pending', 'solving'], true)) usleep(1000000);
}
if ($result['status'] !== 'ready') {
throw new RuntimeException('Task failed: '.($result['errorCode'] ?? 'unknown'));
}
echo 'Ready task: '.$id.PHP_EOL;
// Submit $result['solution']['token'] with userAgent/secChUa and the same proxy.
} catch (Throwable $error) {
fwrite(STDERR, 'Recovery requestId='.$input['requestId'].' taskId='.($id ?? 'unknown').PHP_EOL);
throw $error;
}O cliente se autentica com uma chave Bearer. Seu base_uri termina em /v1/, e os caminhos das requisições são relativos, preservando esse prefixo da API. A opção json do Guzzle envia a entrada da tarefa como JSON.
O helper faz um único POST de criação. Em seguida, consulta periodicamente o ID da tarefa retornado enquanto o status for pending ou solving. A criação e as consultas compartilham um limite de 180 segundos; cada chamada HTTP é limitada ao tempo restante, com timeouts máximos de requisição e conexão de 25 e 10 segundos, respectivamente. Uma nova consulta não reinicia o limite total de tempo.
Os redirecionamentos estão desativados. Definir http_errors como false permite que o helper verifique explicitamente respostas fora da faixa 2xx antes de decodificar um conteúdo de sucesso; isso não suprime erros de conexão nem timeouts.
- Uma resposta HTTP fora da faixa 2xx lança um erro HTTP da API. Analise o status e o corpo da resposta em vez de tratá-la como uma resolução que falhou.
- Uma tarefa no estado terminal failed encerra as consultas. O exemplo lança seu errorCode; examine também o campo error da tarefa para ver a mensagem de diagnóstico. Resoluções que falham são reembolsadas.
- Somente ready contém uma solução utilizável. A linha “Ready task” impressa informa que a tarefa está pronta, não que foi aceita pelo site de destino.
Recupere uma requisição que excedeu o tempo limite sem pagar por outra tarefa
Guarde o requestId gerado e a entrada exata da tarefa antes de enviar o POST. O bloco catch imprime requestId e, se a criação tiver retornado um, taskId. Essa saída ajuda na recuperação, mas não substitui salvar a requisição antes de enviá-la.
- 1.
Se você tem um ID de tarefa, consulte essa tarefa
Use GET /v1/tasks/:id para verificar seu status. Atingir o prazo local do helper não comprova que a tarefa remota falhou.
- 2.
Se a criação excedeu o tempo limite sem retornar um ID, recupere-a com requestId
Envie a mesma requisição de tarefa com o requestId salvo. Entradas correspondentes retornam a tarefa existente; entradas diferentes com esse ID causam conflito.
- 3.
Não execute o script novamente como atalho de recuperação
Cada execução gera um novo requestId. Não adicione uma nova tentativa automática de POST que gere outro ID e não repita cegamente uma entrada inválida sem alterá-la.
Envie o token pelo mesmo proxy
O exemplo para antes de contatar o destino. Envie solution.token — não o ID da tarefa — e use os valores retornados de solution.userAgent e solution.secChUa como os cabeçalhos User-Agent e Sec-CH-UA da requisição de destino.
O proxy dentro do JSON da tarefa informa ao solvethree qual proxy usar na resolução. Ele não configura a conexão do Guzzle com a API nem sua requisição posterior ao destino. Configure a requisição de destino separadamente para usar esse mesmo proxy.
Use um cliente separado para a requisição de destino, para que o cabeçalho Authorization padrão do cliente da API não seja enviado ao site. Mantenha juntos o token, a identidade de navegador retornada, o proxy e o destino pretendido. Um token pronto ainda pode ser rejeitado se a requisição subsequente não corresponder.
Fontes e referência da API
Execute sua primeira tarefa.
Comece com $5 em créditos no espaço de trabalho.