wpms commited on
Commit
00e671d
·
verified ·
1 Parent(s): 8b720e3

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +327 -160
main.py CHANGED
@@ -1,5 +1,3 @@
1
- from flask import Flask
2
- from threading import Thread
3
  import discord
4
  from discord.ext import commands, tasks
5
  import os
@@ -7,57 +5,39 @@ import asyncio
7
  from datetime import datetime
8
  import logging
9
 
10
- # ================= WEB SERVER =================
11
-
12
- app = Flask(__name__)
13
-
14
- @app.route('/')
15
- def home():
16
- return "hey, bot started✅"
17
-
18
- def run_web():
19
- app.run(host='0.0.0.0', port=7860)
20
-
21
- Thread(target=run_web).start()
22
-
23
- # ================= LOGGING =================
24
-
25
  logging.basicConfig(
26
  level=logging.INFO,
27
  format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
28
  )
29
  logger = logging.getLogger('discord_bot')
30
 
31
- # ================= BOT CONFIG =================
32
-
33
  TOKEN = os.getenv('DISCORD_TOKEN')
34
-
35
  if not TOKEN:
36
  raise ValueError("DISCORD_TOKEN environment variable is required!")
37
 
38
- # ================= BOT INTENTS =================
39
-
40
  intents = discord.Intents.default()
41
- intents.message_content = True
42
  intents.members = True
43
  intents.presences = True
44
 
45
- # ================= BOT INSTANCE =================
46
-
47
  bot = commands.Bot(
48
  command_prefix='!',
49
  intents=intents,
50
- help_command=None,
51
  case_insensitive=True
52
  )
53
 
54
- # ================= READY EVENT =================
55
-
56
  @bot.event
57
  async def on_ready():
58
- logger.info(f'✅ Bot logged in as {bot.user.name} ({bot.user.id})')
59
- logger.info(f'🌐 Connected to {len(bot.guilds)} guilds')
60
-
 
61
  await bot.change_presence(
62
  activity=discord.Activity(
63
  type=discord.ActivityType.watching,
@@ -65,12 +45,11 @@ async def on_ready():
65
  ),
66
  status=discord.Status.online
67
  )
 
 
 
68
 
69
- if not status_update.is_running():
70
- status_update.start()
71
-
72
- # ================= STATUS UPDATE =================
73
-
74
  @tasks.loop(minutes=5)
75
  async def status_update():
76
  await bot.change_presence(
@@ -81,221 +60,409 @@ async def status_update():
81
  status=discord.Status.online
82
  )
83
 
84
- # ================= GUILD EVENTS =================
85
-
86
  @bot.event
87
  async def on_guild_join(guild):
88
- logger.info(f'➕ Joined guild: {guild.name} ({guild.id})')
89
 
 
90
  @bot.event
91
  async def on_guild_remove(guild):
92
- logger.info(f'➖ Left guild: {guild.name} ({guild.id})')
93
-
94
- # ================= MESSAGE EVENT =================
95
 
 
96
  @bot.event
97
  async def on_message(message):
 
98
  if message.author.bot:
99
  return
100
-
 
101
  await bot.process_commands(message)
102
 
103
- # ================= HELP COMMAND =================
104
-
105
- @bot.command(name='help')
106
- async def help_command(ctx):
107
- embed = discord.Embed(
108
- title="🤖 Bot Commands",
109
- description="""
110
- `!ping` - Check bot latency
111
- `!info` - Bot info
112
- `!say <text>` - Bot repeats text
113
- `!avatar` - Show avatar
114
- `!uptime` - Show uptime
115
- `!coinflip` - Flip a coin
116
- `!8ball <question>` - Ask 8ball
117
- """,
118
- color=discord.Color.blue()
119
- )
120
-
121
- await ctx.send(embed=embed)
122
-
123
- # ================= PING =================
124
-
125
- @bot.command(name='ping')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  async def ping_command(ctx):
 
127
  latency = round(bot.latency * 1000)
128
-
129
  embed = discord.Embed(
130
- title="🏓 Pong!",
131
- description=f"Latency: `{latency}ms`",
132
- color=discord.Color.green()
133
  )
