Llama al servicio de resolución desde un Route Handler de Next.js
Usa un controlador POST del lado del servidor para crear la tarea una sola vez y luego recuperarla por su ID mediante GET. Mantén la clave de solvethree en el servidor; el navegador no debe llamar directamente al servicio de resolución ni crear otra tarea cada vez que venza una espera.
En esta página
Configura el servidor y el perfil del sitio
- Usa Node.js 22+ y el SDK oficial de JavaScript. Sigue la instalación mediante la URL del paquete indicada en la documentación; no des por hecho que hay un paquete disponible en el registro npm.
- Define SOLVETHREE_API_KEY, CAPTCHA_SITE, SOLVETHREE_PROXY e INTEGRATION_KEY en el entorno del servidor. No añadas el prefijo NEXT_PUBLIC_ a ninguno de los dos secretos.
- Activa un perfil para el nombre de host de destino en tu espacio de trabajo antes de llamar a la ruta. Definir CAPTCHA_SITE no crea un perfil; consulta la configuración del perfil del sitio.
- Sustituye la acción login del ejemplo por la acción que requiere tu integración. La solicitud usa un único proxy y, de forma predeterminada, reCAPTCHA Enterprise v3; no necesita los campos type ni url.
Añade el controlador de creación y recuperación
Coloca el ejemplo en app/api/captcha/route.js. Exporta controladores HTTP de App Router y selecciona explícitamente el entorno de ejecución de Node.js para el SDK. Mantenlo como una ruta de servidor que se ejecuta al recibir solicitudes, no como un recurso generado estáticamente.
import { Solvethree, SolvethreeError } from '@solvethree/sdk';
export const runtime = 'nodejs';
const client = new Solvethree({ apiKey: process.env.SOLVETHREE_API_KEY });
function authorized(request) {
const key = process.env.INTEGRATION_KEY;
return Boolean(key) && request.headers.get('x-integration-key') === key;
}
function failure(error) {
return error instanceof SolvethreeError
? Response.json({ requestId: error.requestId, taskId: error.taskId }, { status: 502 })
: Response.json({ error: 'Invalid task input or ID' }, { status: 400 });
}
export async function POST(request) {
if (!authorized(request)) return new Response('Unauthorized', { status: 401 });
try {
return Response.json(await client.createTask({
site: process.env.CAPTCHA_SITE, action: 'login', proxy: process.env.SOLVETHREE_PROXY,
requestId: request.headers.get('x-request-id') ?? undefined,
}, { waitMs: 0, signal: AbortSignal.timeout(20000) }));
} catch (error) { return failure(error); }
}
export async function GET(request) {
if (!authorized(request)) return new Response('Unauthorized', { status: 401 });
const id = new URL(request.url).searchParams.get('id');
if (!id) return Response.json({ error: 'Provide id' }, { status: 400 });
try {
return Response.json(await client.getTask(id, { waitMs: 15000, signal: AbortSignal.timeout(25000) }));
} catch (error) { return failure(error); }
}POST llama a createTask con waitMs: 0, por lo que devuelve la respuesta de la tarea sin esperar una solución. Guarda el ID de tarea devuelto. GET requiere ese ID existente y llama a getTask; nunca crea una tarea.
GET solicita una espera de hasta 15 segundos, con una cancelación independiente de la solicitud a los 25 segundos. POST cancela la solicitud a los 20 segundos. Estos límites se aplican a cada solicitud, no a la duración de la tarea.
Autoriza el acceso a cada tarea antes de devolverla
Para el acceso desde el navegador, usa la autenticación real del lado del servidor de tu aplicación en lugar de distribuir INTEGRATION_KEY. La autenticación por sí sola no basta: aceptar cualquier ID de tarea de un usuario autenticado seguiría permitiéndole solicitar el resultado de otra persona.
- 1.
Asocia la creación con quien realiza la solicitud
Después de que un POST autenticado cree una tarea, guarda su ID asociado al usuario o tenant autenticado antes de devolverlo. Asocia también el requestId lógico con ese propietario, para que la recuperación no pierda el registro de propiedad.
- 2.
Comprueba la propiedad antes de recuperar la tarea
En GET, autentica a quien realiza la solicitud y comprueba el ID proporcionado con ese registro de propiedad antes de llamar a getTask. Rechaza los ID que no le pertenezcan y devuelve los resultados solo después de superar esa comprobación.
Mantén el sitio, la acción y el proxy bajo el control del servidor, salvo que tu aplicación autorice explícitamente a quienes realizan las solicitudes a elegirlos. Los valores fijos del entorno en este ejemplo impiden que el cliente cambie esas entradas.
Consulta la misma tarea y recupera las solicitudes de resultado incierto
- 1.
Sigue consultando las tareas que no estén en un estado terminal
Para pending o solving, vuelve a recuperar el mismo ID, respetando el plazo global de tu aplicación. Que termine una espera de GET no es motivo para crear otra tarea.
- 2.
Detente en ready o failed
Solo ready contiene una solución utilizable. En failed, deja de consultar y revisa errorCode y error; las resoluciones fallidas se reembolsan. Gestiona las respuestas HTTP no satisfactorias antes de interpretar una respuesta como una tarea. El bloque catch de la ruta no sustituye la comprobación del estado de la tarea devuelta.
- 3.
Recupera la creación tras agotar el tiempo de conexión
Elige y conserva un x-request-id antes de POST. Si recibiste un ID de tarea, recupérala. Si se perdió la respuesta de creación, repite POST con el mismo ID de solicitud y las mismas entradas de la tarea para recuperar la tarea existente. Los ID de solicitud admiten entre 1 y 64 letras ASCII, números, guiones bajos o guiones; reutilizar uno con entradas diferentes genera un conflicto.
Una tarea en ready significa que solvethree ha generado una solución, no que el destino la haya aceptado. El SDK no la envía por ti. Al enviarla, usa los valores userAgent y secChUa devueltos junto con el proxy con el que se obtuvo la solución: el proxy configurado en este ejemplo de un único proxy. No cambies a una identidad de navegador o una IP ajenas.
Para errores de solicitud o fallos terminales, consulta la referencia de errores de la API antes de pagar otra resolución. Reintentar con entradas no válidas sin modificarlas no las corregirá.
Fuentes y referencia de la API
Ejecuta tu primera tarea.
Empieza con $5 de crédito en tu espacio de trabajo.