UNPKG

8.46 kBJavaScriptView Raw
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3 return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5Object.defineProperty(exports, "__esModule", { value: true });
6exports.isArrayLikeString = void 0;
7const fs_1 = __importDefault(require("fs"));
8const axios_1 = __importDefault(require("axios"));
9const cheerio_1 = __importDefault(require("cheerio"));
10var types_1 = require("./types");
11Object.defineProperty(exports, "isArrayLikeString", { enumerable: true, get: function () { return types_1.isArrayLikeString; } });
12const wait = (s) => new Promise(res => setTimeout(res, s * 1000));
13function throwErrorOfBadStatus(status, data) {
14 if (!status && data.request !== 'CAPCHA_NOT_READY') {
15 const e = new Error(data.error_text);
16 e.name = data.request;
17 throw e;
18 }
19}
20function RuCaptcha2Captcha(key, captchaService) {
21 const isRuCaptcha = captchaService !== 2 && captchaService !== '2';
22 const domain = `https://${isRuCaptcha ? 'ru' : 2}captcha.com`;
23 const sendUrl = `${domain}/in.php`;
24 const getUrl = `${domain}/res.php`;
25 const priceUrls = {
26 all: isRuCaptcha ? 'https://rucaptcha.com/api-rucaptcha#rates' : 'https://2captcha.com/2captcha-api#rates',
27 normal: `${domain}/public_statistics`,
28 };
29 const waitings = {};
30 const makeReport = (type) => ((id) => axios_1.default
31 .get(getUrl, {
32 params: {
33 key,
34 action: `report${type}`,
35 id,
36 json: 1,
37 },
38 })
39 .then((e) => e.data)
40 .catch(e => {
41 if (e.message === 'Request failed with status code 500') {
42 const res = { status: 1, request: 'OK_REPORT_RECORDED' };
43 return res;
44 }
45 throw e;
46 }));
47 const res = {
48 async send({ url, method, file, body, ...restParams }) {
49 let p = {
50 method,
51 file,
52 body,
53 };
54 if (url) {
55 let buffer;
56 try {
57 buffer = fs_1.default.readFileSync(url);
58 }
59 catch {
60 const { data } = await axios_1.default.get(url, { responseType: 'arraybuffer' });
61 buffer = Buffer.from(data, 'binary');
62 }
63 p = {
64 method: 'base64',
65 body: buffer.toString('base64'),
66 };
67 }
68 const params = {
69 ...Object.fromEntries(Object.entries(p).filter(e => e[1] != null)),
70 ...restParams,
71 key,
72 json: 1,
73 soft_id: 2721,
74 };
75 const { data: { status, ...data } } = await axios_1.default.post(sendUrl, params);
76 throwErrorOfBadStatus(status, data);
77 const { request: id } = data;
78 const m = (params.method || '').toLowerCase();
79 const timeToWaitInSeconds = true
80 && ['post', 'base64', ''].includes(m)
81 && params.recaptcha == null
82 && params.coordinatescaptcha == null
83 ? 5
84 : 20;
85 waitings[id] = wait(timeToWaitInSeconds);
86 return id;
87 },
88 async get(id) {
89 const ids = String(id).split(/\s*,\s*/);
90 // eslint-disable-next-line no-constant-condition
91 while (1) {
92 await Promise.all(ids.map(id => waitings[id]));
93 const { data: { status, ...data } } = await axios_1.default.get(getUrl, {
94 params: {
95 key,
96 action: 'get',
97 [`id${ids.length > 1 ? 's' : ''}`]: ids.join(),
98 json: 1,
99 },
100 });
101 throwErrorOfBadStatus(status, data);
102 const res = data.request.split('|');
103 if (res.every(e => e !== 'CAPCHA_NOT_READY')) {
104 return (Array.isArray(id) || typeof id === 'string' && id.match(/,/) ? res : res[0]);
105 }
106 if (res.length === ids.length) {
107 const arr = ids
108 .map((id, i) => ({ id, captcha: res[i] }))
109 .filter(({ captcha }) => captcha === 'CAPCHA_NOT_READY');
110 for (const { id } of arr) {
111 waitings[id] = wait(5);
112 }
113 }
114 else {
115 for (const id of ids) {
116 waitings[id] = wait(5);
117 }
118 }
119 }
120 throw new Error();
121 },
122 async getWithPrice(id) {
123 // eslint-disable-next-line no-param-reassign
124 id = String(id);
125 // eslint-disable-next-line no-constant-condition
126 while (1) {
127 await waitings[id];
128 const { data: { status, ...data } } = await axios_1.default.get(getUrl, {
129 params: {
130 key,
131 action: 'get2',
132 id,
133 json: 1,
134 },
135 });
136 throwErrorOfBadStatus(status, data);
137 if (data.request !== 'CAPCHA_NOT_READY') {
138 const { request: token, ...rest } = data;
139 return { token, ...rest };
140 }
141 waitings[id] = wait(5);
142 }
143 throw new Error();
144 },
145 reportGood: makeReport('good'),
146 reportBad: makeReport('bad'),
147 async getBalance() {
148 const { data } = await axios_1.default.get(getUrl, {
149 params: {
150 key,
151 action: 'getbalance',
152 },
153 });
154 return data;
155 },
156 async getPrices() {
157 const normalNames = [];
158 const [normalPrice, otherPrices] = await Promise.all([
159 axios_1.default.get(priceUrls.normal).then(({ data }) => {
160 const $ = cheerio_1.default.load(data, { decodeEntities: false });
161 const price = $.text().match(/[i$] ?([\d.]+)/);
162 return price && +(Number(price[1]) / 1000).toFixed(7) || NaN;
163 }),
164 axios_1.default.get(priceUrls.all).then(({ data }) => {
165 const $ = cheerio_1.default.load(data, { decodeEntities: false });
166 const table = $($('.table').toArray().find(e => $(e).text().match(/Type of captcha|Вид капчи/i)));
167 return table.find('tr').toArray().slice(1).reduce((obj, e) => {
168 const [types, price] = $(e).find('td').toArray().map((e, i) => (i ? e : $(e).find('a').toArray()));
169 const p = +(Number($(price).text().replace(/\$/g, '')) / 1000).toFixed(7) || NaN;
170 for (const type of types) {
171 const t = $(type).text().trim();
172 if (Number.isNaN(p)) {
173 normalNames.push(t);
174 }
175 else {
176 // eslint-disable-next-line no-param-reassign
177 obj[t] = p;
178 }
179 }
180 return obj;
181 }, {});
182 }),
183 ]);
184 const normalPrices = Object.fromEntries(normalNames.map(e => [e, normalPrice]));
185 return {
186 ...normalPrices,
187 ...otherPrices,
188 };
189 },
190 async solve(...params) {
191 const id = await res.send(...params);
192 const token = await res.get(id);
193 return {
194 token,
195 tokenIsGood: res.reportGood.bind(null, id),
196 tokenIsBad: res.reportBad.bind(null, id),
197 };
198 },
199 };
200 return res;
201}
202exports.default = RuCaptcha2Captcha;
203if (typeof exports.default === 'function') {
204 module.exports = exports.default;
205 Object.assign(module.exports, exports);
206}