-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclient.js
More file actions
139 lines (119 loc) · 4.31 KB
/
Copy pathclient.js
File metadata and controls
139 lines (119 loc) · 4.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/**
* utils/client.js
* Helper module for interacting with the Captcha Solver API.
*
* The examples import these helpers instead of calling axios directly,
* so the request, error checking and polling logic lives in one place.
*/
const axios = require('axios');
const config = require('./config');
/**
* Creates a new task via the Captcha Solver API.
* @param {Object} taskData - The task configuration object.
* @returns {Promise<string|null>} The task ID, or null on error.
*/
async function createTask(taskData) {
try {
const response = await axios.post(`${config.API_BASE}/createTask`, {
clientKey: config.API_KEY,
task: taskData
});
// Always check errorId: 0 indicates success
if (response.data.errorId !== 0) {
console.error("[-] API Error during task creation:", response.data);
return null;
}
console.log(`[+] Task created. ID: ${response.data.taskId}`);
return response.data.taskId;
} catch (error) {
console.error("[-] Connection error:", error.message);
return null;
}
}
/**
* Polls the API to retrieve the result of a specific task.
* @param {string} taskId - The ID of the task to retrieve.
* @returns {Promise<Object|null>} The full response body, or null on error.
*/
async function getTaskResult(taskId) {
try {
const response = await axios.post(`${config.API_BASE}/getTaskResult`, {
clientKey: config.API_KEY,
taskId: taskId
});
if (response.data.errorId !== 0) {
console.error("[-] API Error during polling:", response.data);
return null;
}
return response.data;
} catch (error) {
console.error("[-] Polling error:", error.message);
return null;
}
}
/**
* Polls getTaskResult until the task is ready or the retry limit is reached.
* The API solves captchas asynchronously, so the status has to be checked periodically.
* @param {string} taskId - The ID of the task to wait for.
* @param {Object} [options] - Overrides for the polling defaults in config.js.
* @param {number} [options.pollingInterval] - Delay between polls, in milliseconds.
* @param {number} [options.maxRetries] - Maximum number of polls before giving up.
* @returns {Promise<Object|null>} The solution object, or null on error/timeout.
*/
async function waitForResult(taskId, options = {}) {
const pollingInterval = options.pollingInterval || config.POLLING_INTERVAL;
const maxRetries = options.maxRetries || config.MAX_RETRIES;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
const result = await getTaskResult(taskId);
// An API or connection error was already logged, retrying will not help.
if (result === null) {
return null;
}
if (result.status === "ready") {
return result.solution;
}
// Status is "processing": wait before checking again.
await new Promise(resolve => setTimeout(resolve, pollingInterval));
}
console.error(`[-] Timeout: task ${taskId} was not solved after ${maxRetries} polls.`);
return null;
}
/**
* Creates a task and waits for its solution. This is the entry point the examples use.
* @param {Object} taskData - The task configuration object.
* @param {Object} [options] - Polling overrides, see waitForResult.
* @returns {Promise<Object|null>} The solution object, or null on error/timeout.
*/
async function solveCaptcha(taskData, options) {
const taskId = await createTask(taskData);
if (!taskId) {
return null;
}
return waitForResult(taskId, options);
}
/**
* Retrieves the current account balance.
* @returns {Promise<number|null>} The balance, or null on error.
*/
async function getBalance() {
try {
const response = await axios.post(`${config.API_BASE}/getBalance`, {
clientKey: config.API_KEY
});
if (response.data.errorId !== 0) {
console.error("[-] API Error during balance check:", response.data);
return null;
}
return response.data.balance;
} catch (error) {
console.error("[-] Connection error:", error.message);
return null;
}
}
module.exports = {
createTask,
getTaskResult,
waitForResult,
solveCaptcha,
getBalance
};