运行环境:Node.js 18 以上(自带 fetch),示例是 ES module(.mjs),不需要安装第三方库。运行前设置环境变量:
export YESCAPTCHA_CLIENT_KEY=你的clientKey不扣点,用来确认 clientKey 正确:
// Check the balance. getBalance is free and is a quick way to verify your clientKey. Node.js 18+const CLIENT_KEY = process.env.YESCAPTCHA_CLIENT_KEY;
const res = await fetch('https://api.yescaptcha.com/getBalance', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ clientKey: CLIENT_KEY }),});const data = await res.json();if (data.errorId) { // e.g. ERROR_KEY_DOES_NOT_EXIST when the clientKey is wrong console.log('error:', data.errorCode, data.errorDescription);} else { console.log('balance (points):', data.balance);}识别一张图片验证码
Section titled “识别一张图片验证码”同步类型 ImageToTextTaskOcrBase,一次请求拿到结果。示例图片:captcha.jpg。运行 node quickstart.mjs captcha.jpg。
// First request: read an alphanumeric image captcha with ImageToTextTaskOcrBase (synchronous, 2 points per image).// Usage: YESCAPTCHA_CLIENT_KEY=your_client_key node quickstart.mjs captcha.pngimport { readFileSync } from 'node:fs';
const CLIENT_KEY = process.env.YESCAPTCHA_CLIENT_KEY;const body = readFileSync(process.argv[2] ?? 'captcha.png').toString('base64'); // no "data:" prefix
const res = await fetch('https://api.yescaptcha.com/createTask', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ clientKey: CLIENT_KEY, task: { type: 'ImageToTextTaskOcrBase', body } }),});const data = await res.json();if (data.errorId) throw new Error(`${data.errorCode}: ${data.errorDescription}`);console.log('text:', data.solution.text);可复用的客户端
Section titled “可复用的客户端”// A small client you can copy into your project: create tasks, poll results, check the balance. Node.js 18+//// import { YesCaptcha } from './yescaptcha.mjs';// const client = new YesCaptcha(process.env.YESCAPTCHA_CLIENT_KEY);// const solution = await client.solve({ type: 'NoCaptchaTaskProxyless', websiteURL: '...', websiteKey: '...' });
export class YesCaptchaError extends Error { constructor(code, description) { super(`${code}: ${description}`); this.code = code; }}
export class YesCaptcha { constructor(clientKey, { endpoint = 'https://api.yescaptcha.com', pollInterval = 5000, timeout = 180000 } = {}) { this.clientKey = clientKey; this.endpoint = endpoint.replace(/\/$/, ''); this.pollInterval = pollInterval; // 5 s: polling the same taskId more often only returns "processing" this.timeout = timeout; }
async call(method, payload = {}) { const res = await fetch(`${this.endpoint}/${method}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ clientKey: this.clientKey, ...payload }), }); const data = await res.json(); if (data.errorId) throw new YesCaptchaError(data.errorCode, data.errorDescription); return data; }
async balance() { return (await this.call('getBalance')).balance; }
async solve(task) { const created = await this.call('createTask', { task }); if (created.status === 'ready') return created.solution; // synchronous types return the solution directly const deadline = Date.now() + this.timeout; while (Date.now() < deadline) { await new Promise((r) => setTimeout(r, this.pollInterval)); const result = await this.call('getTaskResult', { taskId: created.taskId }); if (result.status === 'ready') return result.solution; } throw new Error(`task ${created.taskId} not ready after ${this.timeout} ms`); }}
if (import.meta.url === `file://${process.argv[1]}`) { const client = new YesCaptcha(process.env.YESCAPTCHA_CLIENT_KEY); console.log('balance:', await client.balance());}import { YesCaptcha } from './yescaptcha.mjs';
const client = new YesCaptcha(process.env.YESCAPTCHA_CLIENT_KEY);const solution = await client.solve({ type: 'TurnstileTaskProxyless', websiteURL: 'https://example.com/login', websiteKey: '0x4AAAAAAA_SITE_KEY',});console.log(solution.token);出错时抛出 YesCaptchaError,err.code 是错误码,含义见 错误码。