@gabriellb438/nestjs-capsolver
v1.0.1
Published
Integração tipada da API CapSolver com NestJS para reCAPTCHA, Cloudflare Turnstile e CAPTCHA de imagem.
Maintainers
Readme
CapSolver para NestJS — @gabriellb438/nestjs-capsolver
Integração nativa, tipada e segura da API do CapSolver com NestJS. Resolva
reCAPTCHA v2, reCAPTCHA v3, Cloudflare Turnstile e CAPTCHA de imagem em
aplicações Node.js e TypeScript, com polling automático, cancelamento por
AbortSignal e erros especializados.
Use este pacote somente em sites, aplicações e fluxos nos quais você tenha autorização para automatizar a resolução de CAPTCHA.
Recursos
- Configuração síncrona com
forRoot()ou assíncrona comforRootAsync(). - Compatibilidade com módulos globais do NestJS.
- Tipos TypeScript para tarefas, soluções, respostas e opções da API.
- Suporte tipado a reCAPTCHA v2/v3, reCAPTCHA Enterprise, Cloudflare Turnstile e ImageToText.
- Polling automático para tarefas assíncronas com limites configuráveis.
- Retorno imediato para tarefas concluídas de forma síncrona.
- Cancelamento de requisições e polling com
AbortSignal. - Timeouts de requisição e classes de erro específicas.
- Extensão tipada para novos tipos de tarefa do CapSolver.
- Builds ESM e CommonJS, com declarações de tipos incluídas.
Compatibilidade
| Tecnologia | Versão | | --- | --- | | Node.js | 20.11 ou superior | | NestJS | 11 ou 12 | | TypeScript | Tipos incluídos no pacote |
O projeto usa o fetch nativo do Node.js, portanto não exige um cliente HTTP
adicional.
Instalação
Com pnpm:
pnpm add @gabriellb438/nestjs-capsolverCom npm:
npm install @gabriellb438/nestjs-capsolverCom Yarn:
yarn add @gabriellb438/nestjs-capsolverConfiguração
Defina sua chave do CapSolver em uma variável de ambiente:
CAPSOLVER_CLIENT_KEY=sua-chave-aquiConfiguração direta
Use forRoot() quando as opções já estiverem disponíveis durante a criação do
módulo:
import { Module } from '@nestjs/common';
import { CapsolverModule } from '@gabriellb438/nestjs-capsolver';
@Module({
imports: [
CapsolverModule.forRoot({
clientKey: process.env.CAPSOLVER_CLIENT_KEY!,
isGlobal: true,
}),
],
})
export class AppModule {}Configuração assíncrona recomendada
Com @nestjs/config, use forRootAsync() para validar e injetar a chave sem
gravá-la no código-fonte:
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { CapsolverModule } from '@gabriellb438/nestjs-capsolver';
@Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
CapsolverModule.forRootAsync({
isGlobal: true,
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
clientKey: config.getOrThrow<string>('CAPSOLVER_CLIENT_KEY'),
requestTimeoutMs: 30_000,
pollIntervalMs: 3_000,
pollTimeoutMs: 300_000,
maxPollAttempts: 100,
}),
}),
],
})
export class AppModule {}Opções do módulo
| Opção | Tipo | Padrão | Descrição |
| --- | --- | --- | --- |
| clientKey | string | Obrigatória | Chave da conta CapSolver consumidora. |
| isGlobal | boolean | false | Torna o módulo global no NestJS. |
| baseUrl | string | https://api.capsolver.com | Substitui o endpoint em testes ou ambientes controlados. |
| requestTimeoutMs | number | 30000 | Timeout individual de cada chamada HTTP. |
| pollIntervalMs | number | 3000 | Intervalo entre consultas do resultado. |
| pollTimeoutMs | number | 300000 | Tempo total de polling; máximo de cinco minutos. |
| maxPollAttempts | number | 100 | Número máximo de consultas; limite de 120. |
Uso
Injete CapsolverService em qualquer provider do NestJS. O método solve()
cria a tarefa, retorna imediatamente quando a solução já está pronta ou faz o
polling até a conclusão.
Resolver reCAPTCHA v2
import { Injectable } from '@nestjs/common';
import {
CapsolverService,
type RecaptchaSolution,
} from '@gabriellb438/nestjs-capsolver';
@Injectable()
export class CaptchaService {
constructor(private readonly capsolver: CapsolverService) {}
async resolveRecaptcha(): Promise<string> {
const result = await this.capsolver.solve<RecaptchaSolution>({
type: 'ReCaptchaV2TaskProxyLess',
websiteURL: 'https://www.google.com/recaptcha/api2/demo',
websiteKey: 'SITE_KEY',
});
return result.solution.gRecaptchaResponse;
}
}Resolver Cloudflare Turnstile
import type { TurnstileSolution } from '@gabriellb438/nestjs-capsolver';
const result = await capsolver.solve<TurnstileSolution>({
type: 'AntiTurnstileTaskProxyLess',
websiteURL: 'https://example.com',
websiteKey: '0x4...',
metadata: {
action: 'login',
},
});
console.log(result.solution.token);Converter CAPTCHA de imagem em texto
O campo body deve conter somente a imagem em Base64, sem o prefixo de data
URI, como data:image/png;base64,.
import type { ImageToTextSolution } from '@gabriellb438/nestjs-capsolver';
const result = await capsolver.solve<ImageToTextSolution>({
type: 'ImageToTextTask',
body: imageBase64,
});
console.log(result.solution.text);Tipos de tarefa incluídos
| Categoria | Valores aceitos em task.type |
| --- | --- |
| reCAPTCHA v2 | ReCaptchaV2TaskProxyLess, ReCaptchaV2Task |
| reCAPTCHA v2 Enterprise | ReCaptchaV2EnterpriseTaskProxyLess, ReCaptchaV2EnterpriseTask |
| reCAPTCHA v3 | ReCaptchaV3TaskProxyLess, ReCaptchaV3Task |
| reCAPTCHA v3 Enterprise | ReCaptchaV3EnterpriseTaskProxyLess, ReCaptchaV3EnterpriseTask |
| Cloudflare Turnstile | AntiTurnstileTaskProxyLess |
| CAPTCHA de imagem | ImageToTextTask |
A biblioteca exporta tipos TypeScript que abrangem todos os valores acima.
Usar um novo tipo de tarefa
Você não precisa aguardar uma nova versão da biblioteca quando o CapSolver
adicionar outro tipo de tarefa. Use CustomCapsolverTask para preservar a
tipagem dos campos:
import type { CustomCapsolverTask } from '@gabriellb438/nestjs-capsolver';
type FutureTask = CustomCapsolverTask<
'FutureTaskProxyLess',
{ websiteURL: string; websiteKey: string }
>;
const task: FutureTask = {
type: 'FutureTaskProxyLess',
websiteURL: 'https://example.com',
websiteKey: 'SITE_KEY',
};
await capsolver.solve(task);API pública
| Método | Finalidade |
| --- | --- |
| getBalance(signal?) | Consulta o saldo e os pacotes da conta consumidora. |
| createTask(task, options?) | Cria uma tarefa, inclui o appId do pacote e aceita callbackUrl. |
| getTaskResult(taskId, signal?) | Consulta o estado de uma tarefa assíncrona. |
| waitForTask(taskId, options?) | Faz polling de uma tarefa existente dentro dos limites configurados. |
| solve(task, options?) | Cria a tarefa e aguarda automaticamente até a solução ficar pronta. |
| getToken(task, options?) | Usa o endpoint direto /getToken e inclui o appId do pacote. |
Todos os métodos retornam Promises e possuem respostas tipadas. solve(),
waitForTask() e getToken() retornam CapsolverReadyResult<TSolution> quando
a tarefa é concluída.
Cancelamento
As chamadas HTTP e os fluxos de polling aceitam um AbortSignal:
const controller = new AbortController();
const resultPromise = capsolver.solve(task, {
signal: controller.signal,
});
// Cancele quando a requisição deixar de ser necessária.
controller.abort();
await resultPromise;Tratamento de erros
A biblioteca exporta classes específicas que podem ser tratadas em filtros de exceção ou na camada de aplicação:
| Erro | Situação |
| --- | --- |
| CapsolverError | Classe-base dos erros específicos da biblioteca. |
| CapsolverApiError | A API retornou errorId maior que zero. |
| CapsolverHttpError | O endpoint respondeu com status HTTP inválido. |
| CapsolverRequestTimeoutError | Uma chamada HTTP excedeu o timeout configurado. |
| CapsolverPollingTimeoutError | A tarefa excedeu o tempo ou o número de tentativas de polling. |
| CapsolverTaskFailedError | A API marcou a tarefa como failed. |
| CapsolverProtocolError | A resposta não contém JSON ou estrutura válida. |
| CapsolverConfigurationError | A configuração ou a tarefa informada é inválida. |
Exemplo:
import {
CapsolverApiError,
CapsolverPollingTimeoutError,
} from '@gabriellb438/nestjs-capsolver';
try {
const result = await capsolver.solve(task);
return result.solution;
} catch (error) {
if (error instanceof CapsolverApiError) {
console.error(error.errorCode, error.message);
}
if (error instanceof CapsolverPollingTimeoutError) {
console.error(error.taskId, error.attempts);
}
throw error;
}Por segurança, os erros não incluem a clientKey nem o corpo integral da
requisição.
Segurança e uso responsável
- Armazene
CAPSOLVER_CLIENT_KEYem variáveis de ambiente ou em um gerenciador de segredos. - Nunca envie a chave ao navegador ou a exponha em logs.
- Configure timeouts compatíveis com o ciclo de vida da sua aplicação.
- Use a integração somente em sistemas autorizados e de acordo com os termos do CapSolver e dos serviços envolvidos.
Desenvolvimento
pnpm install
pnpm validate
pnpm pack:checkpnpm validate executa lint, verificação de tipos, testes e build.
Palavras-chave
NestJS CapSolver, CapSolver API NestJS, integração CAPTCHA NestJS, resolver CAPTCHA Node.js, CAPTCHA solver TypeScript, reCAPTCHA v2 NestJS, reCAPTCHA v3 NestJS, reCAPTCHA Enterprise, Cloudflare Turnstile NestJS, AntiTurnstile, ImageToText CAPTCHA, polling CapSolver e automação CAPTCHA autorizada.
Licença
Este projeto é disponibilizado sob a CapSolver App ID License 1.0. Você pode
usar, clonar, modificar e redistribuir o código desde que todas as requisições
à API do CapSolver preservem o appId definido pelo autor. Consulte o arquivo
LICENSE para conhecer todos os termos.
