gadisk820 commited on
Commit
6c79100
Β·
verified Β·
1 Parent(s): b4b19da

Upload 19 files

Browse files
.dockerignore ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __pycache__/
2
+ *.pyc
3
+ *.pyo
4
+ *.pyd
5
+ .Python
6
+ env/
7
+ venv/
8
+ .venv/
9
+ env.bak/
10
+ venv.bak/
11
+ *.log
12
+ logs/
13
+ data/
14
+ *.db
15
+ .DS_Store
16
+ .git/
17
+ .gitignore
18
+ .vscode/
19
+ .idea/
20
+ *.md
21
+ docker-compose.override.yml
.env ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Email configuration
2
+ EMAIL=gi2h27@gmail.com
3
+
4
+ # Faucet configuration
5
+ MAX_CLAIMS=100000
6
+ COOLDOWN_OVERRIDE=5
7
+
8
+ # Proxy settings (jika perlu)
9
+ HTTP_PROXY=
10
+ HTTPS_PROXY=
11
+ NO_PROXY=localhost,127.0.0.1
12
+
13
+ # Solver settings
14
+ SOLVER_URL=https://gi2h-xxx.hf.space
15
+ SOLVER_KEY=00000000000000000000#0000000000000000000#000000000000000000#
Api/.gitattributes ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
Api/Api.js ADDED
@@ -0,0 +1,205 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * API.js
3
+ */
4
+ const express = require('express');
5
+ const { connect } = require("puppeteer-real-browser");
6
+ const fs = require('fs');
7
+ const path = require('path');
8
+
9
+ const app = express();
10
+ const port = process.env.PORT || 7860;
11
+ const authToken = process.env.authToken || null;
12
+
13
+ global.browserLimit = 100;
14
+ global.timeOut = 300000;
15
+
16
+ // cache
17
+ const CACHE_DIR = path.join(__dirname, "cache");
18
+ const CACHE_FILE = path.join(CACHE_DIR, "cache.json");
19
+ const CACHE_TTL = 5 * 60 * 1000;
20
+ const CACHE_AUTOSAVE = process.env.CACHE_AUTOSAVE === "true";
21
+
22
+ function readCache(type, taskId) {
23
+ const file = path.join(CACHE_DIR, type, `${taskId}.json`);
24
+ if (!fs.existsSync(file)) return null;
25
+
26
+ try {
27
+ const data = JSON.parse(fs.readFileSync(file, 'utf-8'));
28
+ console.log(`cache check: ${type}:${taskId} => ${data ? "HIT" : "MISS"}`);
29
+ if (Date.now() - data.timestamp < CACHE_TTL) {
30
+ return data;
31
+ }
32
+ return null;
33
+ } catch {
34
+ return null;
35
+ }
36
+ }
37
+
38
+ function writeCache(type, taskId, value) {
39
+ const dir = path.join(CACHE_DIR, type);
40
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
41
+
42
+ const file = path.join(dir, `${taskId}.json`);
43
+ const data = { timestamp: Date.now(), ...value };
44
+
45
+ fs.writeFileSync(file, JSON.stringify(data, null, 2), 'utf-8');
46
+ console.log(`cache saved: ${type}:${taskId}`);
47
+ }
48
+
49
+ function cleanCache() {
50
+ const types = ["turnstile", "recaptcha3", "recaptcha2", "interstitial", "error"];
51
+ const now = Date.now();
52
+ const TTL = 60 * 60 * 1000;
53
+
54
+ types.forEach(type => {
55
+ const dir = path.join(CACHE_DIR, type);
56
+ if (!fs.existsSync(dir)) return;
57
+
58
+ fs.readdirSync(dir).forEach(file => {
59
+ const filePath = path.join(dir, file);
60
+ try {
61
+ const data = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
62
+ if (now - data.timestamp > TTL) {
63
+ fs.unlinkSync(filePath);
64
+ console.log(`cache expired: ${filePath}`);
65
+ }
66
+ } catch {
67
+ fs.unlinkSync(filePath);
68
+ }
69
+ });
70
+ });
71
+ }
72
+
73
+ setInterval(cleanCache, 600 * 1000);
74
+
75
+ app.use(express.json());
76
+ app.use(express.urlencoded({ extended: true }));
77
+ const tasks = {};
78
+
79
+ // Api_route
80
+ app.get("/", (req, res) => {
81
+ const baseUrl = `${req.protocol}://${req.get('host')}`;
82
+ const uptime = process.uptime();
83
+ res.json({
84
+ message: "Welcome",
85
+ server: {
86
+ domain: baseUrl,
87
+ version: "7.3.0",
88
+ uptime: `${Math.floor(uptime)} seconds`,
89
+ limit: global.browserLimit,
90
+ timeout: global.timeOut,
91
+ status: "recently running"
92
+ },
93
+ solvers: ["turnstile", "recaptcha2", "recaptcha3", "interstitial"]
94
+ });
95
+ });
96
+
97
+
98
+ app.post('/solve', async (req, res) => {
99
+ const { type, domain, siteKey, taskId, action, proxy, isInvisible } = req.body;
100
+
101
+ if (taskId) {
102
+ const task = tasks[taskId];
103
+ if (!task) return res.status(404).json({ status: "error", message: "Task not found" });
104
+
105
+ if (task.status === "pending") {
106
+ return res.json({ status: "processing" });
107
+ }
108
+
109
+ return res.json(task);
110
+ }
111
+
112
+ const newTaskId = Date.now().toString(36);
113
+ tasks[newTaskId] = { status: "pending" };
114
+ console.log(`New : ${newTaskId}=${type}:${domain}`);
115
+
116
+ (async () => {
117
+ try {
118
+ const ctx = await init_browser(proxy?.server);
119
+ const page = ctx.page;
120
+ let result;
121
+
122
+ switch (type) {
123
+ case "turnstile":
124
+ result = await turnstile({ domain, siteKey, action, proxy }, page);
125
+ tasks[newTaskId] = { status: "done", ...result };
126
+ console.log(`done: ${newTaskId}=${type}:${domain}`);
127
+ if (CACHE_AUTOSAVE) writeCache("turnstile", newTaskId, tasks[newTaskId]);
128
+ break;
129
+
130
+ case "interstitial":
131
+ result = await interstitial({ domain, proxy }, page);
132
+ tasks[newTaskId] = { status: "done", ...result };
133
+ console.log(`done: ${newTaskId}=${type}:${domain}`);
134
+ if (CACHE_AUTOSAVE) writeCache("interstitial", newTaskId, tasks[newTaskId]);
135
+ break;
136
+
137
+ case "recaptcha2":
138
+ result = await recaptchaV2({ domain, siteKey, action, isInvisible, proxy }, page);
139
+ tasks[newTaskId] = { status: "done", ...result };
140
+ console.log(`done: ${newTaskId}=${type}:${domain}`);
141
+ if (CACHE_AUTOSAVE) writeCache("recaptcha2", newTaskId, tasks[newTaskId]);
142
+ break;
143
+
144
+ case "recaptcha3":
145
+ result = await recaptchaV3({ domain, siteKey, action, proxy }, page);
146
+ tasks[newTaskId] = { status: "done", ...result };
147
+ console.log(`done: ${newTaskId}=${type}:${domain}`);
148
+ if (CACHE_AUTOSAVE) writeCache("recaptcha3", newTaskId, tasks[newTaskId]);
149
+ break;
150
+
151
+ default:
152
+ tasks[newTaskId] = { status: "error", message: "Invalid type" };
153
+ }
154
+
155
+ await ctx.browser.close();
156
+ console.log(`Browser closed ${newTaskId}`);
157
+ } catch (err) {
158
+ tasks[newTaskId] = { status: "error", message: "totally failed" };
159
+ console.error(`failed: ${newTaskId}=${type}:${domain}`);
160
+ console.error("Detailed error:", err);
161
+ }
162
+ })();
163
+
164
+ res.json({ taskId: newTaskId, status: "pending" });
165
+ });
166
+
167
+ // init_browser
168
+ async function init_browser(proxyServer = null) {
169
+ const connectOptions = {
170
+ headless: false,
171
+ turnstile: true,
172
+ connectOption: { defaultViewport: null },
173
+ disableXvfb: false,
174
+ };
175
+ if (proxyServer) connectOptions.args = [`--proxy-server=${proxyServer}`];
176
+
177
+ const { browser } = await connect(connectOptions);
178
+ const [page] = await browser.pages();
179
+
180
+ await page.goto('about:blank');
181
+ await page.setRequestInterception(true);
182
+ page.on('request', (req) => {
183
+ const type = req.resourceType();
184
+ if (["image", "stylesheet", "font", "media"].includes(type)) req.abort();
185
+ else req.continue();
186
+ });
187
+ console.log(`initialized${proxyServer ? "proxy= " + proxyServer : ""}`);
188
+
189
+ return { browser, page };
190
+ }
191
+
192
+
193
+ const turnstile = require('./Api/turnstile');
194
+ const interstitial = require('./Api/interstitial');
195
+ const recaptchaV2 = require('./Api/recaptcha2');
196
+ const recaptchaV3 = require('./Api/recaptcha3');
197
+
198
+ app.use((req, res) => {
199
+ res.status(404).json({ message: 'Not Found' });
200
+ console.warn(`error: ${req.method} ${req.originalUrl}`);
201
+ });
202
+
203
+ app.listen(port, () => {
204
+ console.log(`Server running: http://localhost:${port}`);
205
+ });
Api/Api/Api.md ADDED
@@ -0,0 +1 @@
 
 
1
+ Api
Api/Api/interstitial.js ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * INTERSTITIAL
3
+ */
4
+ async function interstitial({ domain, proxy }, page) {
5
+ return new Promise(async (resolve, reject) => {
6
+ if (!domain) return reject(new Error("Missing domain parameter"));
7
+
8
+ const startTime = Date.now();
9
+ let isResolved = false;
10
+ let userAgent = null;
11
+
12
+ const cl = setTimeout(() => {
13
+ if (!isResolved) {
14
+ isResolved = true;
15
+ resolve({
16
+ cf_clearance: null,
17
+ cookies: null,
18
+ user_agent: userAgent,
19
+ type: 'interstitial'
20
+ });
21
+ }
22
+ }, 20000);
23
+
24
+ try {
25
+ if (proxy?.username && proxy?.password) {
26
+ await page.authenticate({
27
+ username: proxy.username,
28
+ password: proxy.password,
29
+ });
30
+ }
31
+
32
+ page.removeAllListeners("request");
33
+ page.removeAllListeners("response");
34
+ await page.setRequestInterception(true);
35
+
36
+ page.on("request", async (req) => {
37
+ try {
38
+ await req.continue();
39
+ } catch (_) {}
40
+ });
41
+
42
+ page.on("response", async (res) => {
43
+ try {
44
+ const url = res.url();
45
+ if (url.includes("/cdn-cgi/challenge-platform/")) {
46
+ const headers = res.headers();
47
+ if (headers["set-cookie"]) {
48
+ const cookies = headers["set-cookie"];
49
+ const match = cookies.match(/cf_clearance=([^;]+)/);
50
+ if (match) {
51
+ const cf_clearance = match[1];
52
+ const userAgent = (await res.request().headers())["user-agent"];
53
+
54
+ if (!isResolved) {
55
+ isResolved = true;
56
+ clearTimeout(cl);
57
+ resolve({
58
+ cf_clearance,
59
+ cookies, // seluruh cookie string
60
+ user_agent: userAgent,
61
+ type: 'interstitial'
62
+ });
63
+ }
64
+ }
65
+ }
66
+ }
67
+ } catch (_) {}
68
+ });
69
+
70
+ await page.goto(domain, { waitUntil: "domcontentloaded" });
71
+ userAgent = await page.evaluate(() => navigator.userAgent);
72
+ } catch (err) {
73
+ if (!isResolved) {
74
+ isResolved = true;
75
+ clearTimeout(cl);
76
+ reject(err);
77
+ }
78
+ }
79
+ });
80
+ }
81
+
82
+ module.exports = interstitial;
Api/Api/recaptcha2.js ADDED
@@ -0,0 +1,228 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * API_RECAPTCHA2
3
+ */
4
+ async function recaptchaV2({ domain, siteKey, action = "submit", isInvisible = false, proxy }, page) {
5
+ if (!domain) throw new Error("Missing domain parameter");
6
+ if (!siteKey) throw new Error("Missing siteKey parameter");
7
+
8
+ const timeout = global.timeOut;
9
+
10
+ return new Promise(async (resolve, reject) => {
11
+ let isResolved = false;
12
+
13
+ const cl = setTimeout(() => {
14
+ if (!isResolved) {
15
+ isResolved = true;
16
+ reject(new Error("Timeout Error"));
17
+ }
18
+ }, timeout);
19
+
20
+ try {
21
+ if (proxy?.username && proxy?.password) {
22
+ await page.authenticate({
23
+ username: proxy.username,
24
+ password: proxy.password,
25
+ });
26
+ }
27
+
28
+ const htmlContent = `
29
+ <!DOCTYPE html>
30
+ <html lang="en">
31
+ <head>
32
+ <meta charset="UTF-8">
33
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
34
+ <title>reCAPTCHA v2 Solver</title>
35
+ <style>
36
+ body {
37
+ font-family: Arial, sans-serif;
38
+ margin: 0;
39
+ padding: 20px;
40
+ background: #f5f5f5;
41
+ display: flex;
42
+ justify-content: center;
43
+ align-items: center;
44
+ min-height: 100vh;
45
+ }
46
+ .container {
47
+ background: white;
48
+ padding: 30px;
49
+ border-radius: 10px;
50
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
51
+ text-align: center;
52
+ }
53
+ .status {
54
+ margin-top: 20px;
55
+ padding: 10px;
56
+ border-radius: 5px;
57
+ background: #f8f9fa;
58
+ }
59
+ button {
60
+ background: #007bff;
61
+ color: white;
62
+ border: none;
63
+ padding: 10px 20px;
64
+ border-radius: 5px;
65
+ cursor: pointer;
66
+ margin: 10px;
67
+ }
68
+ button:hover { background: #0056b3; }
69
+ </style>
70
+ </head>
71
+ <body>
72
+ <div class="container">
73
+ <h2>reCAPTCHA v2 Solver</h2>
74
+ <p>SiteKey: ${siteKey}</p>
75
+ <div id="recaptcha-container">
76
+ <div class="g-recaptcha"
77
+ data-sitekey="${siteKey}"
78
+ data-callback="recaptchaCallback"
79
+ data-expired-callback="recaptchaExpired"
80
+ data-error-callback="recaptchaError"
81
+ data-size="${isInvisible ? 'invisible' : 'normal'}"
82
+ data-theme="light"></div>
83
+ </div>
84
+ ${isInvisible ? '<button onclick="executeInvisible()">Execute reCAPTCHA</button>' : ''}
85
+ <button onclick="checkToken()">Check Token</button>
86
+ <div class="status" id="status">Waiting for reCAPTCHA...</div>
87
+ </div>
88
+
89
+ <script>
90
+ window.recaptchaToken = null;
91
+ window.recaptchaSolved = false;
92
+
93
+ window.recaptchaCallback = function(token) {
94
+ console.log('reCAPTCHA token received:', token);
95
+ window.recaptchaToken = token;
96
+ window.recaptchaSolved = true;
97
+
98
+ document.getElementById('status').innerHTML =
99
+ 'βœ… reCAPTCHA Solved! Token: ' + token.substring(0, 20) + '...';
100
+ document.getElementById('status').style.background = '#d4edda';
101
+ document.getElementById('status').style.color = '#155724';
102
+
103
+ var input = document.createElement('input');
104
+ input.type = 'hidden';
105
+ input.name = 'g-recaptcha-response';
106
+ input.value = token;
107
+ input.id = 'recaptcha-token-input';
108
+ document.body.appendChild(input);
109
+
110
+ localStorage.setItem('recaptcha_token', token);
111
+ };
112
+
113
+ window.recaptchaExpired = function() {
114
+ console.log('reCAPTCHA expired');
115
+ window.recaptchaToken = null;
116
+ window.recaptchaSolved = false;
117
+ document.getElementById('status').innerHTML = '❌ reCAPTCHA Expired - Refreshing...';
118
+ document.getElementById('status').style.background = '#fff3cd';
119
+ document.getElementById('status').style.color = '#856404';
120
+
121
+ var existing = document.getElementById('recaptcha-token-input');
122
+ if (existing) existing.remove();
123
+
124
+ setTimeout(() => { if (window.grecaptcha) grecaptcha.reset(); }, 1000);
125
+ };
126
+
127
+ window.recaptchaError = function() {
128
+ console.log('reCAPTCHA error');
129
+ document.getElementById('status').innerHTML = '❌ reCAPTCHA Error';
130
+ document.getElementById('status').style.background = '#f8d7da';
131
+ document.getElementById('status').style.color = '#721c24';
132
+ };
133
+
134
+ window.executeInvisible = function() {
135
+ if (window.grecaptcha) grecaptcha.execute();
136
+ };
137
+
138
+ window.checkToken = function() {
139
+ const token = window.recaptchaToken ||
140
+ document.getElementById('recaptcha-token-input')?.value;
141
+ document.getElementById('status').innerHTML = token
142
+ ? 'Token: ' + token
143
+ : 'No token yet';
144
+ };
145
+
146
+ window.onload = function() {
147
+ setTimeout(function() {
148
+ if (${isInvisible} && window.grecaptcha) {
149
+ grecaptcha.execute();
150
+ }
151
+ if (!${isInvisible}) {
152
+ var iframe = document.querySelector('iframe[src*="recaptcha"]');
153
+ if (iframe) {
154
+ console.log('Attempting to interact with reCAPTCHA');
155
+ var rect = iframe.getBoundingClientRect();
156
+ var clickEvent = new MouseEvent('click', {
157
+ view: window, bubbles: true, cancelable: true,
158
+ clientX: rect.left + rect.width / 2,
159
+ clientY: rect.top + rect.height / 2
160
+ });
161
+ iframe.dispatchEvent(clickEvent);
162
+ }
163
+ }
164
+ }, 2000);
165
+ };
166
+ </script>
167
+
168
+ <script src="https://www.google.com/recaptcha/api.js" async defer></script>
169
+ </body>
170
+ </html>
171
+ `;
172
+
173
+ await page.setRequestInterception(true);
174
+ page.removeAllListeners("request");
175
+ page.on("request", async (req) => {
176
+ const url = req.url();
177
+ if ([domain, domain + "/"].includes(url) && req.resourceType() === "document") {
178
+ await req.respond({ status: 200, contentType: "text/html", body: htmlContent });
179
+ } else if (["image", "stylesheet", "font"].includes(req.resourceType())) {
180
+ await req.abort();
181
+ } else {
182
+ await req.continue();
183
+ }
184
+ });
185
+
186
+ await page.goto(domain, { waitUntil: "domcontentloaded", timeout });
187
+ await page.waitForSelector('.g-recaptcha', { timeout: 10000 });
188
+
189
+ const tokenHandle = await page.waitForFunction(() => {
190
+ const input = document.querySelector('#recaptcha-token-input');
191
+ if (input?.value?.length > 10) return input.value;
192
+ const stored = localStorage.getItem('recaptcha_token');
193
+ if (stored?.length > 10) return stored;
194
+ if (window.recaptchaToken?.length > 10) return window.recaptchaToken;
195
+ return null;
196
+ }, { timeout, polling: 100 });
197
+
198
+ const tokenValue = await tokenHandle.jsonValue();
199
+
200
+ isResolved = true;
201
+ clearTimeout(cl);
202
+
203
+ if (!tokenValue || tokenValue.length < 10) {
204
+ reject(new Error("Failed to get valid reCAPTCHA token"));
205
+ } else {
206
+ resolve({ token: tokenValue, type: 'recaptcha_v2' });
207
+ }
208
+ } catch (error) {
209
+ if (!isResolved) {
210
+ isResolved = true;
211
+ clearTimeout(cl);
212
+ try {
213
+ const fallbackToken = await page.evaluate(() => {
214
+ const input = document.querySelector('#recaptcha-token-input');
215
+ return input ? input.value : null;
216
+ });
217
+ if (fallbackToken?.length > 10) {
218
+ resolve({ token: fallbackToken, type: 'recaptcha_v2' });
219
+ return;
220
+ }
221
+ } catch {}
222
+ reject(new Error(`reCAPTCHA solving failed: ${error.message}`));
223
+ }
224
+ }
225
+ });
226
+ }
227
+
228
+ module.exports = recaptchaV2;
Api/Api/recaptcha3.js ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * recaptcha3.js
3
+ */
4
+ async function recaptchaV3({ domain, siteKey, action, proxy }, page) {
5
+ if (!domain) throw new Error("Missing domain parameter");
6
+ if (!siteKey) throw new Error("Missing siteKey parameter");
7
+
8
+ const timeout = 120000;
9
+
10
+ return new Promise(async (resolve, reject) => {
11
+ let isResolved = false;
12
+
13
+ const cl = setTimeout(() => {
14
+ if (!isResolved) {
15
+ isResolved = true;
16
+ reject(new Error("Timeout Error"));
17
+ }
18
+ }, timeout);
19
+
20
+ try {
21
+ if (proxy?.username && proxy?.password) {
22
+ await page.authenticate({
23
+ username: proxy.username,
24
+ password: proxy.password,
25
+ });
26
+ }
27
+
28
+ await page.goto(domain, { waitUntil: "domcontentloaded" });
29
+
30
+ await page.addScriptTag({ url: "https://www.google.com/recaptcha/api.js?render=" + siteKey });
31
+
32
+ const token = await page.evaluate(async (siteKey, action) => {
33
+ return await grecaptcha.execute(siteKey, { action: action || "login" });
34
+ }, siteKey, action);
35
+
36
+ isResolved = true;
37
+ clearTimeout(cl);
38
+
39
+ if (!token || token.length < 10) {
40
+ reject(new Error("Failed to get token"));
41
+ } else {
42
+ resolve({ token: token, type: "recaptcha3" });
43
+ }
44
+ } catch (e) {
45
+ if (!isResolved) {
46
+ isResolved = true;
47
+ clearTimeout(cl);
48
+ reject(e);
49
+ }
50
+ }
51
+ });
52
+ }
53
+
54
+ module.exports = recaptchaV3;
Api/Api/turnstile.js ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * API_TURNSTILE
3
+ */
4
+ async function turnstile({ domain, siteKey, action, proxy }, page) {
5
+ if (!domain) throw new Error("Missing domain parameter");
6
+ if (!siteKey) throw new Error("Missing siteKey parameter");
7
+
8
+ const timeout = global.timeOut;
9
+
10
+ return new Promise(async (resolve, reject) => {
11
+ let isResolved = false;
12
+
13
+ const cl = setTimeout(() => {
14
+ if (!isResolved) {
15
+ isResolved = true;
16
+ reject(new Error("Timeout Error"));
17
+ }
18
+ }, timeout);
19
+
20
+ try {
21
+ if (proxy?.username && proxy?.password) {
22
+ await page.authenticate({
23
+ username: proxy.username,
24
+ password: proxy.password,
25
+ });
26
+ }
27
+
28
+ const htmlContent = `
29
+ <!DOCTYPE html>
30
+ <html lang="en">
31
+ <body>
32
+ <div class="turnstile"></div>
33
+ <script src="https://challenges.cloudflare.com/turnstile/v0/api.js?onload=onloadTurnstileCallback" defer></script>
34
+ <script>
35
+ window.onloadTurnstileCallback = function () {
36
+ turnstile.render('.turnstile', {
37
+ sitekey: '${siteKey}',
38
+ action: '${action || ""}',
39
+ callback: function (token) {
40
+ var c = document.createElement('input');
41
+ c.type = 'hidden';
42
+ c.name = 'cf-response';
43
+ c.value = token;
44
+ document.body.appendChild(c);
45
+ },
46
+ });
47
+ };
48
+ </script>
49
+ </body>
50
+ </html>
51
+ `;
52
+
53
+ await page.setRequestInterception(true);
54
+ page.removeAllListeners("request");
55
+ page.on("request", async (request) => {
56
+ if ([domain, domain + "/"].includes(request.url()) && request.resourceType() === "document") {
57
+ await request.respond({
58
+ status: 200,
59
+ contentType: "text/html",
60
+ body: htmlContent,
61
+ });
62
+ } else {
63
+ await request.continue();
64
+ }
65
+ });
66
+
67
+ await page.goto(domain, { waitUntil: "domcontentloaded" });
68
+ await page.waitForSelector('[name="cf-response"]', { timeout });
69
+
70
+ const token = await page.evaluate(() => {
71
+ return document.querySelector('[name="cf-response"]').value;
72
+ });
73
+
74
+ isResolved = true;
75
+ clearTimeout(cl);
76
+
77
+ if (!token || token.length < 10) {
78
+ reject(new Error("Failed to get token"));
79
+ } else {
80
+ resolve({ token: token, type: 'turnstile' });
81
+ }
82
+ } catch (e) {
83
+ if (!isResolved) {
84
+ isResolved = true;
85
+ clearTimeout(cl);
86
+ reject(e);
87
+ }
88
+ }
89
+ });
90
+ }
91
+
92
+ module.exports = turnstile;
Api/Dockerfile ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM node:20-slim
2
+
3
+ RUN apt update && apt install -y \
4
+ wget gnupg ca-certificates xvfb \
5
+ fonts-liberation libappindicator3-1 libasound2 libatk-bridge2.0-0 \
6
+ libatk1.0-0 libxss1 libnss3 libxcomposite1 libxdamage1 libxrandr2 libgbm1 \
7
+ && wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb \
8
+ && apt install -y ./google-chrome-stable_current_amd64.deb \
9
+ && rm google-chrome-stable_current_amd64.deb
10
+
11
+ WORKDIR /A
12
+
13
+ RUN mkdir -p /A/Api && mkdir -p /A/cache
14
+
15
+ COPY package.json ./
16
+ RUN npm install
17
+
18
+ COPY . .
19
+
20
+ EXPOSE 7860
21
+
22
+ CMD rm -f /tmp/.X99-lock && \
23
+ Xvfb :99 -screen 0 1024x768x24 & \
24
+ export DISPLAY=:99 && \
25
+ npm start
Api/README.md ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Api
3
+ emoji: πŸ¦€
4
+ colorFrom: blue
5
+ colorTo: yellow
6
+ sdk: docker
7
+ pinned: false
8
+ license: mit
9
+ short_description: Api
10
+ ---
11
+
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
Api/package.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "api",
3
+ "version": "7.3.0",
4
+ "description": "gmxch_Api",
5
+ "scripts": {
6
+ "start": "node Api.js",
7
+ "dev": "nodemon Api.js"
8
+ },
9
+ "dependencies": {
10
+ "express": "^5.1.0",
11
+ "puppeteer-real-browser": "^1.4.0"
12
+ },
13
+ "devDependencies": {
14
+ "nodemon": "^3.1.10"
15
+ },
16
+ "license": "MIT"
17
+ }
Api/supervisord.conf ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [supervisord]
2
+ nodaemon=true
3
+ logfile=/var/log/supervisor/supervisord.log
4
+ pidfile=/var/run/supervisord.pid
5
+ childlogdir=/var/log/supervisor
6
+
7
+ [program:xvfb]
8
+ command=Xvfb :99 -screen 0 1024x768x24 -ac +extension GLX +render -noreset
9
+ autostart=true
10
+ autorestart=true
11
+ priority=100
12
+ stdout_logfile=/var/log/supervisor/xvfb.log
13
+ stderr_logfile=/var/log/supervisor/xvfb.err
14
+
15
+ [program:api]
16
+ command=npm start
17
+ directory=/app/api
18
+ environment=DISPLAY=":99",NODE_ENV="production"
19
+ autostart=true
20
+ autorestart=true
21
+ priority=200
22
+ stdout_logfile=/var/log/supervisor/api.log
23
+ stderr_logfile=/var/log/supervisor/api.err
24
+ startretries=3
25
+
26
+ [program:bot]
27
+ command=gunicorn --bind 0.0.0.0:7861 --workers 1 --threads 2 --timeout 120 app:app
28
+ directory=/app/bot
29
+ environment=DISPLAY=":99",PYTHONUNBUFFERED="1"
30
+ autostart=true
31
+ autorestart=true
32
+ priority=300
33
+ stdout_logfile=/var/log/supervisor/bot.log
34
+ stderr_logfile=/var/log/supervisor/bot.err
35
+
36
+ [program:nginx]
37
+ command=nginx -g 'daemon off;'
38
+ autostart=true
39
+ autorestart=true
40
+ priority=400
41
+ stdout_logfile=/var/log/supervisor/nginx.log
42
+ stderr_logfile=/var/log/supervisor/nginx.err
Dockerfile ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ============================================
2
+ # DOCKERFILE FAUCET BOT - FULL FIX
3
+ # ============================================
4
+ FROM python:3.9-slim
5
+
6
+ # -------------------------------
7
+ # 1. Install system dependencies + Xvfb
8
+ # -------------------------------
9
+ RUN apt-get update && apt-get install -y \
10
+ curl \
11
+ wget \
12
+ gnupg \
13
+ ca-certificates \
14
+ xz-utils \
15
+ xvfb \
16
+ fonts-liberation \
17
+ libnss3 \
18
+ libatk-bridge2.0-0 \
19
+ libx11-xcb1 \
20
+ libxcb-dri3-0 \
21
+ libxcomposite1 \
22
+ libxdamage1 \
23
+ libxrandr2 \
24
+ libgbm1 \
25
+ libasound2 \
26
+ libatk1.0-0 \
27
+ libgtk-3-0 \
28
+ libxshmfence1 \
29
+ && rm -rf /var/lib/apt/lists/*
30
+
31
+ # -------------------------------
32
+ # 2. Install Google Chrome
33
+ # -------------------------------
34
+ RUN mkdir -p /etc/apt/keyrings \
35
+ && wget -q -O - https://dl.google.com/linux/linux_signing_key.pub > /tmp/google.pub \
36
+ && gpg --dearmor < /tmp/google.pub > /etc/apt/keyrings/google-chrome.gpg \
37
+ && echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/google-chrome.gpg] http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list \
38
+ && apt-get update \
39
+ && apt-get install -y google-chrome-stable \
40
+ && rm -rf /var/lib/apt/lists/* \
41
+ && rm /tmp/google.pub
42
+
43
+ WORKDIR /app
44
+
45
+ # -------------------------------
46
+ # 3. Install Python dependencies
47
+ # -------------------------------
48
+ COPY requirements.txt .
49
+ RUN pip install --no-cache-dir --upgrade pip && \
50
+ pip install --no-cache-dir -r requirements.txt
51
+
52
+ # -------------------------------
53
+ # 4. Install Node.js 20
54
+ # -------------------------------
55
+ RUN mkdir -p /etc/apt/keyrings \
56
+ && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
57
+ && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \
58
+ && apt-get update \
59
+ && apt-get install -y nodejs \
60
+ && rm -rf /var/lib/apt/lists/*
61
+
62
+ # -------------------------------
63
+ # 5. Copy API
64
+ # -------------------------------
65
+ COPY Api/ /app/Api/
66
+ WORKDIR /app/Api
67
+ RUN npm install --omit=dev
68
+
69
+ WORKDIR /app
70
+
71
+ # -------------------------------
72
+ # 6. Copy Python bot
73
+ # -------------------------------
74
+ COPY app.py .
75
+
76
+ # -------------------------------
77
+ # 7. Startup Script
78
+ # -------------------------------
79
+ RUN echo '#!/bin/bash\n\
80
+ echo "πŸ€– STARTING FAUCET BOT"\n\
81
+ echo "======================"\n\
82
+ \n\
83
+ echo "Starting Node.js API..."\n\
84
+ cd /app/Api\n\
85
+ node Api.js &\n\
86
+ \n\
87
+ echo "Waiting for API to start..."\n\
88
+ sleep 5\n\
89
+ \n\
90
+ echo "Starting Python Bot..."\n\
91
+ cd /app\n\
92
+ xvfb-run -a python3 app.py\n\
93
+ ' > /start.sh && chmod +x /start.sh
94
+
95
+ # -------------------------------
96
+ # 8. Healthcheck
97
+ # -------------------------------
98
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
99
+ CMD curl -f http://localhost:3000/ || exit 1
100
+
101
+ # -------------------------------
102
+ # 9. Expose API port
103
+ # -------------------------------
104
+ EXPOSE 3000
105
+
106
+ # -------------------------------
107
+ # 10. Start container
108
+ # -------------------------------
109
+ CMD ["/start.sh"]
README.md CHANGED
@@ -1,8 +1,8 @@
1
  ---
2
- title: Drtrx
3
- emoji: πŸ¦€
4
- colorFrom: blue
5
- colorTo: indigo
6
  sdk: docker
7
  pinned: false
8
  ---
 
1
  ---
2
+ title: Auto
3
+ emoji: πŸ“‰
4
+ colorFrom: pink
5
+ colorTo: gray
6
  sdk: docker
7
  pinned: false
8
  ---
app.py ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ import asyncio, json, os, re, aiohttp
3
+ from bs4 import BeautifulSoup
4
+ from datetime import datetime
5
+ from yarl import URL
6
+
7
+ BASE = "https://driptrx.fun"
8
+ URL_FAUCET = BASE + "/faucet.php"
9
+ URL_LUCKY = BASE + "/lucky.php"
10
+ URL_SPIN = BASE + "/lucky.php?spin=1"
11
+
12
+ EMAILS = [
13
+ "qnita989@gmail.com","gadisk820@gmail.com","jokondeso53@gmail.com","gadis0469@gmail.com",
14
+ "aldoaldo254535@gmail.com","queenitanita27@gmail.com","qoniytata@gmail.com","gi2h27013@gmail.com",
15
+ "gi2h27012@gmail.com","gi2h2720@gmail.com","gi2h27010@gmail.com","cleopard438@gmail.com",
16
+ "jndeso64@gmail.com","monross254535@gmail.com","gi2h2706@gmail.com","gi2h2709@gmail.com",
17
+ "gi2h27018@gmail.com","gigihlazim1@gmail.com","gigihlazim7@gmail.com","gigihlazim8@gmail.com",
18
+ "gigihlazim9@gmail.com","qoniq65@gmail.com","bosocksock@gmail.com","chusmyoh@gmail.com",
19
+ "gi2h370@gmail.com","aldi254535@gmail.com","monnavaldemar11@gmail.com","exelsnoxyti@gmail.com",
20
+ "toxicnozle@gmail.com","ydahross@gmail.com","gi2h37@gmail.com","gi2h27@gmail.com",
21
+ "gi2h270@gmail.com","gi2h2701@gmail.com","gi2h2702@gmail.com","gi2h2703@gmail.com",
22
+ "gi2h2704@gmail.com","gi2h2705@gmail.com","gi2h27015@gmail.com"
23
+ ]
24
+
25
+ GREEN = "\033[92m"
26
+ RESET = "\033[0m"
27
+
28
+ TOTAL_SUCCESS = 0
29
+ TOTAL_LOCK = asyncio.Lock()
30
+
31
+ COOK_DIR = "drptrx21"
32
+ os.makedirs(COOK_DIR, exist_ok=True)
33
+
34
+ HEADERS = {
35
+ "user-agent": "Mozilla/5.0 (Linux; Android 12; SM-A537F) Chrome/140 Mobile"
36
+ }
37
+
38
+ def safe(email):
39
+ return email.replace("@","_at_").replace(".","_")
40
+
41
+ def load_cookies(email):
42
+ fn = f"{COOK_DIR}/cookies_{safe(email)}.json"
43
+ if os.path.exists(fn):
44
+ try:
45
+ with open(fn) as f:
46
+ return json.load(f)
47
+ except:
48
+ return None
49
+ return None
50
+
51
+ def save_cookies(email, jar):
52
+ fn = f"{COOK_DIR}/cookies_{safe(email)}.json"
53
+ with open(fn,"w") as f:
54
+ json.dump(jar, f)
55
+
56
+ async def fetch(session, url):
57
+ async with session.get(url, timeout=30) as r:
58
+ return await r.text()
59
+
60
+ async def post(session, url, data):
61
+ async with session.post(url, data=data, timeout=30) as r:
62
+ return await r.text()
63
+
64
+ def parse(html):
65
+ soup = BeautifulSoup(html, "html.parser")
66
+
67
+ success = soup.find("div", class_=re.compile("alert.*success"))
68
+ msg = success.get_text(strip=True) if success else None
69
+
70
+ cd = soup.find(id="countdown-text")
71
+ sec = None
72
+ if cd:
73
+ m = re.search(r"(\d+)", cd.get_text(strip=True))
74
+ if m:
75
+ sec = int(m.group(1))
76
+
77
+ has_address = soup.find("input", {"name": "address"}) is not None
78
+ has_verify = soup.find("input", {"name": "verify"}) is not None
79
+
80
+ return msg, sec, has_address, has_verify
81
+
82
+ def parse_spin(html):
83
+ soup = BeautifulSoup(html, "html.parser")
84
+
85
+ b = soup.find("b")
86
+ if b and b.get_text(strip=True).isdigit():
87
+ return ("reward", int(b.get_text(strip=True)))
88
+
89
+ txt = soup.get_text(" ", strip=True)
90
+
91
+ r = re.search(r"You won\s+(\d+)\s+satoshi", txt, re.I)
92
+ if r:
93
+ return ("reward", int(r.group(1)))
94
+
95
+ cd = re.search(r"(\d+)m\s*(\d+)s", txt)
96
+ if cd:
97
+ return ("cooldown", int(cd.group(1))*60 + int(cd.group(2)))
98
+
99
+ js = re.search(r"remaining\s*=\s*(\d+)", html)
100
+ if js:
101
+ return ("cooldown", int(js.group(1)))
102
+
103
+ return ("unknown", None)
104
+
105
+ def get_spin_token(html):
106
+ soup = BeautifulSoup(html, "html.parser")
107
+ token_input = soup.find("input", {"name": "token"})
108
+
109
+ if token_input:
110
+ return token_input.get("value")
111
+ else:
112
+ return "50000" # default token agar tidak error
113
+
114
+
115
+ async def worker(email):
116
+ global TOTAL_SUCCESS
117
+ print(f"[START] {email}")
118
+
119
+ async with aiohttp.ClientSession(
120
+ headers=HEADERS,
121
+ cookie_jar=aiohttp.CookieJar()
122
+ ) as session:
123
+
124
+ ck = load_cookies(email)
125
+ if ck:
126
+ session.cookie_jar.update_cookies(ck)
127
+
128
+ success_count = 0
129
+
130
+ while True:
131
+ try:
132
+ now = datetime.now().strftime("%H:%M:%S")
133
+ html = await fetch(session, URL_FAUCET + "?after_verify=1")
134
+ msg, sec, has_address, has_verify = parse(html)
135
+
136
+ if msg and ("sent" in msg.lower()):
137
+ success_count += 1
138
+ async with TOTAL_LOCK:
139
+ TOTAL_SUCCESS += 1
140
+ global_total = TOTAL_SUCCESS
141
+
142
+ print(f"[{now}] {email} β†’ {GREEN}{msg}{RESET} "
143
+ f"+ Timer {sec or 0}s "
144
+ f"(Email: {success_count} | Global: {global_total})")
145
+
146
+ cookies = session.cookie_jar.filter_cookies(URL(BASE))
147
+ save_cookies(email, {k: v.value for k, v in cookies.items()})
148
+
149
+
150
+
151
+ await asyncio.sleep((sec or 2) + 2)
152
+ continue
153
+
154
+ if has_address:
155
+ print(f"[{now}] {email} β†’ Session expired β†’ STEP 1")
156
+ await post(session, URL_FAUCET, {"address": email})
157
+ await asyncio.sleep(1)
158
+ continue
159
+
160
+ if has_verify:
161
+ print(f"[{now}] {email} β†’ Server minta verify β†’ STEP 2")
162
+ await post(session, URL_FAUCET, {"verify": "1"})
163
+ await asyncio.sleep(1)
164
+ continue
165
+
166
+ if sec and sec > 0:
167
+ print(f"[{now}] {email} β†’ Timer {sec}s")
168
+ await asyncio.sleep(sec + 2)
169
+ continue
170
+
171
+ print(f"[{now}] {email} β†’ Claiming...")
172
+ html = await post(session,
173
+ URL_FAUCET + "?after_verify=1",
174
+ {"verify": "1"})
175
+ msg, sec, _, _ = parse(html)
176
+ sec = sec or 0
177
+
178
+ print(f"[{now}] {email} β†’ {GREEN}{msg}{RESET} + Timer {sec}s")
179
+
180
+ cookies = session.cookie_jar.filter_cookies(URL(BASE))
181
+ save_cookies(email, {k: v.value for k, v in cookies.items()})
182
+
183
+ await asyncio.sleep(3)
184
+
185
+ except Exception as e:
186
+ print(f"{email} ERROR: {e}")
187
+ await asyncio.sleep(5)
188
+
189
+ async def main():
190
+ tasks = [asyncio.create_task(worker(email)) for email in EMAILS]
191
+ await asyncio.gather(*tasks)
192
+
193
+ if __name__ == "__main__":
194
+ asyncio.run(main())
docker-compose.yml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ version: '3.8'
2
+
3
+ services:
4
+ multi-coin-bot:
5
+ build: .
6
+ container_name: multi-coin-faucet-bot
7
+ restart: unless-stopped
8
+ volumes:
9
+ - ./logs:/app/logs
10
+ - ./data:/app/data
11
+ environment:
12
+ - TZ=Asia/Jakarta
13
+ - EMAIL=gi2h27@gmail.com
14
+ - MAX_CYCLES=100000
15
+ - SOLVER_URL=https://gi2h-xxx.hf.space
16
+ - SOLVER_KEY=00000000000000000000#0000000000000000000#000000000000000000#
17
+ - PYTHONUNBUFFERED=1
18
+ logging:
19
+ driver: "json-file"
20
+ options:
21
+ max-size: "10m"
22
+ max-file: "3"
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ requests==2.31.0
2
+ colorama==0.4.6
3
+ python-dotenv==1.0.0
4
+ aiohttp
5
+ beautifulsoup4