UNPKG

anticaptcha-async

Version:

Modern asynchronous JavaScript API client for Anticaptcha service

145 lines (123 loc) 4.67 kB
'use strict'; const superagent = require('superagent'); const stream_to_base64 = (stream) => new Promise((resolve, reject) => { const bufs = []; stream.on('data', data => { bufs.push(data); }); stream.on('error', reject); stream.on('end', () => resolve(Buffer.concat(bufs).toString('base64'))); }); const Anticaptcha = (client_key, opts = {}) => { const soft_id = 847; const protocol = opts.unsecure ? 'http' : 'https'; const host = opts.host || 'api.anti-captcha.com'; const language_pool = opts.language_pool || 'en'; const request = (path, body) => superagent .post(`${protocol}://${host}/${path}`, Object.assign({}, { clientKey: client_key, }, body)) .then(resp => resp.body) .then(body => { if (body.errorId) { const err = new Error(body.errorDescription); err.errorId = body.errorId; err.errorCode = body.errorCode; throw err; } return body; }); const getTaskId = (task) => request('createTask', { task: task, softId: soft_id, languagePool: language_pool, }) .then(body => body.taskId); const getTaskResult = async (taskId, options = {}) => { const delay = options.delay || 5 * 1000; const attempts = options.attempts || 30; for (let i = 0; i <= 30; i++) { const resp = await request('getTaskResult', { clientKey: client_key, taskId: taskId, }); if (resp.status && resp.status !== 'processing') { return resp; } await new Promise(r => setTimeout(r, delay)); } throw new Error(`Timeout for get result of time after ${delay * attempts}.`); }; const getImageTask = (file_stream, options = {}) => stream_to_base64(file_stream) .then(content => Object.assign({type: 'ImageToTextTask'}, options, { body: content, })); const getRecaptchaTask = (url, key) => Promise.resolve({ type: 'NoCaptchaTaskProxyless', websiteURL: url, websiteKey: key, }); const getFuncaptchaTask = (url, key) => Promise.resolve({ type: 'FunCaptchaTask', websiteURL: url, websiteKey: key, }); const getCustomTask = (assignment, image_url, fields) => Promise.resolve({ type: 'CustomCaptchaTask', imageUrl: image_url, assignment: assignment, forms: fields, }); const reportIncorrect = (taskId) => request('reportIncorrectImageCaptcha', { taskId: taskId, clientKey: client_key, }) .then(body => body.status); const getResponse = (value, taskId) => ({ getValue: () => value, reportIncorrect: () => this.reportIncorrect(taskId), }); const getImage = async (file_stream, options = {}) => { const task = await getImageTask(file_stream, options.restriction); const taskId = await getTaskId(task); const result = await getTaskResult(taskId, options); return getResponse(result.solution.text, taskId); }; const getRecaptcha = async (website_url, website_key, options = {}) => { const task = await getRecaptchaTask(website_url, website_key, options); const taskId = await getTaskId(task); const result = await getTaskResult(taskId, options); return getResponse(result.solution.gRecaptchaResponse, taskId); }; const getFuncaptcha = async (website_url, website_key, options = {}) => { const task = await getFuncaptchaTask(website_url, website_key, options); const taskId = await getTaskId(task); const result = await getTaskResult(taskId, options); return getResponse(result.solution.token, taskId); }; const getCustom = async (assignment, image_url, fields, options = {}) => { const task = await getCustomTask(assignment, image_url, fields); const taskId = await getTaskId(task); const result = await getTaskResult(taskId, options); return getResponse(result.solution.answers, taskId); }; const getBalance = () => request('getBalance', { clientKey: client_key, }) .then(result => result.balance); return { getTaskId, getTaskResult, reportIncorrect, getBalance, getImageTask, getRecaptchaTask, getFuncaptchaTask, getCustomTask, getImage, getRecaptcha, getFuncaptcha, getCustom, }; }; module.exports = Anticaptcha;