imseldrith commited on
Commit
2c59b39
·
verified ·
1 Parent(s): 0df4281

Upload 3 files

Browse files
Files changed (3) hide show
  1. .env +2 -0
  2. bot.py +538 -0
  3. requirements.txt +4 -0
.env ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ USE_PROXY=true
2
+ ROTATE_PROXY=true
bot.py ADDED
@@ -0,0 +1,538 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from aiohttp import (
2
+ ClientResponseError,
3
+ ClientSession,
4
+ ClientTimeout,
5
+ BasicAuth
6
+ )
7
+ from aiohttp_socks import ProxyConnector
8
+ from base64 import urlsafe_b64decode
9
+ from datetime import datetime
10
+ from colorama import *
11
+ import asyncio, time, json, pytz, re, os
12
+
13
+ wib = pytz.timezone('Asia/Jakarta')
14
+
15
+ class Interlink:
16
+ def __init__(self) -> None:
17
+ self.HEADERS = {
18
+ "Accept-Encoding": "*/*",
19
+ "User-Agent": "okhttp/4.12.0",
20
+ "Accept-Encoding": "gzip"
21
+ }
22
+ self.BASE_API = "https://prod.interlinklabs.ai/api/v1"
23
+ self.proxies = []
24
+ self.proxy_index = 0
25
+ self.account_proxies = {}
26
+ self.access_tokens = {}
27
+
28
+ def clear_terminal(self):
29
+ os.system('cls' if os.name == 'nt' else 'clear')
30
+
31
+ def log(self, message):
32
+ print(
33
+ f"{Fore.CYAN + Style.BRIGHT}[ {datetime.now().astimezone(wib).strftime('%x %X %Z')} ]{Style.RESET_ALL}"
34
+ f"{Fore.WHITE + Style.BRIGHT} | {Style.RESET_ALL}{message}",
35
+ flush=True
36
+ )
37
+
38
+ def welcome(self):
39
+ print(
40
+ f"""
41
+ {Fore.GREEN + Style.BRIGHT}Auto Claim {Fore.BLUE + Style.BRIGHT}Interlink - BOT
42
+ """
43
+ f"""
44
+ {Fore.GREEN + Style.BRIGHT}Rey? {Fore.YELLOW + Style.BRIGHT}<INI WATERMARK>
45
+ """
46
+ )
47
+
48
+ def format_seconds(self, seconds):
49
+ hours, remainder = divmod(seconds, 3600)
50
+ minutes, seconds = divmod(remainder, 60)
51
+ return f"{int(hours):02}:{int(minutes):02}:{int(seconds):02}"
52
+
53
+ def load_accounts(self):
54
+ filename = "tokens.json"
55
+ env_tokens = os.getenv("TOKENS_JSON")
56
+
57
+ if env_tokens:
58
+ try:
59
+ data = json.loads(env_tokens)
60
+ if isinstance(data, list):
61
+ self.log(
62
+ f"{Fore.GREEN + Style.BRIGHT}Loaded accounts from environment variable TOKENS_JSON.{Style.RESET_ALL}"
63
+ )
64
+ return data
65
+ self.log(
66
+ f"{Fore.RED + Style.BRIGHT}TOKENS_JSON is not a JSON array. No accounts loaded.{Style.RESET_ALL}"
67
+ )
68
+ return []
69
+ except json.JSONDecodeError as exc:
70
+ self.log(
71
+ f"{Fore.RED + Style.BRIGHT}Failed to parse TOKENS_JSON: {exc}.{Style.RESET_ALL}"
72
+ )
73
+ return []
74
+
75
+ try:
76
+ if not os.path.exists(filename):
77
+ self.log(f"{Fore.RED}File {filename} Not Found.{Style.RESET_ALL}")
78
+ return []
79
+
80
+ with open(filename, 'r') as file:
81
+ data = json.load(file)
82
+ if isinstance(data, list):
83
+ return data
84
+ self.log(
85
+ f"{Fore.RED + Style.BRIGHT}{filename} does not contain a JSON array. No accounts loaded.{Style.RESET_ALL}"
86
+ )
87
+ return []
88
+ except json.JSONDecodeError as exc:
89
+ self.log(
90
+ f"{Fore.RED + Style.BRIGHT}Failed to parse {filename}: {exc}.{Style.RESET_ALL}"
91
+ )
92
+ return []
93
+
94
+ async def load_proxies(self):
95
+ filename = "proxy.txt"
96
+ try:
97
+ env_proxies = os.getenv("PROXIES")
98
+ if env_proxies:
99
+ self.proxies = self.parse_env_list(env_proxies)
100
+ source = "environment variable PROXIES"
101
+ else:
102
+ if not os.path.exists(filename):
103
+ self.log(f"{Fore.RED + Style.BRIGHT}File {filename} Not Found.{Style.RESET_ALL}")
104
+ return
105
+ with open(filename, 'r') as f:
106
+ self.proxies = [line.strip() for line in f.read().splitlines() if line.strip()]
107
+ source = filename
108
+
109
+ if not self.proxies:
110
+ self.log(f"{Fore.RED + Style.BRIGHT}No Proxies Found.{Style.RESET_ALL}")
111
+ return
112
+
113
+ self.log(
114
+ f"{Fore.GREEN + Style.BRIGHT}Proxies Total : {Style.RESET_ALL}"
115
+ f"{Fore.WHITE + Style.BRIGHT}{len(self.proxies)}{Style.RESET_ALL}"
116
+ f"{Fore.GREEN + Style.BRIGHT} (from {source}){Style.RESET_ALL}"
117
+ )
118
+
119
+ except Exception as e:
120
+ self.log(f"{Fore.RED + Style.BRIGHT}Failed To Load Proxies: {e}{Style.RESET_ALL}")
121
+ self.proxies = []
122
+
123
+ def check_proxy_schemes(self, proxies):
124
+ schemes = ["http://", "https://", "socks4://", "socks5://"]
125
+ if any(proxies.startswith(scheme) for scheme in schemes):
126
+ return proxies
127
+ return f"http://{proxies}"
128
+
129
+ def get_next_proxy_for_account(self, account):
130
+ if account not in self.account_proxies:
131
+ if not self.proxies:
132
+ return None
133
+ proxy = self.check_proxy_schemes(self.proxies[self.proxy_index])
134
+ self.account_proxies[account] = proxy
135
+ self.proxy_index = (self.proxy_index + 1) % len(self.proxies)
136
+ return self.account_proxies[account]
137
+
138
+ def rotate_proxy_for_account(self, account):
139
+ if not self.proxies:
140
+ return None
141
+ proxy = self.check_proxy_schemes(self.proxies[self.proxy_index])
142
+ self.account_proxies[account] = proxy
143
+ self.proxy_index = (self.proxy_index + 1) % len(self.proxies)
144
+ return proxy
145
+
146
+ def build_proxy_config(self, proxy=None):
147
+ if not proxy:
148
+ return None, None, None
149
+
150
+ if proxy.startswith("socks"):
151
+ connector = ProxyConnector.from_url(proxy)
152
+ return connector, None, None
153
+
154
+ elif proxy.startswith("http"):
155
+ match = re.match(r"http://(.*?):(.*?)@(.*)", proxy)
156
+ if match:
157
+ username, password, host_port = match.groups()
158
+ clean_url = f"http://{host_port}"
159
+ auth = BasicAuth(username, password)
160
+ return None, clean_url, auth
161
+ else:
162
+ return None, proxy, None
163
+
164
+ raise Exception("Unsupported Proxy Type.")
165
+
166
+ def decode_token(self, token: str):
167
+ try:
168
+ header, payload, signature = token.split(".")
169
+ decoded_payload = urlsafe_b64decode(payload + "==").decode("utf-8")
170
+ parsed_payload = json.loads(decoded_payload)
171
+ exp_time = parsed_payload["exp"]
172
+
173
+ return exp_time
174
+ except Exception as e:
175
+ return None
176
+
177
+ def mask_account(self, account):
178
+ if "@" in account:
179
+ local, domain = account.split('@', 1)
180
+ mask_account = local[:3] + '*' * 3 + local[-3:]
181
+ return f"{mask_account}@{domain}"
182
+
183
+ def parse_env_list(self, raw: str):
184
+ items = []
185
+ if not raw:
186
+ return items
187
+
188
+ normalized = raw.replace("\r\n", "\n")
189
+ for line in normalized.split("\n"):
190
+ for part in line.split(","):
191
+ candidate = part.strip()
192
+ if candidate:
193
+ items.append(candidate)
194
+ return items
195
+
196
+ def get_env_bool(self, name: str, default=None):
197
+ value = os.getenv(name)
198
+ if value is None:
199
+ return default
200
+ value = value.strip().lower()
201
+ if value in {"1", "true", "yes", "y"}:
202
+ return True
203
+ if value in {"0", "false", "no", "n"}:
204
+ return False
205
+ return default
206
+
207
+ def print_question(self):
208
+ while True:
209
+ try:
210
+ print(f"{Fore.WHITE + Style.BRIGHT}1. Run With Proxy{Style.RESET_ALL}")
211
+ print(f"{Fore.WHITE + Style.BRIGHT}2. Run Without Proxy{Style.RESET_ALL}")
212
+ proxy_choice = int(input(f"{Fore.BLUE + Style.BRIGHT}Choose [1/2] -> {Style.RESET_ALL}").strip())
213
+
214
+ if proxy_choice in [1, 2]:
215
+ proxy_type = (
216
+ "With" if proxy_choice == 1 else
217
+ "Without"
218
+ )
219
+ print(f"{Fore.GREEN + Style.BRIGHT}Run {proxy_type} Proxy Selected.{Style.RESET_ALL}")
220
+ break
221
+ else:
222
+ print(f"{Fore.RED + Style.BRIGHT}Please enter either 1 or 2.{Style.RESET_ALL}")
223
+ except ValueError:
224
+ print(f"{Fore.RED + Style.BRIGHT}Invalid input. Enter a number (1 or 2).{Style.RESET_ALL}")
225
+
226
+ rotate_proxy = False
227
+ if proxy_choice == 1:
228
+ while True:
229
+ rotate_proxy = input(f"{Fore.BLUE + Style.BRIGHT}Rotate Invalid Proxy? [y/n] -> {Style.RESET_ALL}").strip()
230
+ if rotate_proxy in ["y", "n"]:
231
+ rotate_proxy = rotate_proxy == "y"
232
+ break
233
+ else:
234
+ print(f"{Fore.RED + Style.BRIGHT}Invalid input. Enter 'y' or 'n'.{Style.RESET_ALL}")
235
+
236
+ return proxy_choice, rotate_proxy
237
+
238
+ async def check_connection(self, proxy_url=None):
239
+ connector, proxy, proxy_auth = self.build_proxy_config(proxy_url)
240
+ try:
241
+ async with ClientSession(connector=connector, timeout=ClientTimeout(total=10)) as session:
242
+ async with session.get(url="https://api.ipify.org?format=json", proxy=proxy, proxy_auth=proxy_auth) as response:
243
+ response.raise_for_status()
244
+ return True
245
+ except (Exception, ClientResponseError) as e:
246
+ self.log(
247
+ f"{Fore.CYAN+Style.BRIGHT}Status :{Style.RESET_ALL}"
248
+ f"{Fore.RED+Style.BRIGHT} Connection Not 200 OK {Style.RESET_ALL}"
249
+ f"{Fore.MAGENTA+Style.BRIGHT}-{Style.RESET_ALL}"
250
+ f"{Fore.YELLOW+Style.BRIGHT} {str(e)} {Style.RESET_ALL}"
251
+ )
252
+ return None
253
+
254
+ async def token_balance(self, email: str, proxy_url=None, retries=5):
255
+ url = f"{self.BASE_API}/token/get-token"
256
+ headers = {
257
+ **self.HEADERS,
258
+ "Authorization": f"Bearer {self.access_tokens[email]}"
259
+ }
260
+ await asyncio.sleep(3)
261
+ for attempt in range(retries):
262
+ connector, proxy, proxy_auth = self.build_proxy_config(proxy_url)
263
+ try:
264
+ async with ClientSession(connector=connector, timeout=ClientTimeout(total=60)) as session:
265
+ async with session.get(url=url, headers=headers, proxy=proxy, proxy_auth=proxy_auth, ssl=False) as response:
266
+ response.raise_for_status()
267
+ return await response.json()
268
+ except (Exception, ClientResponseError) as e:
269
+ if attempt < retries - 1:
270
+ await asyncio.sleep(5)
271
+ continue
272
+ self.log(
273
+ f"{Fore.CYAN+Style.BRIGHT}Balance:{Style.RESET_ALL}"
274
+ f"{Fore.RED+Style.BRIGHT} GET Token Earned Failed {Style.RESET_ALL}"
275
+ f"{Fore.MAGENTA+Style.BRIGHT}-{Style.RESET_ALL}"
276
+ f"{Fore.YELLOW+Style.BRIGHT} {str(e)} {Style.RESET_ALL}"
277
+ )
278
+
279
+ return None
280
+
281
+ async def claimable_check(self, email: str, proxy_url=None, retries=5):
282
+ url = f"{self.BASE_API}/token/check-is-claimable"
283
+ headers = {
284
+ **self.HEADERS,
285
+ "Authorization": f"Bearer {self.access_tokens[email]}"
286
+ }
287
+ await asyncio.sleep(3)
288
+ for attempt in range(retries):
289
+ connector, proxy, proxy_auth = self.build_proxy_config(proxy_url)
290
+ try:
291
+ async with ClientSession(connector=connector, timeout=ClientTimeout(total=60)) as session:
292
+ async with session.get(url=url, headers=headers, proxy=proxy, proxy_auth=proxy_auth, ssl=False) as response:
293
+ response.raise_for_status()
294
+ return await response.json()
295
+ except (Exception, ClientResponseError) as e:
296
+ if attempt < retries - 1:
297
+ await asyncio.sleep(5)
298
+ continue
299
+ self.log(
300
+ f"{Fore.CYAN+Style.BRIGHT}Mining :{Style.RESET_ALL}"
301
+ f"{Fore.RED+Style.BRIGHT} GET Status Failed {Style.RESET_ALL}"
302
+ f"{Fore.MAGENTA+Style.BRIGHT}-{Style.RESET_ALL}"
303
+ f"{Fore.YELLOW+Style.BRIGHT} {str(e)} {Style.RESET_ALL}"
304
+ )
305
+
306
+ return None
307
+
308
+ async def claim_airdrop(self, email: str, proxy_url=None, retries=1):
309
+ url = f"{self.BASE_API}/token/claim-airdrop"
310
+ headers = {
311
+ **self.HEADERS,
312
+ "Authorization": f"Bearer {self.access_tokens[email]}",
313
+ "Content-Length": "2",
314
+ "Content-Type": "application/json"
315
+ }
316
+ await asyncio.sleep(3)
317
+ for attempt in range(retries):
318
+ connector, proxy, proxy_auth = self.build_proxy_config(proxy_url)
319
+ try:
320
+ async with ClientSession(connector=connector, timeout=ClientTimeout(total=60)) as session:
321
+ async with session.post(url=url, headers=headers, json={}, proxy=proxy, proxy_auth=proxy_auth, ssl=False) as response:
322
+ response.raise_for_status()
323
+ return await response.json()
324
+ except (Exception, ClientResponseError) as e:
325
+ if attempt < retries - 1:
326
+ await asyncio.sleep(5)
327
+ continue
328
+ self.log(
329
+ f"{Fore.CYAN+Style.BRIGHT}Mining :{Style.RESET_ALL}"
330
+ f"{Fore.RED+Style.BRIGHT} Not Claimed {Style.RESET_ALL}"
331
+ f"{Fore.MAGENTA+Style.BRIGHT}-{Style.RESET_ALL}"
332
+ f"{Fore.YELLOW+Style.BRIGHT} {str(e)} {Style.RESET_ALL}"
333
+ )
334
+
335
+ return None
336
+
337
+ async def process_check_connection(self, email: str, use_proxy: bool, rotate_proxy: bool):
338
+ while True:
339
+ proxy = self.get_next_proxy_for_account(email) if use_proxy else None
340
+ self.log(
341
+ f"{Fore.CYAN+Style.BRIGHT}Proxy :{Style.RESET_ALL}"
342
+ f"{Fore.WHITE+Style.BRIGHT} {proxy if proxy else 'No Proxy'} {Style.RESET_ALL}"
343
+ )
344
+
345
+ is_valid = await self.check_connection(proxy)
346
+ if is_valid: return True
347
+
348
+ if rotate_proxy:
349
+ proxy = self.rotate_proxy_for_account(email)
350
+ await asyncio.sleep(1)
351
+ continue
352
+
353
+ return False
354
+
355
+ async def process_accounts(self, email: str, use_proxy: bool, rotate_proxy: bool):
356
+ is_valid = await self.process_check_connection(email, use_proxy, rotate_proxy)
357
+ if not is_valid: return
358
+
359
+ proxy = self.get_next_proxy_for_account(email) if use_proxy else None
360
+
361
+ balance = await self.token_balance(email, proxy)
362
+ if balance:
363
+ token_balance = balance.get("data", {}).get("interlinkTokenAmount", 0)
364
+ silver_balance = balance.get("data", {}).get("interlinkSilverTokenAmount", 0)
365
+ gold_balance = balance.get("data", {}).get("interlinkGoldTokenAmount", 0)
366
+ diamond_balance = balance.get("data", {}).get("interlinkDiamondTokenAmount", 0)
367
+
368
+ self.log(f"{Fore.CYAN+Style.BRIGHT}Balance:{Style.RESET_ALL}")
369
+ self.log(
370
+ f"{Fore.MAGENTA+Style.BRIGHT} ● {Style.RESET_ALL}"
371
+ f"{Fore.BLUE+Style.BRIGHT}Interlink:{Style.RESET_ALL}"
372
+ f"{Fore.WHITE+Style.BRIGHT} {token_balance} {Style.RESET_ALL}"
373
+ )
374
+ self.log(
375
+ f"{Fore.MAGENTA+Style.BRIGHT} ● {Style.RESET_ALL}"
376
+ f"{Fore.BLUE+Style.BRIGHT}Silver :{Style.RESET_ALL}"
377
+ f"{Fore.WHITE+Style.BRIGHT} {silver_balance} {Style.RESET_ALL}"
378
+ )
379
+ self.log(
380
+ f"{Fore.MAGENTA+Style.BRIGHT} ● {Style.RESET_ALL}"
381
+ f"{Fore.BLUE+Style.BRIGHT}Gold :{Style.RESET_ALL}"
382
+ f"{Fore.WHITE+Style.BRIGHT} {gold_balance} {Style.RESET_ALL}"
383
+ )
384
+ self.log(
385
+ f"{Fore.MAGENTA+Style.BRIGHT} ● {Style.RESET_ALL}"
386
+ f"{Fore.BLUE+Style.BRIGHT}Diamond :{Style.RESET_ALL}"
387
+ f"{Fore.WHITE+Style.BRIGHT} {diamond_balance} {Style.RESET_ALL}"
388
+ )
389
+
390
+ claimable = await self.claimable_check(email, proxy)
391
+ if claimable:
392
+ is_claimable = claimable.get("data", {}).get("isClaimable", False)
393
+
394
+ if is_claimable:
395
+ claim = await self.claim_airdrop(email, proxy)
396
+ if claim:
397
+ reward = claim.get("data") or "N/A"
398
+
399
+ self.log(
400
+ f"{Fore.CYAN+Style.BRIGHT}Mining :{Style.RESET_ALL}"
401
+ f"{Fore.GREEN+Style.BRIGHT} Claimed Successfully {Style.RESET_ALL}"
402
+ f"{Fore.MAGENTA+Style.BRIGHT}-{Style.RESET_ALL}"
403
+ f"{Fore.CYAN+Style.BRIGHT} Reward: {Style.RESET_ALL}"
404
+ f"{Fore.WHITE+Style.BRIGHT}{reward}{Style.RESET_ALL}"
405
+ )
406
+
407
+ else:
408
+ next_frame_ts = claimable.get("data", {}).get("nextFrame", 0) / 1000
409
+ next_frame_wib = datetime.fromtimestamp(next_frame_ts).astimezone(wib).strftime('%x %X %Z')
410
+
411
+ self.log(
412
+ f"{Fore.CYAN+Style.BRIGHT}Mining :{Style.RESET_ALL}"
413
+ f"{Fore.YELLOW+Style.BRIGHT} Already Claimed {Style.RESET_ALL}"
414
+ f"{Fore.MAGENTA+Style.BRIGHT}-{Style.RESET_ALL}"
415
+ f"{Fore.CYAN+Style.BRIGHT} Next Claim at: {Style.RESET_ALL}"
416
+ f"{Fore.WHITE+Style.BRIGHT}{next_frame_wib}{Style.RESET_ALL}"
417
+ )
418
+
419
+ async def main(self):
420
+ try:
421
+ accounts = self.load_accounts()
422
+ if not accounts:
423
+ self.log(f"{Fore.RED}No Accounts Loaded.{Style.RESET_ALL}")
424
+ return
425
+
426
+ env_use_proxy = self.get_env_bool("USE_PROXY")
427
+ env_rotate_proxy = self.get_env_bool("ROTATE_PROXY")
428
+
429
+ if env_use_proxy is None:
430
+ proxy_choice, rotate_proxy = self.print_question()
431
+ use_proxy = proxy_choice == 1
432
+ else:
433
+ use_proxy = bool(env_use_proxy)
434
+ rotate_proxy = use_proxy and (
435
+ env_rotate_proxy if env_rotate_proxy is not None else True
436
+ )
437
+ mode_text = "With Proxy" if use_proxy else "Without Proxy"
438
+ source_text = "environment variables"
439
+ self.log(
440
+ f"{Fore.GREEN + Style.BRIGHT}Run {mode_text} Selected via {source_text}.{Style.RESET_ALL}"
441
+ )
442
+
443
+ if not use_proxy:
444
+ rotate_proxy = False
445
+ elif rotate_proxy:
446
+ self.log(
447
+ f"{Fore.GREEN + Style.BRIGHT}Invalid proxy auto-rotation enabled.{Style.RESET_ALL}"
448
+ )
449
+ else:
450
+ self.log(
451
+ f"{Fore.YELLOW + Style.BRIGHT}Invalid proxy auto-rotation disabled.{Style.RESET_ALL}"
452
+ )
453
+
454
+ while True:
455
+ self.clear_terminal()
456
+ self.welcome()
457
+ self.log(
458
+ f"{Fore.GREEN + Style.BRIGHT}Account's Total: {Style.RESET_ALL}"
459
+ f"{Fore.WHITE + Style.BRIGHT}{len(accounts)}{Style.RESET_ALL}"
460
+ )
461
+
462
+ if use_proxy:
463
+ await self.load_proxies()
464
+
465
+ separator = "=" * 27
466
+ for idx, account in enumerate(accounts, start=1):
467
+ if account:
468
+ email = account["email"]
469
+ token = account["token"]
470
+ self.log(
471
+ f"{Fore.CYAN + Style.BRIGHT}{separator}[{Style.RESET_ALL}"
472
+ f"{Fore.WHITE + Style.BRIGHT} {idx} {Style.RESET_ALL}"
473
+ f"{Fore.CYAN + Style.BRIGHT}Of{Style.RESET_ALL}"
474
+ f"{Fore.WHITE + Style.BRIGHT} {len(accounts)} {Style.RESET_ALL}"
475
+ f"{Fore.CYAN + Style.BRIGHT}]{separator}{Style.RESET_ALL}"
476
+ )
477
+
478
+ if not "@" in email or not token:
479
+ self.log(
480
+ f"{Fore.CYAN+Style.BRIGHT}Status :{Style.RESET_ALL}"
481
+ f"{Fore.RED+Style.BRIGHT} Invalid Account Data {Style.RESET_ALL}"
482
+ )
483
+ continue
484
+
485
+ self.log(
486
+ f"{Fore.CYAN+Style.BRIGHT}Account:{Style.RESET_ALL}"
487
+ f"{Fore.WHITE+Style.BRIGHT} {self.mask_account(email)} {Style.RESET_ALL}"
488
+ )
489
+
490
+ exp_time = self.decode_token(token)
491
+ if not exp_time:
492
+ self.log(
493
+ f"{Fore.CYAN+Style.BRIGHT}Status :{Style.RESET_ALL}"
494
+ f"{Fore.RED+Style.BRIGHT} Invalid Token {Style.RESET_ALL}"
495
+ )
496
+ continue
497
+
498
+ if int(time.time()) > exp_time:
499
+ self.log(
500
+ f"{Fore.CYAN+Style.BRIGHT}Status :{Style.RESET_ALL}"
501
+ f"{Fore.RED+Style.BRIGHT} Token Already Expired {Style.RESET_ALL}"
502
+ )
503
+ continue
504
+
505
+ self.access_tokens[email] = token
506
+
507
+ await self.process_accounts(email, use_proxy, rotate_proxy)
508
+ await asyncio.sleep(3)
509
+
510
+ self.log(f"{Fore.CYAN + Style.BRIGHT}={Style.RESET_ALL}"*65)
511
+ seconds = 4 * 60 * 60
512
+ while seconds > 0:
513
+ formatted_time = self.format_seconds(seconds)
514
+ print(
515
+ f"{Fore.CYAN+Style.BRIGHT}[ Wait for{Style.RESET_ALL}"
516
+ f"{Fore.WHITE+Style.BRIGHT} {formatted_time} {Style.RESET_ALL}"
517
+ f"{Fore.CYAN+Style.BRIGHT}... ]{Style.RESET_ALL}"
518
+ f"{Fore.WHITE+Style.BRIGHT} | {Style.RESET_ALL}"
519
+ f"{Fore.BLUE+Style.BRIGHT}All Accounts Have Been Processed...{Style.RESET_ALL}",
520
+ end="\r"
521
+ )
522
+ await asyncio.sleep(1)
523
+ seconds -= 1
524
+
525
+ except Exception as e:
526
+ self.log(f"{Fore.RED+Style.BRIGHT}Error: {e}{Style.RESET_ALL}")
527
+ raise e
528
+
529
+ if __name__ == "__main__":
530
+ try:
531
+ bot = Interlink()
532
+ asyncio.run(bot.main())
533
+ except KeyboardInterrupt:
534
+ print(
535
+ f"{Fore.CYAN + Style.BRIGHT}[ {datetime.now().astimezone(wib).strftime('%x %X %Z')} ]{Style.RESET_ALL}"
536
+ f"{Fore.WHITE + Style.BRIGHT} | {Style.RESET_ALL}"
537
+ f"{Fore.RED + Style.BRIGHT}[ EXIT ] Interlink - BOT{Style.RESET_ALL} "
538
+ )
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ aiohttp==3.11.10
2
+ aiohttp-socks==0.9.1
3
+ colorama==0.4.6
4
+ pytz==2024.1