134
-
135
  await ctx.send(embed=embed)
136
 
137
- # ================= INFO =================
138
-
139
- @bot.command(name='info')
140
  async def info_command(ctx):
 
141
  embed = discord.Embed(
142
- title="🤖 Bot Information",
143
- color=discord.Color.blue()
 
 
144
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
 
146
- embed.add_field(name="Bot Name", value=bot.user.name)
147
- embed.add_field(name="Servers", value=len(bot.guilds))
148
- embed.add_field(name="Users", value=sum(g.member_count for g in bot.guilds))
149
- embed.add_field(name="Uptime", value=get_uptime())
150
-
151
- if bot.user.avatar:
152
- embed.set_thumbnail(url=bot.user.avatar.url)
153
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  await ctx.send(embed=embed)
155
 
156
- # ================= AVATAR =================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
 
158
- @bot.command(name='avatar')
 
159
  async def avatar_command(ctx, member: discord.Member = None):
 
160
  member = member or ctx.author
161
-
162
  embed = discord.Embed(
163
- title=f"{member.name}'s Avatar",
164
  color=discord.Color.blue()
165
  )
166
-
167
  avatar_url = member.avatar.url if member.avatar else member.default_avatar.url
168
-
169
  embed.set_image(url=avatar_url)
170
-
 
171
  await ctx.send(embed=embed)
172
 
173
- # ================= SAY =================
174
-
175
- @bot.command(name='say')
176
- async def say_command(ctx, *, message):
177
  await ctx.message.delete()
178
  await ctx.send(message)
179
 
180
- # ================= UPTIME =================
181
-
182
- @bot.command(name='uptime')
183
- async def uptime_command(ctx):
184
  embed = discord.Embed(
185
- title="⏱️ Uptime",
186
- description=get_uptime(),
187
- color=discord.Color.blue()
188
  )
189
-
190
  await ctx.send(embed=embed)
191
 
192
- # ================= 8BALL =================
193
-
194
- @bot.command(name='8ball')
195
- async def eightball_command(ctx, *, question):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  import random
197
-
198
  responses = [
199
- "Yes",
200
- "No",
201
- "Maybe",
202
- "Definitely",
203
- "Never",
204
- "Ask later"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205
  ]
206
-
207
  embed = discord.Embed(
208
- title="🎱 8Ball",
209
  color=discord.Color.purple()
210
  )
211
-
212
  embed.add_field(name="Question", value=question, inline=False)
213
  embed.add_field(name="Answer", value=random.choice(responses), inline=False)
214
-
215
  await ctx.send(embed=embed)
216
 
217
- # ================= COINFLIP =================
218
-
219
- @bot.command(name='coinflip')
220
  async def coinflip_command(ctx):
 
221
  import random
222
-
223
  result = random.choice(["Heads", "Tails"])
224
-
 
225
  embed = discord.Embed(
226
- title="🪙 Coin Flip",
227
- description=f"Result: **{result}**",
228
  color=discord.Color.gold()
229
  )
230
-
231
  await ctx.send(embed=embed)
232
 
233
- # ================= CLEAR =================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
234
 
235
- @bot.command(name='clear')
 
236
  @commands.has_permissions(manage_messages=True)
237
  async def clear_command(ctx, amount: int = 5):
238
-
239
  if amount < 1 or amount > 100:
240
- return await ctx.send("❌ Amount must be between 1-100")
241
-
 
242
  deleted = await ctx.channel.purge(limit=amount + 1)
243
-
244
- msg = await ctx.send(f"🗑️ Deleted {len(deleted)-1} messages")
245
-
 
 
246
  await asyncio.sleep(3)
247
  await msg.delete()
248
 
249
- # ================= ERROR HANDLER =================
 
 
 
 
 
 
 
 
 
250
 
 
251
  @bot.event
252
  async def on_command_error(ctx, error):
253
-
254
  if isinstance(error, commands.CommandNotFound):
255
- return
256
-
257
- elif isinstance(error, commands.MissingPermissions):
258
- await ctx.send("❌ You don't have permission.")
259
-
260
  elif isinstance(error, commands.MissingRequiredArgument):
261
- await ctx.send("❌ Missing argument.")
262
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
263
  else:
264
- logger.error(error)
265
- await ctx.send("❌ Error occurred.")
266
-
267
- # ================= UPTIME FUNCTION =================
268
-
 
 
 
 
269
  start_time = datetime.now()
270
 
271
  def get_uptime():
272
  delta = datetime.now() - start_time
273
-
274
  days = delta.days
275
  hours, remainder = divmod(delta.seconds, 3600)
276
  minutes, seconds = divmod(remainder, 60)
277
-
278
  parts = []
279
-
280
  if days > 0:
281
  parts.append(f"{days}d")
282
-
283
  if hours > 0:
284
  parts.append(f"{hours}h")
285
-
286
  if minutes > 0:
287
  parts.append(f"{minutes}m")
288
-
289
  parts.append(f"{seconds}s")
290
-
291
  return " ".join(parts)
292
 
293
- # ================= START BOT =================
294
-
295
  if __name__ == "__main__":
296
  try:
297
- logger.info("🚀 Starting bot...")
298
  bot.run(TOKEN)
299
-
300
  except Exception as e:
301
- logger.error(f"Failed to start bot: {e}")
 
 
 
 
1
  import discord
2
  from discord.ext import commands, tasks
3
  import os
 
5
  from datetime import datetime
6
  import logging
7
 
8
+ # Setup logging
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  logging.basicConfig(
10
  level=logging.INFO,
11
  format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
12
  )
13
  logger = logging.getLogger('discord_bot')
14
 
15
+ # Bot configuration
 
16
  TOKEN = os.getenv('DISCORD_TOKEN')
 
17
  if not TOKEN:
18
  raise ValueError("DISCORD_TOKEN environment variable is required!")
19
 
20
+ # Bot intents
 
21
  intents = discord.Intents.default()
22
+ intents.message_content = True # Required for reading message content
23
  intents.members = True
24
  intents.presences = True
25
 
26
+ # Create bot instance
 
27
  bot = commands.Bot(
28
  command_prefix='!',
29
  intents=intents,
30
+ help_command=None, # Custom help command
31
  case_insensitive=True
32
  )
33
 
34
+ # Event: Bot ready
 
35
  @bot.event
36
  async def on_ready():
37
+ logger.info(f'✅ Bot logged in as {bot.user.name} ({bot.user.id})')
38
+ logger.info(f'🌐 Connected to {len(bot.guilds)} guilds')
39
+
40
+ # Set bot status
41
  await bot.change_presence(
42
  activity=discord.Activity(
43
  type=discord.ActivityType.watching,
 
45
  ),
46
  status=discord.Status.online
47
  )
48
+
49
+ # Start background tasks
50
+ status_update.start()
51
 
52
+ # Background task: Update status every 5 minutes
 
 
 
 
53
  @tasks.loop(minutes=5)
54
  async def status_update():
55
  await bot.change_presence(
 
60
  status=discord.Status.online
61
  )
62
 
63
+ # Event: When bot joins a new guild
 
64
  @bot.event
65
  async def on_guild_join(guild):
66
+ logger.info(f'âž• Joined guild: {guild.name} ({guild.id})')
67
 
68
+ # Event: When bot leaves a guild
69
  @bot.event
70
  async def on_guild_remove(guild):
71
+ logger.info(f'âž– Left guild: {guild.name} ({guild.id})')
 
 
72
 
73
+ # Event: Handle messages (for non-command messages)
74
  @bot.event
75
  async def on_message(message):
76
+ # Ignore bot messages
77
  if message.author.bot:
78
  return
79
+
80
+ # Process commands
81
  await bot.process_commands(message)
82
 
83
+ # ==================== COMMANDS ====================
84
+
85
+ # Help Command
86
+ @bot.command(name='help', aliases=['h', 'commands'])
87
+ async def help_command(ctx, command_name: str = None):
88
+ """Show help information"""
89
+ if command_name:
90
+ # Show specific command help
91
+ command = bot.get_command(command_name)
92
+ if command:
93
+ embed = discord.Embed(
94
+ title=f"📖 Help: !{command.name}",
95
+ description=command.help or "No description available",
96
+ color=discord.Color.blue()
97
+ )
98
+ embed.add_field(
99
+ name="Usage",
100
+ value=f"`!{command.name} {command.signature}`" if command.signature else f"`!{command.name}`",
101
+ inline=False
102
+ )
103
+ if command.aliases:
104
+ embed.add_field(
105
+ name="Aliases",
106
+ value=", ".join([f"`!{alias}`" for alias in command.aliases]),
107
+ inline=False
108
+ )
109
+ await ctx.send(embed=embed)
110
+ else:
111
+ await ctx.send(f"❌ Command `!{command_name}` not found!")
112
+ else:
113
+ # Show all commands
114
+ embed = discord.Embed(
115
+ title="🤖 Bot Commands",
116
+ description="Here are all available commands:",
117
+ color=discord.Color.blue(),
118
+ timestamp=datetime.now()
119
+ )
120
+
121
+ # Categorize commands
122
+ categories = {
123
+ "General": ['help', 'ping', 'info', 'serverinfo', 'userinfo'],
124
+ "Fun": ['say', 'embed', 'poll', '8ball', 'coinflip'],
125
+ "Utility": ['avatar', 'invite', 'uptime', 'clear']
126
+ }
127
+
128
+ for category, cmds in categories.items():
129
+ valid_cmds = []
130
+ for cmd_name in cmds:
131
+ cmd = bot.get_command(cmd_name)
132
+ if cmd:
133
+ valid_cmds.append(f"`!{cmd.name}`")
134
+ if valid_cmds:
135
+ embed.add_field(
136
+ name=f"📁 {category}",
137
+ value=" | ".join(valid_cmds),
138
+ inline=False
139
+ )
140
+
141
+ embed.set_footer(text=f"Use !help <command> for more details | Prefix: !")
142
+ await ctx.send(embed=embed)
143
+
144
+ # Ping Command
145
+ @bot.command(name='ping', aliases=['latency'])
146
  async def ping_command(ctx):
147
+ """Check bot latency"""
148
  latency = round(bot.latency * 1000)
149
+
150
  embed = discord.Embed(
151
+ title="🏓 Pong!",
152
+ description=f"**Latency:** `{latency}ms`\n**API Latency:** `{round(bot.latency * 1000)}ms`",
153
+ color=discord.Color.green() if latency < 200 else discord.Color.orange() if latency < 500 else discord.Color.red()
154
  )
155
+ embed.set_footer(text=f"Requested by {ctx.author.name}")
156
  await ctx.send(embed=embed)
157
 
158
+ # Info Command
159
+ @bot.command(name='info', aliases=['botinfo', 'about'])
 
160
  async def info_command(ctx):
161
+ """Show bot information"""
162
  embed = discord.Embed(
163
+ title="🤖 Bot Information",
164
+ description="A Discord bot powered by discord.py",
165
+ color=discord.Color.blue(),
166
+ timestamp=datetime.now()
167
  )
168
+
169
+ embed.add_field(name="Bot Name", value=bot.user.name, inline=True)
170
+ embed.add_field(name="Bot ID", value=bot.user.id, inline=True)
171
+ embed.add_field(name="Servers", value=len(bot.guilds), inline=True)
172
+ embed.add_field(name="Users", value=sum(g.member_count for g in bot.guilds), inline=True)
173
+ embed.add_field(name="Library", value="discord.py", inline=True)
174
+ embed.add_field(name="Python Version", value="3.10+", inline=True)
175
+ embed.add_field(name="Created", value=bot.user.created_at.strftime("%Y-%m-%d"), inline=True)
176
+ embed.add_field(name="Uptime", value=get_uptime(), inline=True)
177
+
178
+ embed.set_thumbnail(url=bot.user.avatar.url if bot.user.avatar else bot.user.default_avatar.url)
179
+ embed.set_footer(text="Made with ❤️ using discord.py")
180
+
181
+ await ctx.send(embed=embed)
182
 
183
+ # Server Info Command
184
+ @bot.command(name='serverinfo', aliases=['server', 'guildinfo'])
185
+ async def serverinfo_command(ctx):
186
+ """Show server information"""
187
+ guild = ctx.guild
188
+
189
+ embed = discord.Embed(
190
+ title=f"📊 {guild.name} Server Info",
191
+ color=discord.Color.blue(),
192
+ timestamp=datetime.now()
193
+ )
194
+
195
+ embed.add_field(name="Server ID", value=guild.id, inline=True)
196
+ embed.add_field(name="Owner", value=guild.owner.mention if guild.owner else "Unknown", inline=True)
197
+ embed.add_field(name="Members", value=guild.member_count, inline=True)
198
+ embed.add_field(name="Channels", value=f"{len(guild.text_channels)} Text | {len(guild.voice_channels)} Voice", inline=True)
199
+ embed.add_field(name="Roles", value=len(guild.roles), inline=True)
200
+ embed.add_field(name="Created", value=guild.created_at.strftime("%Y-%m-%d"), inline=True)
201
+ embed.add_field(name="Boost Level", value=f"Level {guild.premium_tier} ({guild.premium_subscription_count} boosts)", inline=True)
202
+
203
+ if guild.icon:
204
+ embed.set_thumbnail(url=guild.icon.url)
205
+
206
  await ctx.send(embed=embed)
207
 
208
+ # User Info Command
209
+ @bot.command(name='userinfo', aliases=['whois', 'profile'])
210
+ async def userinfo_command(ctx, member: discord.Member = None):
211
+ """Show user information"""
212
+ member = member or ctx.author
213
+
214
+ embed = discord.Embed(
215
+ title=f"👤 {member.name}'s Profile",
216
+ color=member.color if member.color != discord.Color.default() else discord.Color.blue(),
217
+ timestamp=datetime.now()
218
+ )
219
+
220
+ embed.add_field(name="Username", value=member.name, inline=True)
221
+ embed.add_field(name="Display Name", value=member.display_name, inline=True)
222
+ embed.add_field(name="ID", value=member.id, inline=True)
223
+ embed.add_field(name="Joined Server", value=member.joined_at.strftime("%Y-%m-%d %H:%M") if member.joined_at else "Unknown", inline=True)
224
+ embed.add_field(name="Account Created", value=member.created_at.strftime("%Y-%m-%d %H:%M"), inline=True)
225
+ embed.add_field(name="Status", value=str(member.status).title(), inline=True)
226
+ embed.add_field(name="Top Role", value=member.top_role.mention, inline=True)
227
+ embed.add_field(name="Bot?", value="Yes" if member.bot else "No", inline=True)
228
+
229
+ roles = [role.mention for role in member.roles if role != ctx.guild.default_role]
230
+ if roles:
231
+ embed.add_field(name=f"Roles ({len(roles)})", value=" ".join(roles[:10]) + ("..." if len(roles) > 10 else ""), inline=False)
232
+
233
+ embed.set_thumbnail(url=member.avatar.url if member.avatar else member.default_avatar.url)
234
+ embed.set_footer(text=f"Requested by {ctx.author.name}")
235
+
236
+ await ctx.send(embed=embed)
237
 
238
+ # Avatar Command
239
+ @bot.command(name='avatar', aliases=['av', 'pfp'])
240
  async def avatar_command(ctx, member: discord.Member = None):
241
+ """Show user's avatar"""
242
  member = member or ctx.author
243
+
244
  embed = discord.Embed(
245
+ title=f"🖼️ {member.name}'s Avatar",
246
  color=discord.Color.blue()
247
  )
248
+
249
  avatar_url = member.avatar.url if member.avatar else member.default_avatar.url
 
250
  embed.set_image(url=avatar_url)
251
+ embed.add_field(name="Links", value=f"[PNG]({member.avatar.url if member.avatar else member.default_avatar.url}) | [WEBP]({member.avatar.url if member.avatar else member.default_avatar.url})", inline=False)
252
+
253
  await ctx.send(embed=embed)
254
 
255
+ # Say Command
256
+ @bot.command(name='say', aliases=['echo'])
257
+ async def say_command(ctx, *, message: str):
258
+ """Make the bot say something"""
259
  await ctx.message.delete()
260
  await ctx.send(message)
261
 
262
+ # Embed Command
263
+ @bot.command(name='embed', aliases=['em'])
264
+ async def embed_command(ctx, *, message: str):
265
+ """Create a custom embed"""
266
  embed = discord.Embed(
267
+ description=message,
268
+ color=discord.Color.blue(),
269
+ timestamp=datetime.now()
270
  )
271
+ embed.set_author(name=ctx.author.name, icon_url=ctx.author.avatar.url if ctx.author.avatar else ctx.author.default_avatar.url)
272
  await ctx.send(embed=embed)
273
 
274
+ # Poll Command
275
+ @bot.command(name='poll', aliases=['vote'])
276
+ async def poll_command(ctx, *, question: str):
277
+ """Create a poll"""
278
+ embed = discord.Embed(
279
+ title="📊 Poll",
280
+ description=question,
281
+ color=discord.Color.blue(),
282
+ timestamp=datetime.now()
283
+ )
284
+ embed.set_footer(text=f"Poll by {ctx.author.name}")
285
+
286
+ poll_message = await ctx.send(embed=embed)
287
+ await poll_message.add_reaction("👍")
288
+ await poll_message.add_reaction("👎")
289
+ await poll_message.add_reaction("🤷")
290
+
291
+ # 8Ball Command
292
+ @bot.command(name='8ball', aliases=['magic8ball', 'ask'])
293
+ async def eightball_command(ctx, *, question: str):
294
+ """Ask the magic 8-ball"""
295
  import random
296
+
297
  responses = [
298
+ "🎱 It is certain.",
299
+ "🎱 It is decidedly so.",
300
+ "🎱 Without a doubt.",
301
+ "🎱 Yes definitely.",
302
+ "🎱 You may rely on it.",
303
+ "🎱 As I see it, yes.",
304
+ "🎱 Most likely.",
305
+ "🎱 Outlook good.",
306
+ "🎱 Yes.",
307
+ "🎱 Signs point to yes.",
308
+ "🎱 Reply hazy, try again.",
309
+ "🎱 Ask again later.",
310
+ "🎱 Better not tell you now.",
311
+ "🎱 Cannot predict now.",
312
+ "🎱 Concentrate and ask again.",
313
+ "🎱 Don't count on it.",
314
+ "🎱 My reply is no.",
315
+ "🎱 My sources say no.",
316
+ "🎱 Outlook not so good.",
317
+ "🎱 Very doubtful."
318
  ]
319
+
320
  embed = discord.Embed(
321
+ title="🎱 Magic 8-Ball",
322
  color=discord.Color.purple()
323
  )
 
324
  embed.add_field(name="Question", value=question, inline=False)
325
  embed.add_field(name="Answer", value=random.choice(responses), inline=False)
326
+
327
  await ctx.send(embed=embed)
328
 
329
+ # Coin Flip Command
330
+ @bot.command(name='coinflip', aliases=['flip', 'coin'])
 
331
  async def coinflip_command(ctx):
332
+ """Flip a coin"""
333
  import random
334
+
335
  result = random.choice(["Heads", "Tails"])
336
+ emoji = "🪙" if result == "Heads" else "🪙"
337
+
338
  embed = discord.Embed(
339
+ title=f"{emoji} Coin Flip",
340
+ description=f"**Result:** {result}",
341
  color=discord.Color.gold()
342
  )
343
+
344
  await ctx.send(embed=embed)
345
 
346
+ # Invite Command
347
+ @bot.command(name='invite', aliases=['addbot'])
348
+ async def invite_command(ctx):
349
+ """Get bot invite link"""
350
+ permissions = discord.Permissions(
351
+ send_messages=True,
352
+ embed_links=True,
353
+ read_messages=True,
354
+ read_message_history=True,
355
+ add_reactions=True,
356
+ use_external_emojis=True,
357
+ attach_files=True,
358
+ manage_messages=True,
359
+ connect=True,
360
+ speak=True
361
+ )
362
+
363
+ invite_url = discord.utils.oauth_url(bot.user.id, permissions=permissions)
364
+
365
+ embed = discord.Embed(
366
+ title="🔗 Invite Bot",
367
+ description=f"[Click here to invite me!]({invite_url})",
368
+ color=discord.Color.green()
369
+ )
370
+ embed.add_field(name="Bot ID", value=bot.user.id, inline=False)
371
+
372
+ await ctx.send(embed=embed)
373
 
374
+ # Clear Command
375
+ @bot.command(name='clear', aliases=['purge', 'clean'])
376
  @commands.has_permissions(manage_messages=True)
377
  async def clear_command(ctx, amount: int = 5):
378
+ """Clear messages (requires Manage Messages permission)"""
379
  if amount < 1 or amount > 100:
380
+ await ctx.send("❌ Please specify a number between 1 and 100!")
381
+ return
382
+
383
  deleted = await ctx.channel.purge(limit=amount + 1)
384
+ embed = discord.Embed(
385
+ description=f"🗑️ Deleted {len(deleted) - 1} messages!",
386
+ color=discord.Color.green()
387
+ )
388
+ msg = await ctx.send(embed=embed)
389
  await asyncio.sleep(3)
390
  await msg.delete()
391
 
392
+ # Uptime Command
393
+ @bot.command(name='uptime', aliases=['up'])
394
+ async def uptime_command(ctx):
395
+ """Show bot uptime"""
396
+ embed = discord.Embed(
397
+ title="⏱️ Bot Uptime",
398
+ description=get_uptime(),
399
+ color=discord.Color.blue()
400
+ )
401
+ await ctx.send(embed=embed)
402
 
403
+ # Error Handler
404
  @bot.event
405
  async def on_command_error(ctx, error):
 
406
  if isinstance(error, commands.CommandNotFound):
407
+ return # Ignore unknown commands
408
+
 
 
 
409
  elif isinstance(error, commands.MissingRequiredArgument):
410
+ embed = discord.Embed(
411
+ title="❌ Missing Argument",
412
+ description=f"Missing required argument: `{error.param.name}`\nUse `!help {ctx.command.name}` for usage info.",
413
+ color=discord.Color.red()
414
+ )
415
+ await ctx.send(embed=embed)
416
+
417
+ elif isinstance(error, commands.MissingPermissions):
418
+ embed = discord.Embed(
419
+ title="❌ Missing Permissions",
420
+ description=f"You need `{', '.join(error.missing_permissions)}` permission to use this command.",
421
+ color=discord.Color.red()
422
+ )
423
+ await ctx.send(embed=embed)
424
+
425
+ elif isinstance(error, commands.MemberNotFound):
426
+ embed = discord.Embed(
427
+ title="❌ User Not Found",
428
+ description="The specified user was not found.",
429
+ color=discord.Color.red()
430
+ )
431
+ await ctx.send(embed=embed)
432
+
433
  else:
434
+ logger.error(f"Command error: {error}")
435
+ embed = discord.Embed(
436
+ title="❌ Error",
437
+ description="An unexpected error occurred. Please try again later.",
438
+ color=discord.Color.red()
439
+ )
440
+ await ctx.send(embed=embed)
441
+
442
+ # Helper function: Get uptime
443
  start_time = datetime.now()
444
 
445
  def get_uptime():
446
  delta = datetime.now() - start_time
 
447
  days = delta.days
448
  hours, remainder = divmod(delta.seconds, 3600)
449
  minutes, seconds = divmod(remainder, 60)
450
+
451
  parts = []
 
452
  if days > 0:
453
  parts.append(f"{days}d")
 
454
  if hours > 0:
455
  parts.append(f"{hours}h")
 
456
  if minutes > 0:
457
  parts.append(f"{minutes}m")
 
458
  parts.append(f"{seconds}s")
459
+
460
  return " ".join(parts)
461
 
462
+ # Run the bot
 
463
  if __name__ == "__main__":
464
  try:
 
465
  bot.run(TOKEN)
 
466
  except Exception as e:
467
+ logger.error(f"Failed to start bot: {e}")
468
+ raise