AWS LambdaでNode.js SDKを使用する
Node.js 22 以降を使用し、公式 SDK をハンドラーに同梱してください。タスク ID とエラー ID を返す時間を確保できるよう、SDK の期限を Lambda の残り実行時間より短く設定します。
このページの内容
SDK をパッケージ化し、対象を設定する
- 1.
依存関係をインストールする
クリーンなビルドディレクトリで npm パッケージを初期化します。npm を使い、
https://solvethree.com/downloads/solvethree-sdk-0.1.0.tgzの公式 tarball をインストールしてください。これにより@solvethree/sdkをインポートできます。npm レジストリで公開されているとは想定しないでください。 - 2.
ワークスペースと対象を設定する
SOLVETHREE_API_KEY、CAPTCHA_SITE、SOLVETHREE_PROXYという名前の非公開 Lambda 環境変数を設定します。ワークスペースの API キー、完全な URL ではなく対象のホスト名、このタスク用のプロキシを指定してください。ワークスペースには、そのサイトの有効なプロファイルがすでに必要です。サイトプロファイルの設定を参照してください。 - 3.
ハンドラーを保存してパッケージ化する
以下の例を
index.mjsとして保存します。index.mjs、パッケージのメタデータ、インストール済みのnode_modulesディレクトリを、プロジェクトディレクトリの中ではなく、アーカイブのルートに配置した ZIP を作成してください。認証情報を ZIP に含めないでください。 - 4.
既存の Lambda デプロイ手順でデプロイする
Node.js 22 ランタイムを使用し、ハンドラーを
index.handlerに設定します。認可済みのバックエンドまたは IAM フローから呼び出し、論理ジョブに対して変わらないrequestIdを渡してください。返された解決結果のデータは非公開にしてください。
この例ではアクションに login を使っています。デプロイ前に、対象が期待するアクションに変更してください。proxy を 1 つ送信し、デフォルトのリクエストタイプ enterprise-v3 を使用します。reCAPTCHA の type や url フィールドは追加しないでください。
呼び出しの残り時間に合わせて SDK の待機に上限を設ける
import { Solvethree, SolvethreeError, TaskFailedError, ApiError } from '@solvethree/sdk';
const client = new Solvethree({ apiKey: process.env.SOLVETHREE_API_KEY });
export const handler = async (event, context) => {
const timeoutMs = Math.min(180000, context.getRemainingTimeInMillis() - 1500);
if (timeoutMs < 1000) throw new Error('Not enough execution time to start a task');
// The caller supplies one stable ID for this logical job; Lambda retries must
// reuse it. awsRequestId changes with invocations and is not that logical ID.
if (!event.requestId) throw new Error('Provide a stable requestId');
try {
return await client.solve({
site: process.env.CAPTCHA_SITE, action: 'login', proxy: process.env.SOLVETHREE_PROXY,
requestId: event.requestId,
}, { timeoutMs, signal: AbortSignal.timeout(timeoutMs) });
} catch (error) {
if (error instanceof TaskFailedError) return { status: 'failed', id: error.taskId, errorCode: error.errorCode };
if (error instanceof ApiError) return { apiError: error.status, requestId: error.requestId };
if (error instanceof SolvethreeError) return { interrupted: true, requestId: error.requestId, taskId: error.taskId };
throw error;
}
};
// Invoke through your authorized backend/IAM flow. The return value is private
// solution data; do not attach this handler to an unauthenticated public URL.ハンドラーは Lambda の残り実行時間を読み取り、1,500 ミリ秒を確保したうえで、SDK の待機時間に 180,000 ミリ秒の上限を設定します。この上限はこの例の設定であり、Lambda 共通の実行時間制限ではありません。確保分を差し引いた残り時間が 1 秒未満の場合、ハンドラーは処理を開始しません。
SDK のタイムアウトと中止シグナルの両方に、算出した期限を使います。solve はタスクを一度だけ作成し、準備が整うかエラーが発生するまでポーリングします。確保した時間により、エラー処理で復旧情報を返す余裕ができますが、Lambda が強制終了された場合は、レスポンスを一切返せないこともあります。
呼び出し元は、呼び出しを再試行する際も event.requestId を保持する必要があります。ASCII の英字、数字、アンダースコア、ハイフンで構成される 1–64 文字を使用してください。awsRequestId は使用しないでください。これは呼び出しを識別するもので、論理的な解決リクエストを識別するものではありません。
むやみに別の解決処理を開始せずに失敗に対処する
| 結果 | 対処方法 |
|---|---|
ステータスが ready のタスク | その解決結果を使用します。タスクの作成や HTTP レスポンスの成功だけでは不十分です。 |
status: failed | id と errorCode を記録します。エラーメッセージが必要ならタスクを取得しますが、その失敗したタスクのポーリングは停止してください。 |
apiError | HTTP ステータスと返されたリクエスト ID を記録します。これは API リクエストのエラーであり、タスクが失敗の終了状態になったわけではありません。同じ入力で再試行する前に原因を確認してください。 |
interrupted: true | 復旧に備え、返された taskId と requestId があれば、呼び出し元の元の論理リクエスト ID とともに保持してください。 |
検証エラーと想定外のエラーは再スローされます。ハンドラーは、すべての例外を中断レスポンスに変換するわけではありません。
- 1.
タスク ID がある場合は、その ID で復旧する
getTaskで既存のタスクを取得します。pendingとsolvingは処理が継続中であることを意味します。使用可能な解決結果が含まれるのはreadyだけです。追加の待機時間は、新しい呼び出しの残り実行時間内に収めてください。 - 2.
タスク ID がない場合は、論理リクエスト ID で復旧する
呼び出し元の元の
requestIdを使って、同じタスクリクエストを再試行してください。入力が一致すれば既存のタスクが返され、異なれば競合になります。設定変更をまたぐ場合も含め、復旧中はサイト、アクション、プロキシを変更しないでください。
接続のタイムアウトは、タスクの作成が失敗したことを意味しません。新しい論理リクエスト ID を割り当てる前に、既存のタスクを復旧してください。基礎となる仕様については、タスクのポーリングと API エラー処理を参照してください。
同じプロキシと返されたブラウザ識別情報で送信する
SDK は解答データを返しますが、送信先への適用は行いません。アプリケーションから送信するときは、設定済みのプロキシと、返された userAgent および secChUa を使用してください。無関係なブラウザ識別情報や送信先 URL に置き換えないでください。タスクが ready になったことは、解答が生成されたことを意味するだけで、その後のリクエストが送信先に受理されたことを意味しません。
参照元とAPIリファレンス
最初のタスクを実行しましょう。
$5のワークスペースクレジットで始められます。