1 | "use strict";
|
2 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
3 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
4 | };
|
5 | Object.defineProperty(exports, "__esModule", { value: true });
|
6 | exports.isArrayLikeString = void 0;
|
7 | const fs_1 = __importDefault(require("fs"));
|
8 | const axios_1 = __importDefault(require("axios"));
|
9 | const cheerio_1 = __importDefault(require("cheerio"));
|
10 | var types_1 = require("./types");
|
11 | Object.defineProperty(exports, "isArrayLikeString", { enumerable: true, get: function () { return types_1.isArrayLikeString; } });
|
12 | const wait = (s) => new Promise(res => setTimeout(res, s * 1000));
|
13 | function 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 | }
|
20 | function 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 |
|
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 |
|
124 | id = String(id);
|
125 |
|
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 |
|
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 | }
|
202 | exports.default = RuCaptcha2Captcha;
|
203 | if (typeof exports.default === 'function') {
|
204 | module.exports = exports.default;
|
205 | Object.assign(module.exports, exports);
|
206 | }
|