├── auths.txt ├── config.json ├── requirements.txt ├── README.md └── app.py /auths.txt: -------------------------------------------------------------------------------- 1 | 1423666216438075443,MTQyODE5OTc1NDA2MzY3OTYyMQ.AaFbNl7SBTIB2nH4AqW7oM6Y30Dqlm,TRSy94hKK5VczMA2tBqYE6KrJ1fYnW 2 | 1375802098821627926,MTQyODE5OTc1NDA2MzY3OTYyMQ.QgOdipLcluOyatkYR18xHV5lTBLMyw,UvE16B3kNlOQOYYkpw7gGzzQ3Lvrco 3 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "token": "YOUR_BOT_TOKEN", 3 | "secret": "YOUR_BOT_SECRET", 4 | "id": "YOUR_BOT_CLIENT_ID", 5 | "redirect": "http://127.0.0.1:8000/callback", 6 | "api_endpoint": "https://canary.discord.com/api/v8", 7 | "logs": [ 8 | "YOUR_WEBHOOK_LINK_1", 9 | "YOUR_WEBHOOK_LINK_2" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | aiohappyeyeballs==2.6.1 2 | aiohttp==3.13.0 3 | aiosignal==1.4.0 4 | annotated-types==0.7.0 5 | anyio==4.11.0 6 | attrs==25.4.0 7 | certifi==2025.10.5 8 | charset-normalizer==3.4.4 9 | click==8.3.0 10 | colorama==0.4.6 11 | discord==2.3.2 12 | discord.py==2.6.4 13 | fastapi==0.119.0 14 | frozenlist==1.8.0 15 | h11==0.16.0 16 | idna==3.11 17 | multidict==6.7.0 18 | propcache==0.4.1 19 | pydantic==2.12.2 20 | pydantic_core==2.41.4 21 | requests==2.32.5 22 | sniffio==1.3.1 23 | starlette==0.48.0 24 | typing-inspection==0.4.2 25 | typing_extensions==4.15.0 26 | urllib3==2.5.0 27 | uvicorn==0.37.0 28 | yarl==1.22.0 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Authix v3 2 | 3 | **Authix v3** by **Rubin B (pygod7)** is a **fast, async Discord bot** built with **FastAPI**, designed for **member backup and restoration using stored tokens (auths)**. This streamlined version focuses on speed and simplicity. Older versions (v1, v2) can be found in my [rubinexe](https://github.com/rubinexe) repository. 4 | 5 | --- 6 | 7 | ## Features 8 | 9 | * 💾 **Member Backup**: Save Discord members' tokens safely. 10 | * 🔄 **Member Restoration**: Re-add backed-up members to any server. 11 | * ⚡ **Fully Async**: FastAPI-powered for fast operations. 12 | * 🛠 **Lightweight**: Minimal and focused on handling auths. 13 | 14 | --- 15 | 16 | ## Installation 17 | 18 | ```bash 19 | # Clone the repository 20 | git clone https://github.com/pygod139/Authix.git 21 | cd Authix 22 | 23 | # Install dependencies 24 | pip install -r requirements.txt 25 | ``` 26 | 27 | --- 28 | 29 | ## Configuration 30 | 31 | * Simply fill out `config.json` with your bot details. No additional setup is needed. 32 | 33 | --- 34 | 35 | ## Usage 36 | 37 | ```bash 38 | # Run the bot 39 | python app.py 40 | ``` 41 | 42 | ### Bot Commands 43 | 44 | | Command | Description | 45 | | ---------------- | -------------------------------- | 46 | | `!help` | Show help message | 47 | | `!pull ` | Pull specified number of members | 48 | | `!refresh` | Refresh tokens | 49 | | `!count` | Show token count | 50 | 51 | --- 52 | 53 | ## Contributing 54 | 55 | 1. Fork the repository. 56 | 2. Create a branch (`git checkout -b feature-name`). 57 | 3. Commit your changes (`git commit -am 'Add new feature'`). 58 | 4. Push branch (`git push origin feature-name`). 59 | 5. Open a Pull Request. 60 | 61 | --- 62 | 63 | ## Disclaimer 64 | 65 | **Authix v3** is intended solely for **controlled member backup and restoration**. Misuse for spamming or unauthorized member adding may violate Discord's Terms of Service. 66 | -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | import discord 2 | import requests 3 | import json 4 | import fastapi 5 | import uvicorn 6 | import os 7 | import multiprocessing 8 | import random 9 | import time 10 | import asyncio 11 | import urllib.parse 12 | import datetime 13 | 14 | from discord.ext import commands 15 | from multiprocessing import Process 16 | from fastapi import Query 17 | from fastapi.responses import HTMLResponse 18 | 19 | #$ load stuff 20 | with open('config.json', 'r') as f: 21 | stuff = json.load(f) 22 | 23 | token = stuff.get('token') 24 | secret = stuff.get('secret') 25 | id = stuff.get('id') 26 | redirect = stuff.get('redirect') 27 | api = stuff.get('api_endpoint') 28 | logs = stuff.get('logs') 29 | 30 | #$ define fastapi and discord bot 31 | app = fastapi.FastAPI() 32 | intents = discord.Intents.all() 33 | client = commands.Bot(command_prefix='!', intents=intents) 34 | client.remove_command('help') 35 | 36 | @client.event 37 | async def on_ready(): 38 | os.system('cls || clear') 39 | print(f"connected as: {client.user}") 40 | 41 | def run_fastapi(): 42 | uvicorn.run("app:app", reload=True) 43 | #$if you are hosting it on a server, comment out the above line and config the below line and remove the comment of the below line! 44 | #uvicorn.run("app:app",host='0.0.0.0',port=your-port-number-here, reload=True) 45 | 46 | def keep_alive(): 47 | Process(target=run_fastapi).start() 48 | 49 | @client.command() 50 | async def count(ctx): 51 | unique_count = 0 52 | if os.path.exists('auths.txt'): 53 | with open('auths.txt', 'r') as f: 54 | unique_users = set() 55 | for line in f: 56 | try: 57 | user_id, _, _ = line.strip().split(',') 58 | unique_users.add(user_id) 59 | except: 60 | continue 61 | unique_count = len(unique_users) 62 | 63 | embed = discord.Embed( 64 | title="🔢 auth count", 65 | description=f"total unique auths: {unique_count}", 66 | color=discord.Color.green(), 67 | timestamp=datetime.datetime.now() 68 | ) 69 | embed.set_footer(text="authix bot • premium authentication service", icon_url=client.user.avatar.url if client.user.avatar else None) 70 | embed.set_thumbnail(url="https://img.icons8.com/color/48/000000/counter.png") 71 | await ctx.send(embed=embed) 72 | 73 | @app.get("/") 74 | async def home(): 75 | return "authix working fine!" 76 | 77 | @app.get('/callback') 78 | def authenticate(code=Query(...)): 79 | try: 80 | data = { 81 | 'client_id': id, 82 | 'client_secret': secret, 83 | 'grant_type': 'authorization_code', 84 | 'code': code, 85 | 'redirect_uri': redirect, 86 | 'scope': 'identify guilds.join' 87 | } 88 | 89 | response = requests.post(f'{api}/oauth2/token', data=data) 90 | response.raise_for_status() 91 | details = response.json() 92 | 93 | access_token = details['access_token'] 94 | refresh_token = details['refresh_token'] 95 | 96 | headers = {'Authorization': f'Bearer {access_token}'} 97 | user_info = requests.get(f'{api}/users/@me', headers=headers).json() 98 | user_id = user_info['id'] 99 | username = user_info.get('username', 'unknown') 100 | 101 | lines = [] 102 | if os.path.exists('auths.txt'): 103 | with open('auths.txt', 'r') as file: 104 | lines = file.readlines() 105 | 106 | found = False 107 | for i, line in enumerate(lines): 108 | if line.startswith(f"{user_id},"): 109 | lines[i] = f'{user_id},{access_token},{refresh_token}\n' 110 | found = True 111 | break 112 | 113 | if not found: 114 | lines.append(f'{user_id},{access_token},{refresh_token}\n') 115 | 116 | with open('auths.txt', 'w') as file: 117 | file.writelines(lines) 118 | 119 | embed = discord.Embed( 120 | title="✅ authentication successful", 121 | description=f"welcome to the authix club, {username}!", 122 | color=discord.Color.blue(), 123 | timestamp=datetime.datetime.now() 124 | ) 125 | embed.add_field(name="user id", value=user_id, inline=True) 126 | embed.add_field(name="access token", value=access_token[:20] + "...", inline=True) 127 | embed.set_footer(text="authix • premium authentication service") 128 | embed.set_thumbnail(url="https://img.icons8.com/color/48/000000/check.png") 129 | 130 | hook_url = random.choice(logs) 131 | log_data = {'embeds': [embed.to_dict()]} 132 | requests.post(hook_url, json=log_data) 133 | 134 | html_content = f""" 135 | 136 | authix success 137 | 138 |

✅ authentication successful!

139 |

welcome to the authix club, {username}!

140 |

you can now close this tab.

141 | 142 | 143 | """ 144 | return HTMLResponse(content=html_content) 145 | 146 | except Exception as e: 147 | print(f"auth error: {e}") 148 | embed = discord.Embed( 149 | title="❌ authentication failed", 150 | description=f"an error occurred during authentication: {str(e)}", 151 | color=discord.Color.red(), 152 | timestamp=datetime.datetime.now() 153 | ) 154 | embed.set_footer(text="authix • premium authentication service") 155 | embed.set_thumbnail(url="https://img.icons8.com/color/48/000000/error.png") 156 | 157 | hook_url = random.choice(logs) 158 | log_data = {'embeds': [embed.to_dict()]} 159 | requests.post(hook_url, json=log_data) 160 | 161 | html_content = f""" 162 | 163 | authix error 164 | 165 |

❌ authentication failed

166 |

an error occurred: {str(e)}

167 |

please try again later.

168 | 169 | 170 | """ 171 | return HTMLResponse(content=html_content, status_code=500) 172 | 173 | @client.command(name='refresh') 174 | async def refresh(ctx): 175 | start_time = time.time() 176 | refreshed = [] 177 | failed = [] 178 | 179 | def progress_bar(current, total, length=20): 180 | filled_len = int(length * current // total) 181 | bar = '█' * filled_len + '—' * (length - filled_len) 182 | return f"[{bar}] {current}/{total}" 183 | 184 | try: 185 | if not os.path.exists('auths.txt'): 186 | embed = discord.Embed( 187 | title="⚠️ no auths found", 188 | description="the database is empty. nothing to refresh.", 189 | color=discord.Color.orange(), 190 | timestamp=datetime.datetime.now() 191 | ) 192 | embed.set_footer(text="authix bot • premium authentication service", icon_url=client.user.avatar.url if client.user.avatar else None) 193 | embed.set_thumbnail(url="https://img.icons8.com/color/48/000000/empty-box.png") 194 | await ctx.send(embed=embed) 195 | return 196 | 197 | with open('auths.txt', 'r') as f: 198 | lines = f.readlines() 199 | 200 | unique_tokens = {} 201 | for line in lines: 202 | try: 203 | user_id, access_token, refresh_token = line.strip().split(',') 204 | unique_tokens[user_id] = (access_token, refresh_token) 205 | except: 206 | continue 207 | 208 | total = len(unique_tokens) 209 | if total == 0: 210 | embed = discord.Embed( 211 | title="⚠️ no valid auths found", 212 | description="the database has no valid entries. nothing to refresh.", 213 | color=discord.Color.orange(), 214 | timestamp=datetime.datetime.now() 215 | ) 216 | embed.set_footer(text="authix bot • premium authentication service", icon_url=client.user.avatar.url if client.user.avatar else None) 217 | embed.set_thumbnail(url="https://img.icons8.com/color/48/000000/empty-box.png") 218 | await ctx.send(embed=embed) 219 | return 220 | 221 | new_lines = [] 222 | processed = 0 223 | 224 | progress_embed = discord.Embed( 225 | title="🔄 refreshing tokens", 226 | description=f"progress: {progress_bar(0, total)}\nprocessed: 0/{total}", 227 | color=discord.Color.yellow(), 228 | timestamp=datetime.datetime.now() 229 | ) 230 | progress_embed.set_footer(text="authix bot • premium authentication service", icon_url=client.user.avatar.url if client.user.avatar else None) 231 | progress_embed.set_thumbnail(url="https://img.icons8.com/color/48/000000/refresh.png") 232 | msg = await ctx.send(embed=progress_embed) 233 | 234 | for user_id, (access_token, refresh_token) in unique_tokens.items(): 235 | processed += 1 236 | try: 237 | data = { 238 | 'client_id': id, 239 | 'client_secret': secret, 240 | 'grant_type': 'refresh_token', 241 | 'refresh_token': refresh_token, 242 | } 243 | headers = {'Content-Type': 'application/x-www-form-urlencoded'} 244 | response = requests.post(f'{api}/oauth2/token', data=data, headers=headers) 245 | 246 | if response.status_code in (200, 201): 247 | tokens = response.json() 248 | new_access = tokens['access_token'] 249 | new_refresh = tokens['refresh_token'] 250 | new_lines.append(f'{user_id},{new_access},{new_refresh}\n') 251 | refreshed.append(user_id) 252 | else: 253 | failed.append(user_id) 254 | except Exception as e: 255 | print(f"error refreshing token for user {user_id}: {e}") 256 | failed.append(user_id) 257 | 258 | if processed % 5 == 0 or processed == total: 259 | progress_embed.description = f"progress: {progress_bar(processed, total)}\nprocessed: {processed}/{total}" 260 | progress_embed.timestamp = datetime.datetime.now() 261 | await msg.edit(embed=progress_embed) 262 | await asyncio.sleep(0.1) 263 | 264 | with open('auths.txt', 'w') as f: 265 | f.writelines(new_lines) 266 | 267 | total_time = int(time.time() - start_time) 268 | mins, secs = divmod(total_time, 60) 269 | time_str = f"{mins}m {secs}s" 270 | 271 | embed = discord.Embed( 272 | title="✅ token refresh complete", 273 | description=f"refreshed tokens for {len(refreshed)} users out of {total} in {time_str}\nfailed refreshes: {len(failed)}", 274 | color=discord.Color.green(), 275 | timestamp=datetime.datetime.now() 276 | ) 277 | embed.set_footer(text="authix bot • premium authentication service", icon_url=client.user.avatar.url if client.user.avatar else None) 278 | embed.set_thumbnail(url="https://img.icons8.com/color/48/000000/checked.png") 279 | await ctx.send(embed=embed) 280 | 281 | except Exception as e: 282 | embed = discord.Embed( 283 | title="❌ error during refresh", 284 | description=f"an error occurred during the refresh process: {str(e)}", 285 | color=discord.Color.red(), 286 | timestamp=datetime.datetime.now() 287 | ) 288 | embed.set_footer(text="authix bot • premium authentication service", icon_url=client.user.avatar.url if client.user.avatar else None) 289 | embed.set_thumbnail(url="https://img.icons8.com/color/48/000000/error.png") 290 | await ctx.send(embed=embed) 291 | 292 | @client.command(name='pull') 293 | async def pull(ctx, amount: int): 294 | start_time = time.time() 295 | tries = 0 296 | added = 0 297 | failed = 0 298 | last_users = [] 299 | 300 | def progress_bar(current, total, length=20): 301 | filled_len = int(length * current // total) 302 | bar = '█' * filled_len + '—' * (length - filled_len) 303 | return f"[{bar}] {current}/{total}" 304 | 305 | try: 306 | if not os.path.exists('auths.txt'): 307 | embed = discord.Embed( 308 | title="⚠️ no auths found", 309 | description="the database is empty. nothing to pull.", 310 | color=discord.Color.orange(), 311 | timestamp=datetime.datetime.now() 312 | ) 313 | embed.set_footer(text="authix bot • premium authentication service", icon_url=client.user.avatar.url if client.user.avatar else None) 314 | embed.set_thumbnail(url="https://img.icons8.com/color/48/000000/empty-box.png") 315 | await ctx.send(embed=embed) 316 | return 317 | 318 | with open('auths.txt', 'r') as file: 319 | lines = file.readlines() 320 | 321 | unique_users = {} 322 | for line in lines: 323 | try: 324 | user_id, access_token, refresh_token = line.strip().split(',') 325 | unique_users[user_id] = (access_token, refresh_token) 326 | except: 327 | continue 328 | 329 | user_list = list(unique_users.items()) 330 | random.shuffle(user_list) 331 | total_available = len(user_list) 332 | 333 | progress_embed = discord.Embed( 334 | title=f"🚀 pulling {amount} users into {ctx.guild.name}", 335 | description=f"progress: {progress_bar(0, amount)}\ntries: 0 | added: 0 | failed: 0", 336 | color=discord.Color.blue(), 337 | timestamp=datetime.datetime.now() 338 | ) 339 | progress_embed.set_footer(text="authix bot • premium authentication service", icon_url=client.user.avatar.url if client.user.avatar else None) 340 | progress_embed.set_thumbnail(url="https://img.icons8.com/color/48/000000/download.png") 341 | msg = await ctx.send(embed=progress_embed) 342 | 343 | while added < amount and user_list: 344 | tries += 1 345 | user_id, (access_token, refresh_token) = user_list.pop() 346 | success = add_member_to_guild(ctx.guild.id, user_id, access_token) 347 | if success: 348 | username = await fetch_username(access_token) 349 | last_users.append(f"{username} ({user_id})") 350 | added += 1 351 | else: 352 | failed += 1 353 | 354 | if tries % 5 == 0 or added == amount or not user_list: 355 | progress_embed.description = f"progress: {progress_bar(added, amount)}\ntries: {tries} | added: {added} | failed: {failed}\nlast added: {', '.join(last_users[-5:]) if last_users else 'none'}" 356 | progress_embed.timestamp = datetime.datetime.now() 357 | await msg.edit(embed=progress_embed) 358 | await asyncio.sleep(0.1) 359 | 360 | total_time = int(time.time() - start_time) 361 | mins, secs = divmod(total_time, 60) 362 | time_str = f"{mins}m {secs}s" 363 | 364 | embed = discord.Embed( 365 | title="✅ pull operation complete", 366 | description=f"pulled {added} users into {ctx.guild.name} with {failed} failures after {tries} tries in {time_str}.\nlast added users: {', '.join(last_users[-10:]) if last_users else 'none'}", 367 | color=discord.Color.green(), 368 | timestamp=datetime.datetime.now() 369 | ) 370 | embed.set_footer(text="authix bot • premium authentication service", icon_url=client.user.avatar.url if client.user.avatar else None) 371 | embed.set_thumbnail(url="https://img.icons8.com/color/48/000000/checked.png") 372 | await ctx.send(embed=embed) 373 | 374 | except Exception as e: 375 | embed = discord.Embed( 376 | title="❌ error during pull", 377 | description=f"an error occurred during the pull operation: {str(e)}", 378 | color=discord.Color.red(), 379 | timestamp=datetime.datetime.now() 380 | ) 381 | embed.set_footer(text="authix bot • premium authentication service", icon_url=client.user.avatar.url if client.user.avatar else None) 382 | embed.set_thumbnail(url="https://img.icons8.com/color/48/000000/error.png") 383 | await ctx.send(embed=embed) 384 | 385 | def add_member_to_guild(guild_id, user_id, access_token): 386 | url = f"{api}/guilds/{guild_id}/members/{user_id}" 387 | data = {"access_token": access_token} 388 | headers = { 389 | "Authorization": f"Bot {token}", 390 | "Content-Type": "application/json" 391 | } 392 | try: 393 | response = requests.put(url, headers=headers, json=data) 394 | return response.status_code in (201, 204) 395 | except Exception as e: 396 | print(f"join error: {e}") 397 | return False 398 | 399 | async def fetch_username(access_token): 400 | headers = {'Authorization': f'Bearer {access_token}'} 401 | try: 402 | r = requests.get(f'{api}/users/@me', headers=headers) 403 | if r.status_code == 200: 404 | return r.json()['username'] 405 | return "unknown" 406 | except: 407 | return "unknown" 408 | 409 | @client.command() 410 | async def help(ctx): 411 | embed = discord.Embed( 412 | title="📚 authix bot commands help", 413 | description="here's a premium list of available commands for authix bot:", 414 | color=discord.Color.purple(), 415 | timestamp=datetime.datetime.now() 416 | ) 417 | embed.add_field(name="!count", value="displays the total number of unique auths in the database.", inline=False) 418 | embed.add_field(name="!refresh", value="refreshes tokens for all unique users in the database with progress updates.", inline=False) 419 | embed.add_field(name="!pull ", value="pulls a specified amount of users into your server with live progress.", inline=False) 420 | embed.add_field(name="!auth_link", value="generates the authentication link for users to join.", inline=False) 421 | embed.set_footer(text="authix bot • premium authentication service", icon_url=client.user.avatar.url if client.user.avatar else None) 422 | embed.set_thumbnail(url="https://img.icons8.com/color/48/000000/help.png") 423 | 424 | await ctx.send(embed=embed) 425 | 426 | @client.command(name="auth_link") 427 | async def auth_link(ctx): 428 | params = { 429 | 'client_id': id, 430 | 'response_type': 'code', 431 | 'redirect_uri': redirect, 432 | 'scope': 'identify guilds.join' 433 | } 434 | url = "https://discord.com/oauth2/authorize?" + urllib.parse.urlencode(params) 435 | 436 | embed = discord.Embed( 437 | title="🔗 authentication link", 438 | description="click the link below to authenticate and join the premium authix service:", 439 | color=discord.Color.blue(), 440 | timestamp=datetime.datetime.now() 441 | ) 442 | embed.add_field(name="authenticate here", value=f"[click to authenticate]({url})", inline=False) 443 | embed.set_footer(text="authix bot • premium authentication service", icon_url=client.user.avatar.url if client.user.avatar else None) 444 | embed.set_thumbnail(url="https://img.icons8.com/color/48/000000/link.png") 445 | 446 | await ctx.send(embed=embed) 447 | 448 | #$ start bot and fastapi 449 | if __name__ == "__main__": 450 | keep_alive() 451 | client.run(token, reconnect=True) 452 | 453 | #$ credits 454 | #$ updated by rubin b (fixed all bugs, converted flask -> fastapi) 455 | #$ old version was also made by me (github: rubinexe) 456 | #$ new github: pygod7 457 | #$ give credits if you re-distribute! 458 | --------------------------------------------------------------------------------