├── 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 |
--------------------------------------------------------------------------------