Вызывайте сервис решения из обработчика маршрута Next.js

Автор: solvethree4 мин на чтение

Используйте серверный обработчик 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. Используйте его как серверный маршрут, выполняемый при запросе, а не как статически генерируемый ресурс.

app/api/captcha/route.js · обработчик маршрута Node.js
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. 1.

    Свяжите создаваемую задачу с вызывающим пользователем

    После создания задачи аутентифицированным POST-запросом сохраните её ID с привязкой к аутентифицированному пользователю или арендатору, прежде чем вернуть его. Также свяжите логический requestId с этим владельцем, чтобы при восстановлении не потерять запись о принадлежности задачи.

  2. 2.

    Проверяйте владельца перед получением задачи

    При GET аутентифицируйте вызывающего пользователя и проверьте переданный ID по записи о владельце перед вызовом getTask. Отклоняйте ID задач, которые не принадлежат вызывающему пользователю, и возвращайте результаты только после успешной проверки.

Оставьте site, action и proxy под контролем сервера, если приложение явно не разрешает вызывающим пользователям выбирать их. Фиксированные значения окружения в этом примере не позволяют клиенту менять эти входные данные.

Опрашивайте ту же задачу и восстанавливайте запросы с неопределённым исходом

  1. 1.

    Продолжайте опрос задач, не достигших конечного состояния

    При pending или solving повторно запрашивайте тот же ID с учётом общего предельного времени ожидания в приложении. Завершение ожидания GET не является поводом создавать новую задачу.

  2. 2.

    Останавливайтесь при ready или failed

    Только ready содержит пригодное для использования решение. При failed прекратите опрос и проверьте errorCode и error; средства за неудачные решения возвращаются. Обрабатывайте неуспешные HTTP-ответы, прежде чем интерпретировать ответ как задачу. Обработчик catch в маршруте не заменяет проверку возвращённого статуса задачи.

  3. 3.

    Восстановите создание задачи после тайм-аута соединения

    Выберите и сохраните x-request-id перед POST. Если вы получили ID задачи, запросите её. Если ответ на создание был потерян, повторите POST с тем же ID запроса и неизменными входными данными задачи, чтобы получить существующую задачу. ID запроса допускает 1–64 символа: буквы ASCII, цифры, подчёркивания или дефисы; повторное использование ID с другими входными данными приводит к конфликту.

Статус ready означает, что solvethree сгенерировал решение, а не то, что целевой сайт его принял. SDK не отправляет его за вас. При отправке используйте возвращённые userAgent и secChUa вместе с прокси, через который решение было получено, — в этом примере это единственный настроенный прокси. Не переключайтесь на другую идентификацию браузера или IP.

При ошибках запросов или конечных сбоях обратитесь к справочнику ошибок API, прежде чем оплачивать ещё одно решение. Повторная отправка неизменных некорректных данных не исправит их.

Запустите первую задачу.

Начните с $5 на балансе рабочего пространства.

Создать рабочее пространство
Вызывайте сервис решения из обработчика маршрута Next.js · solvethree