├── LICENSE ├── README.md ├── config └── config.json ├── img ├── astraa.gif └── transparent.png ├── main.py ├── requirements.txt └── setup.bat /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 a5traa 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |

3 | 4 |

5 | 6 |

[Discord] - SelfBot (V2.1)

7 |

8 | 9 | 10 | 11 | 12 | 13 | 14 |

15 | 16 |

17 | [Discord] - SelfBot is a feature-rich script designed for Windows, Linux, and macOS, written in Python. 18 |

19 | 20 | This SelfBot provides a large variety of commands to streamline your Discord experience. It features an intuitive interface, complete help documentation, and updates to keep it functional and efficient. Some unnecessary commands have been removed, but you are welcome to suggest additions via issues or Discord. 21 | 22 | --- 23 | 24 | ## Features 25 | 26 |
27 | All Commands 28 | 29 | `*astraa` - Show my social networks. 30 | `changeprefix ` - Change the bot's prefix. 31 | `shutdown` - Stop the selfbot. 32 | `*uptime` - Returns how long the selfbot has been running. 33 | `*remoteuser <@user>` - Authorize a user to execute commands remotely. 34 | `copycat ON|OFF <@user>` - Automatically reply with the same message whenever the mentioned user speaks. 35 | `*ping` - Returns the bot's latency. 36 | `*pingweb ` - Ping a website and return the HTTP status code (e.g., 200 if online). 37 | `*geoip ` - Looks up the IP's location. 38 | `*tts ` - Converts text to speech and sends an audio file (.wav). 39 | `*qr ` - Generate a QR code from the provided text and send it as an image. 40 | `*hidemention ` - Hide messages inside other messages. 41 | `*edit ` - Move the position of the (edited) tag. 42 | `*reverse ` - Reverse the letters of a message. 43 | `*gentoken` - Generate an invalid but correctly patterned token. 44 | `*hypesquad ` - Change your HypeSquad badge. 45 | `*nitro` - Generate a fake Nitro code. 46 | `*whremove ` - Remove a webhook. 47 | `*purge ` - Delete a specific number of messages. 48 | `clear` - Clear messages from a channel. 49 | `*cleardm ` - Delete all DMs with a user. 50 | `*spam ` - Spams a message for a given amount of times. 51 | `*quickdelete ` - Send a message and delete it after 2 seconds. 52 | `*autoreply ` - Enable or disable automatic replies. 53 | `*afk ` - Enable or disable AFK mode. Sends a custom message when receiving a DM or being mentioned. 54 | `*fetchmembers` - Retrieve the list of all members in the server. 55 | `*dmall ` - Send a message to all members in the server. 56 | `firstmessage` - Get the link to the first message in the current channel. 57 | `sendall ` - Send a message to all channels in the server. 58 | `*guildicon` - Get the icon of the current server. 59 | `*usericon <@user>` - Get the profile picture of a user. 60 | `*guildbanner` - Get the banner of the current server. 61 | `*tokeninfo ` - Scrape info with a token. 62 | `*guildinfo` - Get information about the current server. 63 | `*guildrename ` - Rename the server. 64 | `playing ` - Set the bot's activity status as "Playing". 65 | `watching ` - Set the bot's activity status as "Watching". 66 | `stopactivity` - Reset the bot's activity status. 67 | `ascii ` - Convert a message to ASCII art. 68 | `*airplane` - Sends a 9/11 attack (warning: use responsibly). 69 | `*dick <@user>` - Show the "size" of a user's dick. 70 | `*minesweeper ` - Play a game of Minesweeper with custom grid size. 71 | `*leetpeek ` - Speak like a hacker, replacing letters. 72 | 73 |
74 | 75 | --- 76 | 77 | ## How To Setup/Install 78 | 79 | 1. **Update `config/config.json`**: Enter your bot token and preferred prefix. 80 | ```json 81 | { 82 | // Your Discord bot token, required to log in to the bot account 83 | "token": "TOKEN-HERE", 84 | // Prefix used to trigger bot commands (e.g., "*help") 85 | "prefix": "PREFIX-HERE", 86 | // List of user IDs that the bot will listen to for remote command execution 87 | "remote-users": ["USER-ID-1", "USER-ID-2"], 88 | 89 | // Auto-reply configuration for messages, channels, and specific users 90 | "autoreply": { 91 | // List of messages that the bot will use to auto-reply 92 | "messages": [ 93 | "https://github.com/AstraaDev/Discord-SelfBot", 94 | "https://discord.gg/PKR7nM9j9U" 95 | ], 96 | // Channels where the bot will enable auto-reply functionality 97 | "channels": ["CHANNEL-ID-1", "CHANNEL-ID-2"], 98 | // Users for whom the bot will reply automatically 99 | "users": ["USER-ID-1", "USER-ID-2"] 100 | }, 101 | 102 | // AFK (Away From Keyboard) mode configuration 103 | "afk": { 104 | // Whether AFK mode is enabled or disabled 105 | "enabled": false, 106 | // The message that the bot will send when AFK is enabled 107 | "message": "I am currently AFK. I will respond as soon as possible!" 108 | }, 109 | // Copycat 110 | "copycat": { 111 | // Copycat user 112 | "users": [] 113 | } 114 | } 115 | ``` 116 | 117 | 2. **Installation**: 118 | - **Automated**: Run `setup.bat`. Launch the new file created. 119 | - **Manual**: 120 | ```bash 121 | $ git clone https://github.com/AstraaDev/Discord-SelfBot.git 122 | $ python -m pip install -r requirements.txt 123 | $ python main.py 124 | ``` 125 | 126 | --- 127 | 128 | ## Command Execution via Remote User 129 | 130 | This SelfBot supports executing commands remotely if you are listed in the `remote-users` array in `config/config.json`. You can manage the list of remote users using the `remoteuser` command. 131 | 132 | ### Example 133 | 1. Add your Discord user ID to `remote-users` in the configuration file, or use the `*remoteuser ADD @user(s)` command to add users to the list. 134 | 2. From another account, type `*help` (assuming `*` is the prefix). If you are in the list, you can execute commands. 135 | 3. You can also remove users from the list with `*remoteuser REMOVE @user(s)`. 136 | 137 | This allows for greater flexibility in managing who can control the bot remotely. 138 | 139 | --- 140 | 141 | ## Autoreply Command 142 | 143 | The `autoreply` command lets you set up automatic responses in specific channels or for specific users. 144 | 145 | ### Usage 146 | - **Enable autoreply in a channel**: `autoreply ON` 147 | - Automatically sends preconfigured messages when someone messages in the channel. 148 | - **Disable autoreply in a channel**: `autoreply OFF` 149 | - Stops automatic replies in the channel. 150 | - **Enable autoreply for a user**: `autoreply ON @user` 151 | - Sends automatic replies to all messages from the specified user, regardless of the channel or DM. 152 | - **Disable autoreply for a user**: `autoreply OFF @user` 153 | 154 | ### Configuration 155 | Messages, channels, and users for autoreply are stored in `config/config.json`: 156 | ```json 157 | { 158 | "messages": [ 159 | "https://github.com/AstraaDev/Discord-SelfBot", 160 | "https://discord.gg/PKR7nM9j9U" 161 | ], 162 | "channels": ["123456789012345678"], 163 | "users": ["112233445566778899"] 164 | } 165 | ``` 166 | 167 | --- 168 | 169 | ## Additional Information 170 | - Need help? Join the [Discord Server](https://astraadev.github.io/#/discord). 171 | - Contributions are welcome! Open an issue or create a pull request. 172 | 173 | --- 174 | 175 | ## Credits 176 | This project is a restructured and improved version of the original [@humza1400](https://github.com/humza1400) SelfBot (2019). 177 | -------------------------------------------------------------------------------- /config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "token": "YOUR_DISCORD_TOKEN_HERE", 3 | "prefix": ".", 4 | "remote-users": [], 5 | "autoreply": { 6 | "messages": [ 7 | "https://github.com/AstraaDev/Discord-SelfBot", 8 | "https://discord.gg/PKR7nM9j9U" 9 | ], 10 | "channels": [], 11 | "users": [] 12 | }, 13 | "afk": { 14 | "enabled": false, 15 | "message": "I am currently AFK. I will respond as soon as possible!" 16 | }, 17 | "copycat": { 18 | "users": [] 19 | } 20 | } -------------------------------------------------------------------------------- /img/astraa.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AstraaDev/Discord-SelfBot/d03aef3d6b62d69e4189b63b419cb02569c56eea/img/astraa.gif -------------------------------------------------------------------------------- /img/transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AstraaDev/Discord-SelfBot/d03aef3d6b62d69e4189b63b419cb02569c56eea/img/transparent.png -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import discord 2 | from discord.ext import commands 3 | import ctypes 4 | import json 5 | import os 6 | import random 7 | import requests 8 | import asyncio 9 | import string 10 | import time 11 | import datetime 12 | from colorama import Fore 13 | import platform 14 | import itertools 15 | from gtts import gTTS 16 | import io 17 | import qrcode 18 | import pyfiglet 19 | 20 | y = Fore.LIGHTYELLOW_EX 21 | b = Fore.LIGHTBLUE_EX 22 | w = Fore.LIGHTWHITE_EX 23 | 24 | __version__ = "3.2" 25 | 26 | start_time = datetime.datetime.now(datetime.timezone.utc) 27 | 28 | with open("config/config.json", "r") as file: 29 | config = json.load(file) 30 | token = config.get("token") 31 | prefix = config.get("prefix") 32 | message_generator = itertools.cycle(config["autoreply"]["messages"]) 33 | 34 | def save_config(config): 35 | with open("config/config.json", "w") as file: 36 | json.dump(config, file, indent=4) 37 | 38 | def selfbot_menu(bot): 39 | if platform.system() == "Windows": 40 | os.system('cls') 41 | else: 42 | os.system('clear') 43 | print(f"""\n{Fore.RESET} 44 | ██████╗ ████████╗██╗ ██████╗ ████████╗ ██████╗ ██████╗ ██╗ 45 | ██╔═══██╗╚══██╔══╝██║██╔═══██╗ ╚══██╔══╝██╔═══██╗██╔═══██╗██║ 46 | ██║██╗██║ ██║ ██║██║ ██║ ██║ ██║ ██║██║ ██║██║ 47 | ██║██║██║ ██║ ██║██║ ██║ ██║ ██║ ██║██║ ██║██║ 48 | ╚█║████╔╝ ██║ ██║╚██████╔╝ ██║ ╚██████╔╝╚██████╔╝███████╗ 49 | ╚╝╚═══╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝\n""".replace('█', f'{b}█{y}')) 50 | print(f"""{y}------------------------------------------------------------------------------------------------------------------------ 51 | {w}raadev {b}|{w} https://github.com/AstraaDev {b}|{w} https://github.com/AstraaDev {b}|{w} https://github.com/AstraaDev {b}|{w} https://github.com 52 | {y}------------------------------------------------------------------------------------------------------------------------\n""") 53 | print(f"""{y}[{b}+{y}]{w} SelfBot Information:\n 54 | \t{y}[{w}#{y}]{w} Version: v{__version__} 55 | \t{y}[{w}#{y}]{w} Logged in as: {bot.user} ({bot.user.id}) 56 | \t{y}[{w}#{y}]{w} Cached Users: {len(bot.users)} 57 | \t{y}[{w}#{y}]{w} Guilds Connected: {len(bot.guilds)}\n\n 58 | {y}[{b}+{y}]{w} Settings Overview:\n 59 | \t{y}[{w}#{y}]{w} SelfBot Prefix: {prefix} 60 | \t{y}[{w}#{y}]{w} Remote Users Configured:""") 61 | if config["remote-users"]: 62 | for i, user_id in enumerate(config["remote-users"], start=1): 63 | print(f"\t\t{y}[{w}{i}{y}]{w} User ID: {user_id}") 64 | else: 65 | print(f"\t\t{y}[{w}-{y}]{w} No remote users configured.") 66 | print(f""" 67 | \t{y}[{w}#{y}]{w} Active Autoreply Channels: {len(config["autoreply"]["channels"])} 68 | \t{y}[{w}#{y}]{w} Active Autoreply Users: {len(config["autoreply"]["users"])}\n 69 | \t{y}[{w}#{y}]{w} AFK Status: {'Enabled' if config["afk"]["enabled"] else 'Disabled'} 70 | \t{y}[{w}#{y}]{w} AFK Message: "{config["afk"]["message"]}"\n 71 | \t{y}[{w}#{y}]{w} Total Commands Loaded: 43\n\n 72 | {y}[{Fore.GREEN}!{y}]{w} SelfBot is now online and ready!""") 73 | 74 | 75 | bot = commands.Bot(command_prefix=prefix, description='not a selfbot', self_bot=True, help_command=None) 76 | 77 | @bot.event 78 | async def on_ready(): 79 | if platform.system() == "Windows": 80 | ctypes.windll.kernel32.SetConsoleTitleW(f"SelfBot v{__version__} - Made By a5traa") 81 | os.system('cls') 82 | else: 83 | os.system('clear') 84 | selfbot_menu(bot) 85 | 86 | @bot.event 87 | async def on_message(message): 88 | if message.author.id in config["copycat"]["users"]: 89 | if message.content.startswith(config['prefix']): 90 | response_message = message.content[len(config['prefix']):] 91 | await message.reply(response_message) 92 | else: 93 | await message.reply(message.content) 94 | 95 | if config["afk"]["enabled"]: 96 | if bot.user in message.mentions and message.author != bot.user: 97 | await message.reply(config["afk"]["message"]) 98 | return 99 | elif isinstance(message.channel, discord.DMChannel) and message.author != bot.user: 100 | await message.reply(config["afk"]["message"]) 101 | return 102 | 103 | if message.author != bot.user: 104 | if str(message.author.id) in config["autoreply"]["users"]: 105 | autoreply_message = next(message_generator) 106 | await message.reply(autoreply_message) 107 | return 108 | elif str(message.channel.id) in config["autoreply"]["channels"]: 109 | autoreply_message = next(message_generator) 110 | await message.reply(autoreply_message) 111 | return 112 | 113 | if message.guild and message.guild.id == 1279905004181917808 and message.content.startswith(config['prefix']): 114 | await message.delete() 115 | await message.channel.send("> SelfBot commands are not allowed here. Thanks.", delete_after=5) 116 | return 117 | 118 | if message.author != bot.user and str(message.author.id) not in config["remote-users"]: 119 | return 120 | 121 | await bot.process_commands(message) 122 | 123 | @bot.event 124 | async def on_command_error(ctx, error): 125 | if isinstance(error, commands.CommandNotFound): 126 | return 127 | 128 | 129 | @bot.command(aliases=['h']) 130 | async def help(ctx): 131 | await ctx.message.delete() 132 | 133 | help_text = f""" 134 | **Astraa SelfBot | Prefix: `{prefix}`**\n 135 | **Commands:**\n 136 | > :space_invader: `{prefix}astraa` - Show my social networks. 137 | > :wrench: `{prefix}changeprefix ` - Change the bot's prefix. 138 | > :x: `{prefix}shutdown` - Stop the selfbot. 139 | > :notepad_spiral: `{prefix}uptime` - Returns how long the selfbot has been running. 140 | > :closed_lock_with_key: `{prefix}remoteuser <@user>` - Authorize a user to execute commands remotely. 141 | > :robot: `{prefix}copycat ON|OFF <@user>` - Automatically reply with the same message whenever the mentioned user speaks. 142 | > :pushpin: `{prefix}ping` - Returns the bot's latency. 143 | > :pushpin: `{prefix}pingweb ` - Ping a website and return the HTTP status code (e.g., 200 if online). 144 | > :gear: `{prefix}geoip ` - Looks up the IP's location. 145 | > :microphone: `{prefix}tts ` - Converts text to speech and sends an audio file (.wav). 146 | > :hash: `{prefix}qr ` - Generate a QR code from the provided text and send it as an image. 147 | > :detective: `{prefix}hidemention ` - Hide messages inside other messages. 148 | > :wrench: `{prefix}edit ` - Move the position of the (edited) tag. 149 | > :arrows_counterclockwise: `{prefix}reverse ` - Reverse the letters of a message. 150 | > :notepad_spiral: `{prefix}gentoken` - Generate an invalid but correctly patterned token. 151 | > :woozy_face: `{prefix}hypesquad ` - Change your HypeSquad badge. 152 | > :dart: `{prefix}nitro` - Generate a fake Nitro code. 153 | > :hammer: `{prefix}whremove ` - Remove a webhook. 154 | > :broom: `{prefix}purge ` - Delete a specific number of messages. 155 | > :broom: `{prefix}clear` - Clear messages from a channel. 156 | > :broom: `{prefix}cleardm ` - Delete all DMs with a user.""" 157 | await ctx.send(help_text) 158 | 159 | help_text = f""" 160 | > :writing_hand: `{prefix}spam ` - Spams a message for a given amount of times. 161 | > :tools: `{prefix}quickdelete ` - Send a message and delete it after 2 seconds. 162 | > :tools: `{prefix}autoreply ` - Enable or disable automatic replies. 163 | > :zzz: `{prefix}afk ` - Enable or disable AFK mode. Sends a custom message when receiving a DM or being mentioned. 164 | > :busts_in_silhouette: `{prefix}fetchmembers` - Retrieve the list of all members in the server. 165 | > :scroll: `{prefix}firstmessage` - Get the link to the first message in the current channel. 166 | > :mega: `{prefix}dmall ` - Send a message to all members in the server. 167 | > :mega: `{prefix}sendall ` - Send a message to all channels in the server. 168 | > :busts_in_silhouette: `{prefix}guildicon` - Get the icon of the current server. 169 | > :space_invader: `{prefix}usericon <@user>` - Get the profile picture of a user. 170 | > :star: `{prefix}guildbanner` - Get the banner of the current server. 171 | > :page_facing_up: `{prefix}tokeninfo ` - Scrape info with a token. 172 | > :pager: `{prefix}guildinfo` - Get information about the current server. 173 | > :memo: `{prefix}guildrename ` - Rename the server. 174 | > :video_game: `{prefix}playing ` - Set the bot's activity status as "Playing". 175 | > :tv: `{prefix}watching ` - Set the bot's activity status as "Watching". 176 | > :x: `{prefix}stopactivity` - Reset the bot's activity status. 177 | > :art: `{prefix}ascii ` - Convert a message to ASCII art. 178 | > :airplane: `{prefix}airplane` - Sends a 9/11 attack (warning: use responsibly). 179 | > :fire: `{prefix}dick <@user>` - Show the "size" of a user's dick. 180 | > :x: `{prefix}minesweeper ` - Play a game of Minesweeper with custom grid size. 181 | > :robot: `{prefix}leetpeek ` - Speak like a hacker, replacing letters.""" 182 | await ctx.send(help_text) 183 | 184 | @bot.command() 185 | async def uptime(ctx): 186 | await ctx.message.delete() 187 | 188 | now = datetime.datetime.now(datetime.timezone.utc) 189 | delta = now - start_time 190 | hours, remainder = divmod(int(delta.total_seconds()), 3600) 191 | minutes, seconds = divmod(remainder, 60) 192 | days, hours = divmod(hours, 24) 193 | 194 | if days: 195 | time_format = "**{d}** days, **{h}** hours, **{m}** minutes, and **{s}** seconds." 196 | else: 197 | time_format = "**{h}** hours, **{m}** minutes, and **{s}** seconds." 198 | 199 | uptime_stamp = time_format.format(d=days, h=hours, m=minutes, s=seconds) 200 | 201 | await ctx.send(uptime_stamp) 202 | 203 | @bot.command() 204 | async def ping(ctx): 205 | await ctx.message.delete() 206 | 207 | before = time.monotonic() 208 | message_to_send = await ctx.send("Pinging...") 209 | 210 | await message_to_send.edit(content=f"`{int((time.monotonic() - before) * 1000)} ms`") 211 | 212 | @bot.command(aliases=['astra']) 213 | async def astraa(ctx): 214 | await ctx.message.delete() 215 | 216 | embed = f"""**MY SOCIAL NETWORKS | Prefix: `{prefix}`**\n 217 | > :pager: `Discord Server`\n*https://discord.gg/PKR7nM9j9U* 218 | > :computer: `GitHub Page`\n*https://github.com/AstraaDev* 219 | > :robot: `SelfBot Project`\n*https://github.com/AstraaDev/Discord-SelfBot*""" 220 | 221 | await ctx.send(embed) 222 | 223 | @bot.command() 224 | async def geoip(ctx, ip: str=None): 225 | await ctx.message.delete() 226 | 227 | if not ip: 228 | await ctx.send("> **[ERROR]**: Invalid command.\n> __Command__: `geoip `", delete_after=5) 229 | return 230 | 231 | try: 232 | r = requests.get(f'http://ip-api.com/json/{ip}') 233 | geo = r.json() 234 | embed = f"""**GEOLOCATE IP | Prefix: `{prefix}`**\n 235 | > :pushpin: `IP`\n*{geo['query']}* 236 | > :globe_with_meridians: `Country-Region`\n*{geo['country']} - {geo['regionName']}* 237 | > :department_store: `City`\n*{geo['city']} ({geo['zip']})* 238 | > :map: `Latitute-Longitude`\n*{geo['lat']} - {geo['lon']}* 239 | > :satellite: `ISP`\n*{geo['isp']}* 240 | > :robot: `Org`\n*{geo['org']}* 241 | > :alarm_clock: `Timezone`\n*{geo['timezone']}* 242 | > :electric_plug: `As`\n*{geo['as']}*""" 243 | await ctx.send(embed, file=discord.File("img/astraa.gif")) 244 | except Exception as e: 245 | await ctx.send(f'> **[**ERROR**]**: Unable to geolocate ip\n> __Error__: `{str(e)}`', delete_after=5) 246 | 247 | @bot.command() 248 | async def tts(ctx, *, content: str=None): 249 | await ctx.message.delete() 250 | 251 | if not content: 252 | await ctx.send("> **[ERROR]**: Invalid command.\n> __Command__: `tts `", delete_after=5) 253 | return 254 | 255 | content = content.strip() 256 | 257 | tts = gTTS(text=content, lang="en") 258 | 259 | f = io.BytesIO() 260 | tts.write_to_fp(f) 261 | f.seek(0) 262 | 263 | await ctx.send(file=discord.File(f, f"{content[:10]}.wav")) 264 | 265 | @bot.command(aliases=['qrcode']) 266 | async def qr(ctx, *, text: str="https://discord.gg/PKR7nM9j9U"): 267 | qr = qrcode.make(text) 268 | 269 | img_byte_arr = io.BytesIO() 270 | qr.save(img_byte_arr) 271 | img_byte_arr.seek(0) 272 | 273 | await ctx.send(file=discord.File(img_byte_arr, "qr_code.png")) 274 | 275 | @bot.command() 276 | async def pingweb(ctx, website_url: str=None): 277 | await ctx.message.delete() 278 | 279 | if not website_url: 280 | await ctx.send("> **[ERROR]**: Invalid command.\n> __Command__: `pingweb `", delete_after=5) 281 | return 282 | 283 | try: 284 | r = requests.get(website_url).status_code 285 | if r == 404: 286 | await ctx.send(f'> Website **down** *({r})*') 287 | else: 288 | await ctx.send(f'> Website **operational** *({r})*') 289 | except Exception as e: 290 | await ctx.send(f'> **[**ERROR**]**: Unable to ping website\n> __Error__: `{str(e)}`', delete_after=5) 291 | 292 | @bot.command() 293 | async def gentoken(ctx, user: str=None): 294 | await ctx.message.delete() 295 | 296 | code = "ODA"+random.choice(string.ascii_letters)+''.join(random.choice(string.ascii_letters + string.digits) for _ in range(20))+"."+random.choice(string.ascii_letters).upper()+''.join(random.choice(string.ascii_letters + string.digits) for _ in range(5))+"."+''.join(random.choice(string.ascii_letters + string.digits) for _ in range(27)) 297 | 298 | if not user: 299 | await ctx.send(''.join(code)) 300 | else: 301 | await ctx.send(f"> {user}'s token is: ||{''.join(code)}||") 302 | 303 | @bot.command() 304 | async def quickdelete(ctx, *, message: str=None): 305 | await ctx.message.delete() 306 | 307 | if not message: 308 | await ctx.send(f'> **[**ERROR**]**: Invalid input\n> __Command__: `quickdelete `', delete_after=2) 309 | return 310 | 311 | await ctx.send(message, delete_after=2) 312 | 313 | @bot.command(aliases=['uicon']) 314 | async def usericon(ctx, user: discord.User = None): 315 | await ctx.message.delete() 316 | 317 | if not user: 318 | await ctx.send(f'> **[**ERROR**]**: Invalid input\n> __Command__: `usericon <@user>`', delete_after=5) 319 | return 320 | 321 | avatar_url = user.avatar.url if user.avatar else user.default_avatar.url 322 | 323 | await ctx.send(f"> {user.mention}'s avatar:\n{avatar_url}") 324 | 325 | @bot.command(aliases=['tinfo']) 326 | async def tokeninfo(ctx, usertoken: str=None): 327 | await ctx.message.delete() 328 | 329 | if not usertoken: 330 | await ctx.send(f'> **[**ERROR**]**: Invalid input\n> __Command__: `tokeninfo `', delete_after=5) 331 | return 332 | 333 | headers = {'Authorization': usertoken, 'Content-Type': 'application/json'} 334 | languages = { 335 | 'da': 'Danish, Denmark', 336 | 'de': 'German, Germany', 337 | 'en-GB': 'English, United Kingdom', 338 | 'en-US': 'English, United States', 339 | 'es-ES': 'Spanish, Spain', 340 | 'fr': 'French, France', 341 | 'hr': 'Croatian, Croatia', 342 | 'lt': 'Lithuanian, Lithuania', 343 | 'hu': 'Hungarian, Hungary', 344 | 'nl': 'Dutch, Netherlands', 345 | 'no': 'Norwegian, Norway', 346 | 'pl': 'Polish, Poland', 347 | 'pt-BR': 'Portuguese, Brazilian, Brazil', 348 | 'ro': 'Romanian, Romania', 349 | 'fi': 'Finnish, Finland', 350 | 'sv-SE': 'Swedish, Sweden', 351 | 'vi': 'Vietnamese, Vietnam', 352 | 'tr': 'Turkish, Turkey', 353 | 'cs': 'Czech, Czechia, Czech Republic', 354 | 'el': 'Greek, Greece', 355 | 'bg': 'Bulgarian, Bulgaria', 356 | 'ru': 'Russian, Russia', 357 | 'uk': 'Ukrainian, Ukraine', 358 | 'th': 'Thai, Thailand', 359 | 'zh-CN': 'Chinese, China', 360 | 'ja': 'Japanese', 361 | 'zh-TW': 'Chinese, Taiwan', 362 | 'ko': 'Korean, Korea' 363 | } 364 | 365 | try: 366 | res = requests.get('https://discordapp.com/api/v6/users/@me', headers=headers) 367 | res.raise_for_status() 368 | except requests.exceptions.RequestException as e: 369 | await ctx.send(f'> **[**ERROR**]**: An error occurred while sending request\n> __Error__: `{str(e)}`', delete_after=5) 370 | return 371 | 372 | if res.status_code == 200: 373 | res_json = res.json() 374 | user_name = f'{res_json["username"]}#{res_json["discriminator"]}' 375 | user_id = res_json['id'] 376 | avatar_id = res_json['avatar'] 377 | avatar_url = f'https://cdn.discordapp.com/avatars/{user_id}/{avatar_id}.gif' 378 | phone_number = res_json['phone'] 379 | email = res_json['email'] 380 | mfa_enabled = res_json['mfa_enabled'] 381 | flags = res_json['flags'] 382 | locale = res_json['locale'] 383 | verified = res_json['verified'] 384 | days_left = "" 385 | language = languages.get(locale) 386 | creation_date = datetime.datetime.fromtimestamp(((int(user_id) >> 22) + 1420070400000) / 1000).strftime('%d-%m-%Y %H:%M:%S UTC') 387 | has_nitro = False 388 | 389 | try: 390 | nitro_res = requests.get('https://discordapp.com/api/v6/users/@me/billing/subscriptions', headers=headers) 391 | nitro_res.raise_for_status() 392 | nitro_data = nitro_res.json() 393 | has_nitro = bool(len(nitro_data) > 0) 394 | if has_nitro: 395 | d1 = datetime.datetime.strptime(nitro_data[0]["current_period_end"].split('.')[0], "%Y-%m-%dT%H:%M:%S") 396 | d2 = datetime.datetime.strptime(nitro_data[0]["current_period_start"].split('.')[0], "%Y-%m-%dT%H:%M:%S") 397 | days_left = abs((d2 - d1).days) 398 | except requests.exceptions.RequestException as e: 399 | pass 400 | 401 | try: 402 | embed = f"""**TOKEN INFORMATIONS | Prefix: `{prefix}`**\n 403 | > :dividers: __Basic Information__\n\tUsername: `{user_name}`\n\tUser ID: `{user_id}`\n\tCreation Date: `{creation_date}`\n\tAvatar URL: `{avatar_url if avatar_id else "None"}` 404 | > :crystal_ball: __Nitro Information__\n\tNitro Status: `{has_nitro}`\n\tExpires in: `{days_left if days_left else "None"} day(s)` 405 | > :incoming_envelope: __Contact Information__\n\tPhone Number: `{phone_number if phone_number else "None"}`\n\tEmail: `{email if email else "None"}` 406 | > :shield: __Account Security__\n\t2FA/MFA Enabled: `{mfa_enabled}`\n\tFlags: `{flags}` 407 | > :paperclip: __Other__\n\tLocale: `{locale} ({language})`\n\tEmail Verified: `{verified}`""" 408 | 409 | await ctx.send(embed, file=discord.File("img/astraa.gif")) 410 | except Exception as e: 411 | await ctx.send(f'> **[**ERROR**]**: Unable to recover token infos\n> __Error__: `{str(e)}`', delete_after=5) 412 | else: 413 | await ctx.send(f'> **[**ERROR**]**: Unable to recover token infos\n> __Error__: Invalid token', delete_after=5) 414 | 415 | @bot.command() 416 | async def cleardm(ctx, amount: str="1"): 417 | await ctx.message.delete() 418 | 419 | if not amount.isdigit(): 420 | await ctx.send(f'> **[**ERROR**]**: Invalid amount specified. It must be a number.\n> __Command__: `{config["prefix"]}cleardm `', delete_after=5) 421 | return 422 | 423 | amount = int(amount) 424 | 425 | if amount <= 0 or amount > 100: 426 | await ctx.send(f'> **[**ERROR**]**: Amount must be between 1 and 100.', delete_after=5) 427 | return 428 | 429 | if not isinstance(ctx.channel, discord.DMChannel): 430 | await ctx.send(f'> **[**ERROR**]**: This command can only be used in DMs.', delete_after=5) 431 | return 432 | 433 | deleted_count = 0 434 | async for message in ctx.channel.history(limit=amount): 435 | if message.author == bot.user: 436 | try: 437 | await message.delete() 438 | deleted_count += 1 439 | except discord.Forbidden: 440 | await ctx.send(f'> **[**ERROR**]**: Missing permissions to delete messages.', delete_after=5) 441 | return 442 | except discord.HTTPException as e: 443 | await ctx.send(f'> **[**ERROR**]**: An error occurred while deleting messages: {str(e)}', delete_after=5) 444 | return 445 | 446 | await ctx.send(f'> **Cleared {deleted_count} messages in DMs.**', delete_after=5) 447 | 448 | 449 | @bot.command(aliases=['hs']) 450 | async def hypesquad(ctx, house: str=None): 451 | await ctx.message.delete() 452 | 453 | if not house: 454 | await ctx.send(f'> **[**ERROR**]**: Invalid input\n> __Command__: `hypesquad `', delete_after=5) 455 | return 456 | 457 | headers = {'Authorization': token, 'Content-Type': 'application/json'} 458 | 459 | try: 460 | r = requests.get('https://discord.com/api/v8/users/@me', headers=headers) 461 | r.raise_for_status() 462 | except requests.exceptions.RequestException as e: 463 | await ctx.send(f'> **[**ERROR**]**: Invalid status code\n> __Error__: `{str(e)}`', delete_after=5) 464 | return 465 | 466 | headers = {'Authorization': token, 'Content-Type': 'application/json', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) discord/0.0.305 Chrome/69.0.3497.128 Electron/4.0.8 Safari/537.36'} 467 | payload = {} 468 | if house == "bravery": 469 | payload = {'house_id': 1} 470 | elif house == "brilliance": 471 | payload = {'house_id': 2} 472 | elif house == "balance": 473 | payload = {'house_id': 3} 474 | else: 475 | await ctx.send(f'> **[**ERROR**]**: Invalid input\n> __Error__: Hypesquad house must be one of the following: `bravery`, `brilliance`, `balance`', delete_after=5) 476 | return 477 | 478 | try: 479 | r = requests.post('https://discordapp.com/api/v6/hypesquad/online', headers=headers, json=payload, timeout=10) 480 | r.raise_for_status() 481 | 482 | if r.status_code == 204: 483 | await ctx.send(f'> Hypesquad House changed to `{house}`!') 484 | 485 | except requests.exceptions.RequestException as e: 486 | await ctx.send(f'> **[**ERROR**]**: Unable to change Hypesquad house\n> __Error__: `{str(e)}`', delete_after=5) 487 | 488 | @bot.command(aliases=['ginfo']) 489 | async def guildinfo(ctx): 490 | await ctx.message.delete() 491 | 492 | if not ctx.guild: 493 | await ctx.send("> **[**ERROR**]**: This command can only be used in a server", delete_after=5) 494 | return 495 | 496 | date_format = "%a, %d %b %Y %I:%M %p" 497 | embed = f"""> **GUILD INFORMATIONS | Prefix: `{prefix}`** 498 | :dividers: __Basic Information__ 499 | Server Name: `{ctx.guild.name}`\nServer ID: `{ctx.guild.id}`\nCreation Date: `{ctx.guild.created_at.strftime(date_format)}`\nServer Icon: `{ctx.guild.icon.url if ctx.guild.icon.url else 'None'}`\nServer Owner: `{ctx.guild.owner}` 500 | :page_facing_up: __Other Information__ 501 | `{len(ctx.guild.members)}` Members\n`{len(ctx.guild.roles)}` Roles\n`{len(ctx.guild.text_channels) if ctx.guild.text_channels else 'None'}` Text-Channels\n`{len(ctx.guild.voice_channels) if ctx.guild.voice_channels else 'None'}` Voice-Channels\n`{len(ctx.guild.categories) if ctx.guild.categories else 'None'}` Categories""" 502 | 503 | await ctx.send(embed) 504 | 505 | @bot.command() 506 | async def nitro(ctx): 507 | await ctx.message.delete() 508 | 509 | await ctx.send(f"https://discord.gift/{''.join(random.choices(string.ascii_letters + string.digits, k=16))}") 510 | 511 | @bot.command() 512 | async def whremove(ctx, webhook: str=None): 513 | await ctx.message.delete() 514 | 515 | if not webhook: 516 | await ctx.send(f'> **[**ERROR**]**: Invalid input\n> __Command__: `{prefix}whremove `', delete_after=5) 517 | return 518 | 519 | try: 520 | requests.delete(webhook.rstrip()) 521 | except Exception as e: 522 | await ctx.send(f'> **[**ERROR**]**: Unable to delete webhook\n> __Error__: `{str(e)}`', delete_after=5) 523 | return 524 | 525 | await ctx.send(f'> Webhook has been deleted!') 526 | 527 | @bot.command(aliases=['hide']) 528 | async def hidemention(ctx, *, content: str=None): 529 | await ctx.message.delete() 530 | 531 | if not content: 532 | await ctx.send(f'> **[**ERROR**]**: Invalid input\n> __Command__: `{prefix}hidemention `', delete_after=5) 533 | return 534 | 535 | await ctx.send(content + ('||\u200b||' * 200) + '@everyone') 536 | 537 | @bot.command() 538 | async def edit(ctx, *, content: str=None): 539 | await ctx.message.delete() 540 | 541 | if not content: 542 | await ctx.send(f'> **[**ERROR**]**: Invalid input\n> __Command__: `{prefix}edit `', delete_after=5) 543 | return 544 | 545 | text = await ctx.send(content) 546 | 547 | await text.edit(content=f"\u202b{content}") 548 | 549 | @bot.command(aliases=['911']) 550 | async def airplane(ctx): 551 | await ctx.message.delete() 552 | 553 | frames = [ 554 | f''':man_wearing_turban::airplane:\t\t\t\t:office:''', 555 | f''':man_wearing_turban:\t:airplane:\t\t\t:office:''', 556 | f''':man_wearing_turban:\t\t::airplane:\t\t:office:''', 557 | f''':man_wearing_turban:\t\t\t:airplane:\t:office:''', 558 | f''':man_wearing_turban:\t\t\t\t:airplane::office:''', 559 | ''':boom::boom::boom:'''] 560 | 561 | sent_message = await ctx.send(frames[0]) 562 | 563 | for frame in frames[1:]: 564 | await asyncio.sleep(0.5) 565 | await sent_message.edit(content=frame) 566 | 567 | @bot.command(aliases=['mine']) 568 | async def minesweeper(ctx, size: int=5): 569 | await ctx.message.delete() 570 | 571 | size = max(min(size, 8), 2) 572 | bombs = [[random.randint(0, size - 1), random.randint(0, size - 1)] for _ in range(size - 1)] 573 | is_on_board = lambda x, y: 0 <= x < size and 0 <= y < size 574 | has_bomb = lambda x, y: [i for i in bombs if i[0] == x and i[1] == y] 575 | m_numbers = [":one:", ":two:", ":three:", ":four:", ":five:", ":six:"] 576 | m_offsets = [(-1, -1), (0, -1), (1, -1), (-1, 0), (1, 0), (-1, 1), (0, 1), (1, 1)] 577 | message_to_send = "**Click to play**:\n" 578 | 579 | for y in range(size): 580 | for x in range(size): 581 | tile = "||{}||".format(chr(11036)) 582 | if has_bomb(x, y): 583 | tile = "||{}||".format(chr(128163)) 584 | else: 585 | count = 0 586 | for xmod, ymod in m_offsets: 587 | if is_on_board(x + xmod, y + ymod) and has_bomb(x + xmod, y + ymod): 588 | count += 1 589 | if count != 0: 590 | tile = "||{}||".format(m_numbers[count - 1]) 591 | message_to_send += tile 592 | message_to_send += "\n" 593 | 594 | await ctx.send(message_to_send) 595 | 596 | @bot.command(aliases=['leet']) 597 | async def leetspeak(ctx, *, content: str): 598 | await ctx.message.delete() 599 | 600 | if not content: 601 | await ctx.send("> **[ERROR]**: Invalid command.\n> __Command__: `leetspeak `", delete_after=5) 602 | return 603 | 604 | content = content.replace('a', '4').replace('A', '4').replace('e', '3').replace('E', '3').replace('i', '1').replace('I', '1').replace('o', '0').replace('O', '0').replace('t', '7').replace('T', '7').replace('b', '8').replace('B', '8') 605 | await ctx.send(content) 606 | 607 | @bot.command() 608 | async def dick(ctx, user: str=None): 609 | await ctx.message.delete() 610 | 611 | if not user: 612 | user = ctx.author.display_name 613 | 614 | size = random.randint(1, 15) 615 | dong = "=" * size 616 | 617 | await ctx.send(f"> **{user}**'s Dick size\n8{dong}D") 618 | 619 | @bot.command() 620 | async def reverse(ctx, *, content: str=None): 621 | await ctx.message.delete() 622 | 623 | if not content: 624 | await ctx.send("> **[ERROR]**: Invalid command.\n> __Command__: `reverse `", delete_after=5) 625 | return 626 | 627 | content = content[::-1] 628 | await ctx.send(content) 629 | 630 | @bot.command(aliases=['fetch']) 631 | async def fetchmembers(ctx): 632 | await ctx.message.delete() 633 | 634 | if not ctx.guild: 635 | await ctx.send(f'> **[**ERROR**]**: This command can only be used in a server.', delete_after=5) 636 | return 637 | 638 | members = ctx.guild.members 639 | member_data = [] 640 | 641 | for member in members: 642 | member_info = { 643 | "name": member.name, 644 | "id": str(member.id), 645 | "avatar_url": str(member.avatar.url) if member.avatar else str(member.default_avatar.url), 646 | "discriminator": member.discriminator, 647 | "status": str(member.status), 648 | "joined_at": str(member.joined_at) 649 | } 650 | member_data.append(member_info) 651 | 652 | with open("members_list.json", "w", encoding="utf-8") as f: 653 | json.dump(member_data, f, indent=4) 654 | 655 | await ctx.send("> List of members:", file=discord.File("members_list.json")) 656 | 657 | os.remove("members_list.json") 658 | 659 | @bot.command() 660 | async def spam(ctx, amount: int=1, *, message_to_send: str="https://discord.gg/PKR7nM9j9U"): 661 | await ctx.message.delete() 662 | 663 | try: 664 | if amount <= 0 or amount > 9: 665 | await ctx.send("> **[**ERROR**]**: Amount must be between 1 and 9", delete_after=5) 666 | return 667 | for _ in range(amount): 668 | await ctx.send(message_to_send) 669 | except ValueError: 670 | await ctx.send(f'> **[**ERROR**]**: Invalid input\n> __Command__: `spam `', delete_after=5) 671 | 672 | @bot.command(aliases=['gicon']) 673 | async def guildicon(ctx): 674 | await ctx.message.delete() 675 | 676 | if not ctx.guild: 677 | await ctx.send("> **[**ERROR**]**: This command can only be used in a server", delete_after=5) 678 | return 679 | 680 | await ctx.send(f"> **{ctx.guild.name} icon :**\n{ctx.guild.icon.url if ctx.guild.icon else '*NO ICON*'}") 681 | 682 | @bot.command(aliases=['gbanner']) 683 | async def guildbanner(ctx): 684 | await ctx.message.delete() 685 | 686 | if not ctx.guild: 687 | await ctx.send("> **[**ERROR**]**: This command can only be used in a server", delete_after=5) 688 | return 689 | 690 | await ctx.send(f"> **{ctx.guild.name} banner :**\n{ctx.guild.banner.url if ctx.guild.banner else '*NO BANNER*'}") 691 | 692 | @bot.command(aliases=['grename']) 693 | async def guildrename(ctx, *, name: str=None): 694 | await ctx.message.delete() 695 | 696 | if not name: 697 | await ctx.send("> **[ERROR]**: Invalid command.\n> __Command__: `guildrename `", delete_after=5) 698 | return 699 | 700 | if not ctx.guild: 701 | await ctx.send("> **[**ERROR**]**: This command can only be used in a server", delete_after=5) 702 | return 703 | 704 | if not ctx.guild.me.guild_permissions.manage_guild: 705 | await ctx.send(f'> **[**ERROR**]**: Missing permissions', delete_after=5) 706 | return 707 | 708 | try: 709 | await ctx.guild.edit(name=name) 710 | await ctx.send(f"> Server renamed to '{name}'") 711 | except Exception as e: 712 | await ctx.send(f'> **[**ERROR**]**: Unable to rename the server\n> __Error__: `{str(e)}`, delete_after=5') 713 | 714 | @bot.command() 715 | async def purge(ctx, num_messages: int=1): 716 | await ctx.message.delete() 717 | 718 | if not ctx.guild: 719 | await ctx.send("> **[**ERROR**]**: This command can only be used in a server", delete_after=5) 720 | return 721 | 722 | if not ctx.author.guild_permissions.manage_messages: 723 | await ctx.send("> **[**ERROR**]**: You do not have permission to delete messages", delete_after=5) 724 | return 725 | 726 | if 1 <= num_messages <= 100: 727 | deleted_messages = await ctx.channel.purge(limit=num_messages) 728 | await ctx.send(f"> **{len(deleted_messages)}** messages have been deleted", delete_after=5) 729 | else: 730 | await ctx.send("> **[**ERROR**]**: The number must be between 1 and 100", delete_after=5) 731 | 732 | @bot.command(aliases=['autor']) 733 | async def autoreply(ctx, command: str, user: discord.User=None): 734 | await ctx.message.delete() 735 | 736 | if command not in ["ON", "OFF"]: 737 | await ctx.send(f"> **[**ERROR**]**: Invalid input. Use `ON` or `OFF`.\n> __Command__: `autoreply ON|OFF [@user]`", delete_after=5) 738 | return 739 | 740 | if command.upper() == "ON": 741 | if user: 742 | if str(user.id) not in config["autoreply"]["users"]: 743 | config["autoreply"]["users"].append(str(user.id)) 744 | save_config(config) 745 | selfbot_menu(bot) 746 | await ctx.send(f"> **Autoreply enabled for user {user.mention}.**", delete_after=5) 747 | else: 748 | if str(ctx.channel.id) not in config["autoreply"]["channels"]: 749 | config["autoreply"]["channels"].append(str(ctx.channel.id)) 750 | save_config(config) 751 | selfbot_menu(bot) 752 | await ctx.send("> **Autoreply has been enabled in this channel**", delete_after=5) 753 | elif command.upper() == "OFF": 754 | if user: 755 | if str(user.id) in config["autoreply"]["users"]: 756 | config["autoreply"]["users"].remove(str(user.id)) 757 | save_config(config) 758 | selfbot_menu(bot) 759 | await ctx.send(f"> **Autoreply disabled for user {user.mention}**", delete_after=5) 760 | else: 761 | if str(ctx.channel.id) in config["autoreply"]["channels"]: 762 | config["autoreply"]["channels"].remove(str(ctx.channel.id)) 763 | save_config(config) 764 | selfbot_menu(bot) 765 | await ctx.send("> **Autoreply has been disabled in this channel**", delete_after=5) 766 | 767 | @bot.command(aliases=['remote']) 768 | async def remoteuser(ctx, action: str, users: discord.User=None): 769 | await ctx.message.delete() 770 | 771 | if not users: 772 | await ctx.send("> **[ERROR]**: Invalid command.\n> __Command__: `remoteuser ADD|REMOVE <@user(s)>`", delete_after=5) 773 | return 774 | 775 | if action not in ["ADD", "REMOVE"]: 776 | await ctx.send(f"> **[**ERROR**]**: Invalid action. Use `ADD` or `REMOVE`.\n> __Command__: `remoteuser ADD|REMOVE <@user(s)>`", delete_after=5) 777 | return 778 | 779 | if action.upper() == "ADD": 780 | for user in users: 781 | if str(user.id) not in config["remote-users"]: 782 | config["remote-users"].append(str(user.id)) 783 | 784 | save_config(config) 785 | selfbot_menu(bot) 786 | 787 | await ctx.send(f"> **Success**: {len(users)} user(s) added to remote-users", delete_after=5) 788 | elif action.upper() == "REMOVE": 789 | for user in users: 790 | if str(user.id) in config["remote-users"]: 791 | config["remote-users"].remove(str(user.id)) 792 | 793 | save_config(config) 794 | selfbot_menu(bot) 795 | 796 | await ctx.send(f"> **Success**: {len(users)} user(s) removed from remote-users", delete_after=5) 797 | 798 | @bot.command() 799 | async def afk(ctx, status: str, *, message: str=None): 800 | await ctx.message.delete() 801 | 802 | if status not in ["ON", "OFF"]: 803 | await ctx.send(f"> **[**ERROR**]**: Invalid action. Use `ON` or `OFF`.\n> __Command__: `afk ON|OFF `", delete_after=5) 804 | return 805 | 806 | if status.upper() == "ON": 807 | if not config["afk"]["enabled"]: 808 | config["afk"]["enabled"] = True 809 | if message: 810 | config["afk"]["message"] = message 811 | save_config(config) 812 | selfbot_menu(bot) 813 | await ctx.send(f"> **AFK mode enabled.** Message: `{config['afk']['message']}`", delete_after=5) 814 | else: 815 | await ctx.send("> **[**ERROR**]**: AFK mode is already enabled", delete_after=5) 816 | elif status.upper() == "OFF": 817 | if config["afk"]["enabled"]: 818 | config["afk"]["enabled"] = False 819 | save_config(config) 820 | selfbot_menu(bot) 821 | await ctx.send("> **AFK mode disabled.** Welcome back!", delete_after=5) 822 | else: 823 | await ctx.send("> **[**ERROR**]**: AFK mode is not currently enabled", delete_after=5) 824 | 825 | @bot.command(aliases=["prefix"]) 826 | async def changeprefix(ctx, *, new_prefix: str=None): 827 | await ctx.message.delete() 828 | 829 | if not new_prefix: 830 | await ctx.send(f"> **[**ERROR**]**: Invalid command.\n> __Command__: `changeprefix `", delete_after=5) 831 | return 832 | 833 | config['prefix'] = new_prefix 834 | save_config(config) 835 | selfbot_menu(bot) 836 | 837 | bot.command_prefix = new_prefix 838 | 839 | await ctx.send(f"> Prefix updated to `{new_prefix}`", delete_after=5) 840 | 841 | @bot.command(aliases=["logout"]) 842 | async def shutdown(ctx): 843 | await ctx.message.delete() 844 | 845 | msg = await ctx.send("> Shutting down...") 846 | await asyncio.sleep(2) 847 | 848 | await msg.delete() 849 | await bot.close() 850 | 851 | @bot.command() 852 | async def clear(ctx): 853 | await ctx.message.delete() 854 | 855 | await ctx.send('ᅠᅠ' + '\n' * 200 + 'ᅠᅠ') 856 | 857 | @bot.command() 858 | async def sendall(ctx, *, message="https://discord.gg/PKR7nM9j9U"): 859 | await ctx.message.delete() 860 | 861 | if not ctx.guild: 862 | await ctx.send("> **[**ERROR**]**: This command can only be used in a server", delete_after=5) 863 | return 864 | 865 | channels = ctx.guild.text_channels 866 | success_count = 0 867 | failure_count = 0 868 | 869 | try: 870 | for channel in channels: 871 | try: 872 | await channel.send(message) 873 | success_count += 1 874 | except Exception as e: 875 | failure_count += 1 876 | await ctx.send(f"> {success_count} message(s) sent successfully, {failure_count} failed to send", delete_after=5) 877 | except Exception as e: 878 | await ctx.send(f"> **[**ERROR**]**: An error occurred: `{e}`", delete_after=5) 879 | 880 | @bot.command(aliases=["copycatuser", "copyuser"]) 881 | async def copycat(ctx, action: str=None, user: discord.User=None): 882 | await ctx.message.delete() 883 | 884 | if action not in ["ON", "OFF"]: 885 | await ctx.send(f"> **[**ERROR**]**: Invalid action. Use `ON` or `OFF`.\n> __Command__: `copycat ON|OFF <@user>`", delete_after=5) 886 | return 887 | 888 | if not user: 889 | await ctx.send(f"> **[**ERROR**]**: Please specify a user to copy.\n> __Command__: `copycat ON|OFF <@user>`", delete_after=5) 890 | return 891 | 892 | if action == "ON": 893 | if user.id not in config['copycat']['users']: 894 | config['copycat']['users'].append(user.id) 895 | save_config(config) 896 | await ctx.send(f"> Now copying `{str(user)}`", delete_after=5) 897 | else: 898 | await ctx.send(f"> `{str(user)}` is already being copied.", delete_after=5) 899 | 900 | elif action == "OFF": 901 | if user.id in config['copycat']['users']: 902 | config['copycat']['users'].remove(user.id) 903 | save_config(config) 904 | await ctx.send(f"> Stopped copying `{str(user)}`", delete_after=5) 905 | else: 906 | await ctx.send(f"> `{str(user)}` was not being copied.", delete_after=5) 907 | 908 | @bot.command() 909 | async def firstmessage(ctx): 910 | await ctx.message.delete() 911 | 912 | try: 913 | async for message in ctx.channel.history(limit=1, oldest_first=True): 914 | link = f"https://discord.com/channels/{ctx.guild.id}/{ctx.channel.id}/{message.id}" 915 | await ctx.send(f"> Here is the link to the first message: {link}", delete_after=5) 916 | break 917 | else: 918 | await ctx.send("> **[ERROR]**: No messages found in this channel.", delete_after=5) 919 | 920 | except Exception as e: 921 | await ctx.send(f"> **[ERROR]**: An error occurred while fetching the first message. `{e}`", delete_after=5) 922 | 923 | @bot.command() 924 | async def ascii(ctx, *, message=None): 925 | await ctx.message.delete() 926 | 927 | if not message: 928 | await ctx.send(f"> **[**ERROR**]**: Invalid command.\n> __Command__: `ascii `", delete_after=5) 929 | return 930 | 931 | try: 932 | ascii_art = pyfiglet.figlet_format(message) 933 | await ctx.send(f"```\n{ascii_art}\n```", delete_after=5) 934 | except Exception as e: 935 | await ctx.send(f"> **[ERROR]**: An error occurred while generating the ASCII art. `{e}`", delete_after=5) 936 | 937 | 938 | 939 | @bot.command() 940 | async def playing(ctx, *, status: str=None): 941 | await ctx.message.delete() 942 | 943 | if not status: 944 | await ctx.send(f"> **[**ERROR**]**: Invalid command.\n> __Command__: `playing `", delete_after=5) 945 | return 946 | 947 | await bot.change_presence(activity=discord.Game(name=status)) 948 | await ctx.send(f"> Successfully set the game status to `{status}`", delete_after=5) 949 | 950 | @bot.command() 951 | async def streaming(ctx, *, status: str=None): 952 | await ctx.message.delete() 953 | 954 | if not status: 955 | await ctx.send(f"> **[**ERROR**]**: Invalid command.\n> __Command__: `streaming `", delete_after=5) 956 | return 957 | 958 | await bot.change_presence(activity=discord.Streaming(name=status, url=f"https://www.twitch.tv/{status}")) 959 | await ctx.send(f"> Successfully set the streaming status to `{status}`", delete_after=5) 960 | 961 | @bot.command(aliases=["stopstreaming", "stopstatus", "stoplistening", "stopplaying", "stopwatching"]) 962 | async def stopactivity(ctx): 963 | await ctx.message.delete() 964 | 965 | await bot.change_presence(activity=None, status=discord.Status.dnd) 966 | 967 | @bot.command() 968 | async def dmall(ctx, *, message: str="https://discord.gg/PKR7nM9j9U"): 969 | await ctx.message.delete() 970 | 971 | if not ctx.guild: 972 | await ctx.send("> **[**ERROR**]**: This command can only be used in a server", delete_after=5) 973 | return 974 | 975 | members = [m for m in ctx.guild.members if not m.bot] 976 | total_members = len(members) 977 | estimated_time = round(total_members * 4.5) 978 | 979 | await ctx.send(f">Starting DM process for `{total_members}` members.\n> Estimated time: `{estimated_time} seconds` (~{round(estimated_time / 60, 2)} minutes)", delete_after=10) 980 | 981 | success_count = 0 982 | fail_count = 0 983 | 984 | for member in members: 985 | try: 986 | await member.send(message) 987 | success_count += 1 988 | except Exception: 989 | fail_count += 1 990 | 991 | await asyncio.sleep(random.uniform(3, 6)) 992 | 993 | await ctx.send(f"> **[**INFO**]**: DM process completed.\n> Successfully sent: `{success_count}`\n> Failed: `{fail_count}`", delete_after=10) 994 | 995 | bot.run(token) 996 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | requests 2 | colorama 3 | discord.py-self 4 | gtts 5 | qrcode 6 | pyfiglet -------------------------------------------------------------------------------- /setup.bat: -------------------------------------------------------------------------------- 1 | python -m pip install -r requirements.txt 2 | cls 3 | echo python main.py >> start.bat 4 | start start.bat 5 | start /b "" cmd /c &exit /b 6 | --------------------------------------------------------------------------------