ExpressでCAPTCHAソルバーを使用する
solvethreeクライアントはExpressサーバー上に配置してください。認証付きのPOSTルートでタスクを作成し、GETルートで取得します。対象とプロキシはサーバー設定で固定し、呼び出し元がエンドポイントを任意の有料リレーとして利用できないようにしてください。
このページの内容
サーバーと対象を設定する
Node.js 22以降とExpress 5を使用してください。公式JavaScript SDKはnpmレジストリで公開されていると想定せず、ドキュメントに記載されたtarballによるインストール方法でインストールしてください。この例では、ハンドラーの外でSolvethreeクライアントを1つ作成します。
SOLVETHREE_API_KEY:ワークスペースのAPIキー。サーバー側で保持してください。INTEGRATION_KEY:信頼できる内部の呼び出し元向けの、別個のシークレットです。この例ではx-integration-keyヘッダーでの送信が必須です。ブラウザークライアントには配布しないでください。認証ミドルウェアがすでにある場合は、この例の共有キーによるガードではなく、そちらを使用してください。CAPTCHA_SITE:完全なURLではなく、対象のホスト名です。タスクを作成する前に、ワークスペースで有効なサイトプロファイルを設定してください。ホスト名を送信してもプロファイルは作成されません。SOLVETHREE_PROXY:この対象に使用するプロキシです。この例では単一のプロキシを指定し、アクションをloginに固定します。対象で別のアクションを使用する場合は、サーバー側で変更してください。
このリクエストはデフォルトのreCAPTCHA Enterprise設定を使用します。必要なのはsite、action、プロキシであり、typeやurlではありません。対象がまだ設定されていない場合は、サイトプロファイルの設定を参照してください。
1回作成し、その後はタスクを取得する
// npm install express and the official solvethree SDK tarball.
import express from 'express';
import { Solvethree, SolvethreeError } from '@solvethree/sdk';
const app = express();
const client = new Solvethree({ apiKey: process.env.SOLVETHREE_API_KEY });
const secret = process.env.INTEGRATION_KEY;
if (!secret) throw new Error('Set INTEGRATION_KEY');
app.use((request, response, next) => {
if (request.get('x-integration-key') !== secret) return response.sendStatus(401);
next();
});
app.post('/captcha/tasks', async (request, response) => {
const task = await client.createTask({
site: process.env.CAPTCHA_SITE, action: 'login', proxy: process.env.SOLVETHREE_PROXY,
requestId: request.get('x-request-id'),
}, { waitMs: 0, signal: AbortSignal.timeout(20000) });
response.json(task);
});
app.get('/captcha/tasks/:id', async (request, response) => {
response.json(await client.getTask(request.params.id, { waitMs: 15000, signal: AbortSignal.timeout(25000) }));
});
app.use((error, request, response, next) => {
if (error instanceof SolvethreeError) return response.status(502).json({ requestId: error.requestId, taskId: error.taskId });
response.status(400).json({ error: 'Invalid task input or ID' });
});
app.listen(3000);両方のルートは認証ガードで保護されています。POSTハンドラーはホスト名、アクション、プロキシをリクエストボディではなくサーバー設定から取得します。呼び出し元から受け取るのは、任意の作成識別子だけです。
- 1.
作成前にリクエストIDを割り当てる
1–64文字のASCII英字、数字、アンダースコア、ハイフンを使った
x-request-idを送信してください。接続がタイムアウトしても作成を復旧できるよう、論理リクエストとともに保持してください。 - 2.
/captcha/tasksに1回POSTするハンドラーは
waitMs: 0でcreateTaskを呼び出し、タスクを返します。そのIDを保持してください。成功応答はタスクがあることを意味しますが、解決結果もあるとは限りません。 - 3.
GETでステータスを取得する
/captcha/tasks/:idを呼び出してください。ステータスがpendingまたはsolvingの間は取得を続け、進捗確認のためにPOSTを繰り返さないでください。readyまたはfailedになったら停止します。 - 4.
準備完了の解決結果だけを使用する
設定済みの同じプロキシと対象の送信先を使い、返された
userAgentとsecChUaとともにトークンを送信してください。SDKは代わりに送信しません。タスクが準備完了であることは解決結果が生成されたことを意味し、対象がアプリケーションリクエストを受け入れたことを意味するものではありません。
別のタスクを作成せずにタイムアウトを処理する
POSTのSDK呼び出しには、AbortSignalによる20秒の期限があります。GETでは、SDK呼び出しの25秒の期限内で、タスクを15秒待機できます。GET応答がまだ終端状態ではないこともあります。待機の終了を解決の失敗と見なさず、ステータスを確認してください。
作成のタイムアウトは、solvethreeがリクエストを拒否した証拠ではありません。タスクIDを受け取っていれば、そのタスクを取得してください。そうでなければ、同じリクエストIDと変更していないタスク入力で作成を再試行し、既存のタスクを復旧してください。異なる入力でそのIDを再利用すると競合します。リクエストIDを保持していない場合、新しいPOSTによって別の処理が作成されるおそれがあります。
Express 5は、非同期ハンドラーの拒否をエラーミドルウェアに転送します。この例では、SolvethreeErrorに対してHTTP 502を返し、リクエストとタスクの識別子だけを公開します。生のエラー、認証情報、解決結果は公開しません。フォールバックのHTTP 400は汎用的なものであり、期限に関するエラーも含め、SDK以外のすべてのエラーを正確に分類するものではありません。
成功時のペイロードを読み取る前にHTTPエラーを処理してください。それとは別に、取得したタスクのステータスがfailedの場合があります。errorCodeとerrorを確認し、ポーリングを停止してください。解決に失敗した場合は返金されますが、不正な入力を変更せずに再試行しても問題は解消しません。報告された失敗の診断には、APIエラーリファレンスを使用してください。
参照元とAPIリファレンス
最初のタスクを実行しましょう。
$5のワークスペースクレジットで始められます。