Вызывайте сервис решения из обработчика маршрута Next.js
Используйте серверный обработчик POST, чтобы создать задачу один раз, а затем получать её через GET по ID. Храните ключ solvethree на сервере; браузер не должен напрямую обращаться к сервису решения или создавать новую задачу при каждом истечении времени ожидания.
На этой странице
Настройте сервер и профиль сайта
- Используйте Node.js 22+ и официальный JavaScript SDK. Выполните установку по URL пакета, как описано в документации; не предполагайте, что пакет доступен в реестре npm.
- Задайте SOLVETHREE_API_KEY, CAPTCHA_SITE, SOLVETHREE_PROXY и INTEGRATION_KEY в окружении сервера. Не добавляйте префикс NEXT_PUBLIC_ ни к одному из двух секретов.
- Перед вызовом маршрута активируйте в рабочем пространстве профиль для целевого имени хоста. Установка CAPTCHA_SITE не создаёт профиль; см. настройку профиля сайта.
- Замените действие login из примера на действие, необходимое вашей интеграции. Запрос использует один прокси и по умолчанию выбирает reCAPTCHA Enterprise v3; поля type и url не нужны.
Добавьте обработчик создания и получения задачи
Поместите пример в app/api/captcha/route.js. Он экспортирует HTTP-обработчики App Router и явно выбирает среду выполнения Node.js для SDK. Используйте его как серверный маршрут, выполняемый при запросе, а не как статически генерируемый ресурс.
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 вызывает createTask с waitMs: 0, поэтому возвращает ответ с задачей, не дожидаясь решения. Сохраните полученный ID задачи. GET требует этот существующий ID и вызывает getTask; он никогда не создаёт задачу.
GET запрашивает ожидание до 15 секунд с отдельным прерыванием запроса через 25 секунд. POST прерывает запрос через 20 секунд. Эти ограничения действуют на каждый запрос, а не на время жизни задачи.
Проверяйте права доступа к каждой задаче перед её возвратом
Для доступа из браузера используйте полноценную серверную аутентификацию вашего приложения, а не распространяйте INTEGRATION_KEY. Одной аутентификации недостаточно: если принимать любой ID задачи от аутентифицированного пользователя, он всё равно сможет запросить чужой результат.
- 1.
Свяжите создаваемую задачу с вызывающим пользователем
После создания задачи аутентифицированным POST-запросом сохраните её ID с привязкой к аутентифицированному пользователю или арендатору, прежде чем вернуть его. Также свяжите логический requestId с этим владельцем, чтобы при восстановлении не потерять запись о принадлежности задачи.
- 2.
Проверяйте владельца перед получением задачи
При GET аутентифицируйте вызывающего пользователя и проверьте переданный ID по записи о владельце перед вызовом getTask. Отклоняйте ID задач, которые не принадлежат вызывающему пользователю, и возвращайте результаты только после успешной проверки.
Оставьте site, action и proxy под контролем сервера, если приложение явно не разрешает вызывающим пользователям выбирать их. Фиксированные значения окружения в этом примере не позволяют клиенту менять эти входные данные.
Опрашивайте ту же задачу и восстанавливайте запросы с неопределённым исходом
- 1.
Продолжайте опрос задач, не достигших конечного состояния
При pending или solving повторно запрашивайте тот же ID с учётом общего предельного времени ожидания в приложении. Завершение ожидания GET не является поводом создавать новую задачу.
- 2.
Останавливайтесь при ready или failed
Только ready содержит пригодное для использования решение. При failed прекратите опрос и проверьте errorCode и error; средства за неудачные решения возвращаются. Обрабатывайте неуспешные HTTP-ответы, прежде чем интерпретировать ответ как задачу. Обработчик catch в маршруте не заменяет проверку возвращённого статуса задачи.
- 3.
Восстановите создание задачи после тайм-аута соединения
Выберите и сохраните x-request-id перед POST. Если вы получили ID задачи, запросите её. Если ответ на создание был потерян, повторите POST с тем же ID запроса и неизменными входными данными задачи, чтобы получить существующую задачу. ID запроса допускает 1–64 символа: буквы ASCII, цифры, подчёркивания или дефисы; повторное использование ID с другими входными данными приводит к конфликту.
Статус ready означает, что solvethree сгенерировал решение, а не то, что целевой сайт его принял. SDK не отправляет его за вас. При отправке используйте возвращённые userAgent и secChUa вместе с прокси, через который решение было получено, — в этом примере это единственный настроенный прокси. Не переключайтесь на другую идентификацию браузера или IP.
При ошибках запросов или конечных сбоях обратитесь к справочнику ошибок API, прежде чем оплачивать ещё одно решение. Повторная отправка неизменных некорректных данных не исправит их.
Источники и справочник API
Запустите первую задачу.
Начните с $5 на балансе рабочего пространства.