wpms commited on
Commit
48554f5
·
verified ·
1 Parent(s): 815f04e

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +143 -257
main.py CHANGED
@@ -1,13 +1,11 @@
1
  import discord
2
  from discord.ext import commands, tasks
3
- from discord import app_commands
4
  import os
5
  import asyncio
6
  from datetime import datetime
7
  import logging
8
  from flask import Flask
9
  from threading import Thread
10
- import random
11
 
12
  # Setup logging
13
  logging.basicConfig(
@@ -37,15 +35,15 @@ if not TOKEN:
37
 
38
  # Bot intents
39
  intents = discord.Intents.default()
40
- intents.message_content = True
41
  intents.members = True
42
  intents.presences = True
43
 
44
- # Create bot instance - NO prefix needed for slash commands
45
  bot = commands.Bot(
46
- command_prefix=None,
47
  intents=intents,
48
- help_command=None,
49
  case_insensitive=True
50
  )
51
 
@@ -55,18 +53,11 @@ async def on_ready():
55
  logger.info(f'✅ Bot logged in as {bot.user.name} ({bot.user.id})')
56
  logger.info(f'🌐 Connected to {len(bot.guilds)} guilds')
57
 
58
- # Sync slash commands globally
59
- try:
60
- synced = await bot.tree.sync()
61
- logger.info(f'✅ Synced {len(synced)} slash commands globally')
62
- except Exception as e:
63
- logger.error(f'❌ Failed to sync commands: {e}')
64
-
65
  # Set bot status
66
  await bot.change_presence(
67
  activity=discord.Activity(
68
  type=discord.ActivityType.watching,
69
- name=f"{len(bot.guilds)} servers | /help"
70
  ),
71
  status=discord.Status.online
72
  )
@@ -80,7 +71,7 @@ async def status_update():
80
  await bot.change_presence(
81
  activity=discord.Activity(
82
  type=discord.ActivityType.watching,
83
- name=f"{len(bot.guilds)} servers | /help"
84
  ),
85
  status=discord.Status.online
86
  )
@@ -95,175 +86,94 @@ async def on_guild_join(guild):
95
  async def on_guild_remove(guild):
96
  logger.info(f'➖ Left guild: {guild.name} ({guild.id})')
97
 
98
- # ==================== SLASH COMMANDS ====================
99
-
100
- # Help Command - Shows all commands in chat with autocomplete
101
- @bot.tree.command(name="help", description="Show all available commands")
102
- @app_commands.describe(command_name="Specific command to get help for")
103
- @app_commands.choices(command_name=[
104
- app_commands.Choice(name="help", value="help"),
105
- app_commands.Choice(name="ping", value="ping"),
106
- app_commands.Choice(name="info", value="info"),
107
- app_commands.Choice(name="serverinfo", value="serverinfo"),
108
- app_commands.Choice(name="userinfo", value="userinfo"),
109
- app_commands.Choice(name="avatar", value="avatar"),
110
- app_commands.Choice(name="say", value="say"),
111
- app_commands.Choice(name="embed", value="embed"),
112
- app_commands.Choice(name="poll", value="poll"),
113
- app_commands.Choice(name="8ball", value="8ball"),
114
- app_commands.Choice(name="coinflip", value="coinflip"),
115
- app_commands.Choice(name="invite", value="invite"),
116
- app_commands.Choice(name="clear", value="clear"),
117
- app_commands.Choice(name="uptime", value="uptime"),
118
- ])
119
- async def help_command(interaction: discord.Interaction, command_name: str = None):
120
  """Show help information"""
121
  if command_name:
122
- command_details = {
123
- "help": {
124
- "description": "Show all available commands or specific command help",
125
- "usage": "/help [command_name]",
126
- "examples": ["/help", "/help ping"]
127
- },
128
- "ping": {
129
- "description": "Check bot latency and API response time",
130
- "usage": "/ping",
131
- "examples": ["/ping"]
132
- },
133
- "info": {
134
- "description": "Show bot information and statistics",
135
- "usage": "/info",
136
- "examples": ["/info"]
137
- },
138
- "serverinfo": {
139
- "description": "Show server information",
140
- "usage": "/serverinfo",
141
- "examples": ["/serverinfo"]
142
- },
143
- "userinfo": {
144
- "description": "Show user information",
145
- "usage": "/userinfo [member]",
146
- "examples": ["/userinfo", "/userinfo @user"]
147
- },
148
- "avatar": {
149
- "description": "Show user's avatar in full size",
150
- "usage": "/avatar [member]",
151
- "examples": ["/avatar", "/avatar @user"]
152
- },
153
- "say": {
154
- "description": "Make the bot say something",
155
- "usage": "/say <message>",
156
- "examples": ["/say Hello everyone!"]
157
- },
158
- "embed": {
159
- "description": "Create a custom embed message",
160
- "usage": "/embed <message>",
161
- "examples": ["/embed This is a custom embed"]
162
- },
163
- "poll": {
164
- "description": "Create a poll with 👍 👎 🤷 reactions",
165
- "usage": "/poll <question>",
166
- "examples": ["/poll Should we add more channels?"]
167
- },
168
- "8ball": {
169
- "description": "Ask the magic 8-ball a question",
170
- "usage": "/8ball <question>",
171
- "examples": ["/8ball Will I win the lottery?"]
172
- },
173
- "coinflip": {
174
- "description": "Flip a coin (Heads or Tails)",
175
- "usage": "/coinflip",
176
- "examples": ["/coinflip"]
177
- },
178
- "invite": {
179
- "description": "Get bot invite link",
180
- "usage": "/invite",
181
- "examples": ["/invite"]
182
- },
183
- "clear": {
184
- "description": "Clear messages (requires Manage Messages permission)",
185
- "usage": "/clear <amount>",
186
- "examples": ["/clear 10"]
187
- },
188
- "uptime": {
189
- "description": "Show bot uptime",
190
- "usage": "/uptime",
191
- "examples": ["/uptime"]
192
- }
193
- }
194
-
195
- if command_name in command_details:
196
- details = command_details[command_name]
197
  embed = discord.Embed(
198
- title=f"📖 Help: /{command_name}",
199
- description=details["description"],
200
  color=discord.Color.blue()
201
  )
202
- embed.add_field(name="Usage", value=f"`{details['usage']}`", inline=False)
203
- embed.add_field(name="Examples", value="\n".join([f"`{ex}`" for ex in details["examples"]]), inline=False)
204
- await interaction.response.send_message(embed=embed)
 
 
 
 
 
 
 
 
 
205
  else:
206
- await interaction.response.send_message(f"❌ Command `/{command_name}` not found!", ephemeral=True)
207
  else:
 
208
  embed = discord.Embed(
209
  title="🤖 Bot Commands",
210
- description="Here are all available slash commands:",
211
  color=discord.Color.blue(),
212
  timestamp=datetime.now()
213
  )
214
 
 
215
  categories = {
216
- "📁 General": [
217
- "`/help` - Show commands",
218
- "`/ping` - Check latency",
219
- "`/info` - Bot info",
220
- "`/serverinfo` - Server info",
221
- "`/userinfo` - User info",
222
- "`/uptime` - Bot uptime"
223
- ],
224
- "🎉 Fun": [
225
- "`/say` - Bot says something",
226
- "`/embed` - Custom embed",
227
- "`/poll` - Create poll",
228
- "`/8ball` - Magic 8-ball",
229
- "`/coinflip` - Flip a coin"
230
- ],
231
- "🛠️ Utility": [
232
- "`/avatar` - Show avatar",
233
- "`/invite` - Bot invite link",
234
- "`/clear` - Clear messages"
235
- ]
236
  }
237
 
238
  for category, cmds in categories.items():
239
- embed.add_field(
240
- name=category,
241
- value="\n".join(cmds),
242
- inline=False
243
- )
 
 
 
 
 
 
244
 
245
- embed.set_footer(text="Use /help <command> for more details")
246
- await interaction.response.send_message(embed=embed)
247
 
248
  # Ping Command
249
- @bot.tree.command(name="ping", description="Check bot latency")
250
- async def ping_command(interaction: discord.Interaction):
251
  """Check bot latency"""
252
  latency = round(bot.latency * 1000)
253
 
254
- color = discord.Color.green() if latency < 200 else discord.Color.orange() if latency < 500 else discord.Color.red()
255
-
256
  embed = discord.Embed(
257
  title="🏓 Pong!",
258
  description=f"**Latency:** `{latency}ms`\n**API Latency:** `{round(bot.latency * 1000)}ms`",
259
- color=color
260
  )
261
- embed.set_footer(text=f"Requested by {interaction.user.name}")
262
- await interaction.response.send_message(embed=embed)
263
 
264
  # Info Command
265
- @bot.tree.command(name="info", description="Show bot information")
266
- async def info_command(interaction: discord.Interaction):
267
  """Show bot information"""
268
  embed = discord.Embed(
269
  title="🤖 Bot Information",
@@ -284,13 +194,13 @@ async def info_command(interaction: discord.Interaction):
284
  embed.set_thumbnail(url=bot.user.avatar.url if bot.user.avatar else bot.user.default_avatar.url)
285
  embed.set_footer(text="Made with ❤️ using discord.py")
286
 
287
- await interaction.response.send_message(embed=embed)
288
 
289
  # Server Info Command
290
- @bot.tree.command(name="serverinfo", description="Show server information")
291
- async def serverinfo_command(interaction: discord.Interaction):
292
  """Show server information"""
293
- guild = interaction.guild
294
 
295
  embed = discord.Embed(
296
  title=f"📊 {guild.name} Server Info",
@@ -309,14 +219,13 @@ async def serverinfo_command(interaction: discord.Interaction):
309
  if guild.icon:
310
  embed.set_thumbnail(url=guild.icon.url)
311
 
312
- await interaction.response.send_message(embed=embed)
313
 
314
  # User Info Command
315
- @bot.tree.command(name="userinfo", description="Show user information")
316
- @app_commands.describe(member="User to get info about (default: you)")
317
- async def userinfo_command(interaction: discord.Interaction, member: discord.Member = None):
318
  """Show user information"""
319
- member = member or interaction.user
320
 
321
  embed = discord.Embed(
322
  title=f"👤 {member.name}'s Profile",
@@ -333,21 +242,20 @@ async def userinfo_command(interaction: discord.Interaction, member: discord.Mem
333
  embed.add_field(name="Top Role", value=member.top_role.mention, inline=True)
334
  embed.add_field(name="Bot?", value="Yes" if member.bot else "No", inline=True)
335
 
336
- roles = [role.mention for role in member.roles if role != interaction.guild.default_role]
337
  if roles:
338
  embed.add_field(name=f"Roles ({len(roles)})", value=" ".join(roles[:10]) + ("..." if len(roles) > 10 else ""), inline=False)
339
 
340
  embed.set_thumbnail(url=member.avatar.url if member.avatar else member.default_avatar.url)
341
- embed.set_footer(text=f"Requested by {interaction.user.name}")
342
 
343
- await interaction.response.send_message(embed=embed)
344
 
345
  # Avatar Command
346
- @bot.tree.command(name="avatar", description="Show user's avatar")
347
- @app_commands.describe(member="User to show avatar (default: you)")
348
- async def avatar_command(interaction: discord.Interaction, member: discord.Member = None):
349
  """Show user's avatar"""
350
- member = member or interaction.user
351
 
352
  embed = discord.Embed(
353
  title=f"🖼️ {member.name}'s Avatar",
@@ -356,34 +264,32 @@ async def avatar_command(interaction: discord.Interaction, member: discord.Membe
356
 
357
  avatar_url = member.avatar.url if member.avatar else member.default_avatar.url
358
  embed.set_image(url=avatar_url)
359
- embed.add_field(name="Links", value=f"[PNG]({avatar_url}) | [WEBP]({avatar_url})", inline=False)
360
 
361
- await interaction.response.send_message(embed=embed)
362
 
363
  # Say Command
364
- @bot.tree.command(name="say", description="Make the bot say something")
365
- @app_commands.describe(message="Message to say")
366
- async def say_command(interaction: discord.Interaction, message: str):
367
  """Make the bot say something"""
368
- await interaction.response.send_message(message)
 
369
 
370
  # Embed Command
371
- @bot.tree.command(name="embed", description="Create a custom embed")
372
- @app_commands.describe(message="Message for the embed")
373
- async def embed_command(interaction: discord.Interaction, message: str):
374
  """Create a custom embed"""
375
  embed = discord.Embed(
376
  description=message,
377
  color=discord.Color.blue(),
378
  timestamp=datetime.now()
379
  )
380
- embed.set_author(name=interaction.user.name, icon_url=interaction.user.avatar.url if interaction.user.avatar else interaction.user.default_avatar.url)
381
- await interaction.response.send_message(embed=embed)
382
 
383
  # Poll Command
384
- @bot.tree.command(name="poll", description="Create a poll")
385
- @app_commands.describe(question="Poll question")
386
- async def poll_command(interaction: discord.Interaction, question: str):
387
  """Create a poll"""
388
  embed = discord.Embed(
389
  title="📊 Poll",
@@ -391,19 +297,19 @@ async def poll_command(interaction: discord.Interaction, question: str):
391
  color=discord.Color.blue(),
392
  timestamp=datetime.now()
393
  )
394
- embed.set_footer(text=f"Poll by {interaction.user.name}")
395
 
396
- await interaction.response.send_message(embed=embed)
397
- poll_message = await interaction.original_response()
398
  await poll_message.add_reaction("👍")
399
  await poll_message.add_reaction("👎")
400
  await poll_message.add_reaction("🤷")
401
 
402
  # 8Ball Command
403
- @bot.tree.command(name="8ball", description="Ask the magic 8-ball")
404
- @app_commands.describe(question="Your question")
405
- async def eightball_command(interaction: discord.Interaction, question: str):
406
  """Ask the magic 8-ball"""
 
 
407
  responses = [
408
  "🎱 It is certain.",
409
  "🎱 It is decidedly so.",
@@ -434,25 +340,28 @@ async def eightball_command(interaction: discord.Interaction, question: str):
434
  embed.add_field(name="Question", value=question, inline=False)
435
  embed.add_field(name="Answer", value=random.choice(responses), inline=False)
436
 
437
- await interaction.response.send_message(embed=embed)
438
 
439
  # Coin Flip Command
440
- @bot.tree.command(name="coinflip", description="Flip a coin")
441
- async def coinflip_command(interaction: discord.Interaction):
442
  """Flip a coin"""
 
 
443
  result = random.choice(["Heads", "Tails"])
 
444
 
445
  embed = discord.Embed(
446
- title=f"🪙 Coin Flip",
447
  description=f"**Result:** {result}",
448
  color=discord.Color.gold()
449
  )
450
 
451
- await interaction.response.send_message(embed=embed)
452
 
453
  # Invite Command
454
- @bot.tree.command(name="invite", description="Get bot invite link")
455
- async def invite_command(interaction: discord.Interaction):
456
  """Get bot invite link"""
457
  permissions = discord.Permissions(
458
  send_messages=True,
@@ -476,78 +385,75 @@ async def invite_command(interaction: discord.Interaction):
476
  )
477
  embed.add_field(name="Bot ID", value=bot.user.id, inline=False)
478
 
479
- await interaction.response.send_message(embed=embed)
480
 
481
  # Clear Command
482
- @bot.tree.command(name="clear", description="Clear messages")
483
- @app_commands.describe(amount="Number of messages to clear (1-100)")
484
- @app_commands.checks.has_permissions(manage_messages=True)
485
- async def clear_command(interaction: discord.Interaction, amount: int):
486
  """Clear messages (requires Manage Messages permission)"""
487
  if amount < 1 or amount > 100:
488
- await interaction.response.send_message("❌ Please specify a number between 1 and 100!", ephemeral=True)
489
  return
490
 
491
- await interaction.response.defer(ephemeral=True)
492
- deleted = await interaction.channel.purge(limit=amount)
493
  embed = discord.Embed(
494
- description=f"🗑️ Deleted {len(deleted)} messages!",
495
  color=discord.Color.green()
496
  )
497
- await interaction.followup.send(embed=embed, ephemeral=True)
498
  await asyncio.sleep(3)
499
- try:
500
- await interaction.delete_original_response()
501
- except:
502
- pass
503
 
504
  # Uptime Command
505
- @bot.tree.command(name="uptime", description="Show bot uptime")
506
- async def uptime_command(interaction: discord.Interaction):
507
  """Show bot uptime"""
508
  embed = discord.Embed(
509
  title="⏱️ Bot Uptime",
510
  description=get_uptime(),
511
  color=discord.Color.blue()
512
  )
513
- await interaction.response.send_message(embed=embed)
514
 
515
- # Error Handler for Slash Commands
516
- @bot.tree.error
517
- async def on_app_command_error(interaction: discord.Interaction, error: app_commands.AppCommandError):
518
- if isinstance(error, app_commands.MissingPermissions):
 
 
 
 
 
 
 
 
 
 
 
519
  embed = discord.Embed(
520
  title="❌ Missing Permissions",
521
  description=f"You need `{', '.join(error.missing_permissions)}` permission to use this command.",
522
  color=discord.Color.red()
523
  )
524
- if interaction.response.is_done():
525
- await interaction.followup.send(embed=embed, ephemeral=True)
526
- else:
527
- await interaction.response.send_message(embed=embed, ephemeral=True)
528
 
529
- elif isinstance(error, app_commands.CheckFailure):
530
  embed = discord.Embed(
531
- title="❌ Check Failed",
532
- description="You do not have permission to use this command.",
533
  color=discord.Color.red()
534
  )
535
- if interaction.response.is_done():
536
- await interaction.followup.send(embed=embed, ephemeral=True)
537
- else:
538
- await interaction.response.send_message(embed=embed, ephemeral=True)
539
 
540
  else:
541
- logger.error(f"Slash command error: {error}")
542
  embed = discord.Embed(
543
  title="❌ Error",
544
  description="An unexpected error occurred. Please try again later.",
545
  color=discord.Color.red()
546
  )
547
- if interaction.response.is_done():
548
- await interaction.followup.send(embed=embed, ephemeral=True)
549
- else:
550
- await interaction.response.send_message(embed=embed, ephemeral=True)
551
 
552
  # Helper function: Get uptime
553
  start_time = datetime.now()
@@ -569,30 +475,10 @@ def get_uptime():
569
 
570
  return " ".join(parts)
571
 
572
- # Retry function with exponential backoff
573
- async def run_bot_with_retry():
574
- max_retries = 10
575
- retry_delay = 5
576
-
577
- for attempt in range(1, max_retries + 1):
578
- try:
579
- logger.info(f"🚀 Attempting to start bot (attempt {attempt}/{max_retries})...")
580
- await bot.start(TOKEN, reconnect=True)
581
- break
582
- except Exception as e:
583
- logger.error(f"❌ Attempt {attempt} failed: {e}")
584
- if attempt < max_retries:
585
- wait_time = retry_delay * (2 ** (attempt - 1))
586
- logger.info(f"⏳ Retrying in {wait_time} seconds...")
587
- await asyncio.sleep(wait_time)
588
- else:
589
- logger.error("💥 Max retries reached. Bot failed to start.")
590
- raise
591
-
592
- # Run the bot with retry logic
593
  if __name__ == "__main__":
594
  try:
595
- asyncio.run(run_bot_with_retry())
596
  except Exception as e:
597
  logger.error(f"Failed to start bot: {e}")
598
  raise
 
1
  import discord
2
  from discord.ext import commands, tasks
 
3
  import os
4
  import asyncio
5
  from datetime import datetime
6
  import logging
7
  from flask import Flask
8
  from threading import Thread
 
9
 
10
  # Setup logging
11
  logging.basicConfig(
 
35
 
36
  # Bot intents
37
  intents = discord.Intents.default()
38
+ intents.message_content = True # Required for reading message content
39
  intents.members = True
40
  intents.presences = True
41
 
42
+ # Create bot instance
43
  bot = commands.Bot(
44
+ command_prefix='!',
45
  intents=intents,
46
+ help_command=None, # Custom help command
47
  case_insensitive=True
48
  )
49
 
 
53
  logger.info(f'✅ Bot logged in as {bot.user.name} ({bot.user.id})')
54
  logger.info(f'🌐 Connected to {len(bot.guilds)} guilds')
55
 
 
 
 
 
 
 
 
56
  # Set bot status
57
  await bot.change_presence(
58
  activity=discord.Activity(
59
  type=discord.ActivityType.watching,
60
+ name=f"{len(bot.guilds)} servers | !help"
61
  ),
62
  status=discord.Status.online
63
  )
 
71
  await bot.change_presence(
72
  activity=discord.Activity(
73
  type=discord.ActivityType.watching,
74
+ name=f"{len(bot.guilds)} servers | !help"
75
  ),
76
  status=discord.Status.online
77
  )
 
86
  async def on_guild_remove(guild):
87
  logger.info(f'➖ Left guild: {guild.name} ({guild.id})')
88
 
89
+ # Event: Handle messages (for non-command messages)
90
+ @bot.event
91
+ async def on_message(message):
92
+ # Ignore bot messages
93
+ if message.author.bot:
94
+ return
95
+
96
+ # Process commands
97
+ await bot.process_commands(message)
98
+
99
+ # ==================== COMMANDS ====================
100
+
101
+ # Help Command
102
+ @bot.command(name='help', aliases=['h', 'commands'])
103
+ async def help_command(ctx, command_name: str = None):
 
 
 
 
 
 
 
104
  """Show help information"""
105
  if command_name:
106
+ # Show specific command help
107
+ command = bot.get_command(command_name)
108
+ if command:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  embed = discord.Embed(
110
+ title=f"📖 Help: !{command.name}",
111
+ description=command.help or "No description available",
112
  color=discord.Color.blue()
113
  )
114
+ embed.add_field(
115
+ name="Usage",
116
+ value=f"`!{command.name} {command.signature}`" if command.signature else f"`!{command.name}`",
117
+ inline=False
118
+ )
119
+ if command.aliases:
120
+ embed.add_field(
121
+ name="Aliases",
122
+ value=", ".join([f"`!{alias}`" for alias in command.aliases]),
123
+ inline=False
124
+ )
125
+ await ctx.send(embed=embed)
126
  else:
127
+ await ctx.send(f"❌ Command `!{command_name}` not found!")
128
  else:
129
+ # Show all commands
130
  embed = discord.Embed(
131
  title="🤖 Bot Commands",
132
+ description="Here are all available commands:",
133
  color=discord.Color.blue(),
134
  timestamp=datetime.now()
135
  )
136
 
137
+ # Categorize commands
138
  categories = {
139
+ "General": ['help', 'ping', 'info', 'serverinfo', 'userinfo'],
140
+ "Fun": ['say', 'embed', 'poll', '8ball', 'coinflip'],
141
+ "Utility": ['avatar', 'invite', 'uptime', 'clear']
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
  }
143
 
144
  for category, cmds in categories.items():
145
+ valid_cmds = []
146
+ for cmd_name in cmds:
147
+ cmd = bot.get_command(cmd_name)
148
+ if cmd:
149
+ valid_cmds.append(f"`!{cmd.name}`")
150
+ if valid_cmds:
151
+ embed.add_field(
152
+ name=f"📁 {category}",
153
+ value=" | ".join(valid_cmds),
154
+ inline=False
155
+ )
156
 
157
+ embed.set_footer(text=f"Use !help <command> for more details | Prefix: !")
158
+ await ctx.send(embed=embed)
159
 
160
  # Ping Command
161
+ @bot.command(name='ping', aliases=['latency'])
162
+ async def ping_command(ctx):
163
  """Check bot latency"""
164
  latency = round(bot.latency * 1000)
165
 
 
 
166
  embed = discord.Embed(
167
  title="🏓 Pong!",
168
  description=f"**Latency:** `{latency}ms`\n**API Latency:** `{round(bot.latency * 1000)}ms`",
169
+ color=discord.Color.green() if latency < 200 else discord.Color.orange() if latency < 500 else discord.Color.red()
170
  )
171
+ embed.set_footer(text=f"Requested by {ctx.author.name}")
172
+ await ctx.send(embed=embed)
173
 
174
  # Info Command
175
+ @bot.command(name='info', aliases=['botinfo', 'about'])
176
+ async def info_command(ctx):
177
  """Show bot information"""
178
  embed = discord.Embed(
179
  title="🤖 Bot Information",
 
194
  embed.set_thumbnail(url=bot.user.avatar.url if bot.user.avatar else bot.user.default_avatar.url)
195
  embed.set_footer(text="Made with ❤️ using discord.py")
196
 
197
+ await ctx.send(embed=embed)
198
 
199
  # Server Info Command
200
+ @bot.command(name='serverinfo', aliases=['server', 'guildinfo'])
201
+ async def serverinfo_command(ctx):
202
  """Show server information"""
203
+ guild = ctx.guild
204
 
205
  embed = discord.Embed(
206
  title=f"📊 {guild.name} Server Info",
 
219
  if guild.icon:
220
  embed.set_thumbnail(url=guild.icon.url)
221
 
222
+ await ctx.send(embed=embed)
223
 
224
  # User Info Command
225
+ @bot.command(name='userinfo', aliases=['whois', 'profile'])
226
+ async def userinfo_command(ctx, member: discord.Member = None):
 
227
  """Show user information"""
228
+ member = member or ctx.author
229
 
230
  embed = discord.Embed(
231
  title=f"👤 {member.name}'s Profile",
 
242
  embed.add_field(name="Top Role", value=member.top_role.mention, inline=True)
243
  embed.add_field(name="Bot?", value="Yes" if member.bot else "No", inline=True)
244
 
245
+ roles = [role.mention for role in member.roles if role != ctx.guild.default_role]
246
  if roles:
247
  embed.add_field(name=f"Roles ({len(roles)})", value=" ".join(roles[:10]) + ("..." if len(roles) > 10 else ""), inline=False)
248
 
249
  embed.set_thumbnail(url=member.avatar.url if member.avatar else member.default_avatar.url)
250
+ embed.set_footer(text=f"Requested by {ctx.author.name}")
251
 
252
+ await ctx.send(embed=embed)
253
 
254
  # Avatar Command
255
+ @bot.command(name='avatar', aliases=['av', 'pfp'])
256
+ async def avatar_command(ctx, member: discord.Member = None):
 
257
  """Show user's avatar"""
258
+ member = member or ctx.author
259
 
260
  embed = discord.Embed(
261
  title=f"🖼️ {member.name}'s Avatar",
 
264
 
265
  avatar_url = member.avatar.url if member.avatar else member.default_avatar.url
266
  embed.set_image(url=avatar_url)
267
+ 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)
268
 
269
+ await ctx.send(embed=embed)
270
 
271
  # Say Command
272
+ @bot.command(name='say', aliases=['echo'])
273
+ async def say_command(ctx, *, message: str):
 
274
  """Make the bot say something"""
275
+ await ctx.message.delete()
276
+ await ctx.send(message)
277
 
278
  # Embed Command
279
+ @bot.command(name='embed', aliases=['em'])
280
+ async def embed_command(ctx, *, message: str):
 
281
  """Create a custom embed"""
282
  embed = discord.Embed(
283
  description=message,
284
  color=discord.Color.blue(),
285
  timestamp=datetime.now()
286
  )
287
+ embed.set_author(name=ctx.author.name, icon_url=ctx.author.avatar.url if ctx.author.avatar else ctx.author.default_avatar.url)
288
+ await ctx.send(embed=embed)
289
 
290
  # Poll Command
291
+ @bot.command(name='poll', aliases=['vote'])
292
+ async def poll_command(ctx, *, question: str):
 
293
  """Create a poll"""
294
  embed = discord.Embed(
295
  title="📊 Poll",
 
297
  color=discord.Color.blue(),
298
  timestamp=datetime.now()
299
  )
300
+ embed.set_footer(text=f"Poll by {ctx.author.name}")
301
 
302
+ poll_message = await ctx.send(embed=embed)
 
303
  await poll_message.add_reaction("👍")
304
  await poll_message.add_reaction("👎")
305
  await poll_message.add_reaction("🤷")
306
 
307
  # 8Ball Command
308
+ @bot.command(name='8ball', aliases=['magic8ball', 'ask'])
309
+ async def eightball_command(ctx, *, question: str):
 
310
  """Ask the magic 8-ball"""
311
+ import random
312
+
313
  responses = [
314
  "🎱 It is certain.",
315
  "🎱 It is decidedly so.",
 
340
  embed.add_field(name="Question", value=question, inline=False)
341
  embed.add_field(name="Answer", value=random.choice(responses), inline=False)
342
 
343
+ await ctx.send(embed=embed)
344
 
345
  # Coin Flip Command
346
+ @bot.command(name='coinflip', aliases=['flip', 'coin'])
347
+ async def coinflip_command(ctx):
348
  """Flip a coin"""
349
+ import random
350
+
351
  result = random.choice(["Heads", "Tails"])
352
+ emoji = "🪙" if result == "Heads" else "🪙"
353
 
354
  embed = discord.Embed(
355
+ title=f"{emoji} Coin Flip",
356
  description=f"**Result:** {result}",
357
  color=discord.Color.gold()
358
  )
359
 
360
+ await ctx.send(embed=embed)
361
 
362
  # Invite Command
363
+ @bot.command(name='invite', aliases=['addbot'])
364
+ async def invite_command(ctx):
365
  """Get bot invite link"""
366
  permissions = discord.Permissions(
367
  send_messages=True,
 
385
  )
386
  embed.add_field(name="Bot ID", value=bot.user.id, inline=False)
387
 
388
+ await ctx.send(embed=embed)
389
 
390
  # Clear Command
391
+ @bot.command(name='clear', aliases=['purge', 'clean'])
392
+ @commands.has_permissions(manage_messages=True)
393
+ async def clear_command(ctx, amount: int = 5):
 
394
  """Clear messages (requires Manage Messages permission)"""
395
  if amount < 1 or amount > 100:
396
+ await ctx.send("❌ Please specify a number between 1 and 100!")
397
  return
398
 
399
+ deleted = await ctx.channel.purge(limit=amount + 1)
 
400
  embed = discord.Embed(
401
+ description=f"🗑️ Deleted {len(deleted) - 1} messages!",
402
  color=discord.Color.green()
403
  )
404
+ msg = await ctx.send(embed=embed)
405
  await asyncio.sleep(3)
406
+ await msg.delete()
 
 
 
407
 
408
  # Uptime Command
409
+ @bot.command(name='uptime', aliases=['up'])
410
+ async def uptime_command(ctx):
411
  """Show bot uptime"""
412
  embed = discord.Embed(
413
  title="⏱️ Bot Uptime",
414
  description=get_uptime(),
415
  color=discord.Color.blue()
416
  )
417
+ await ctx.send(embed=embed)
418
 
419
+ # Error Handler
420
+ @bot.event
421
+ async def on_command_error(ctx, error):
422
+ if isinstance(error, commands.CommandNotFound):
423
+ return # Ignore unknown commands
424
+
425
+ elif isinstance(error, commands.MissingRequiredArgument):
426
+ embed = discord.Embed(
427
+ title="❌ Missing Argument",
428
+ description=f"Missing required argument: `{error.param.name}`\nUse `!help {ctx.command.name}` for usage info.",
429
+ color=discord.Color.red()
430
+ )
431
+ await ctx.send(embed=embed)
432
+
433
+ elif isinstance(error, commands.MissingPermissions):
434
  embed = discord.Embed(
435
  title="❌ Missing Permissions",
436
  description=f"You need `{', '.join(error.missing_permissions)}` permission to use this command.",
437
  color=discord.Color.red()
438
  )
439
+ await ctx.send(embed=embed)
 
 
 
440
 
441
+ elif isinstance(error, commands.MemberNotFound):
442
  embed = discord.Embed(
443
+ title="❌ User Not Found",
444
+ description="The specified user was not found.",
445
  color=discord.Color.red()
446
  )
447
+ await ctx.send(embed=embed)
 
 
 
448
 
449
  else:
450
+ logger.error(f"Command error: {error}")
451
  embed = discord.Embed(
452
  title="❌ Error",
453
  description="An unexpected error occurred. Please try again later.",
454
  color=discord.Color.red()
455
  )
456
+ await ctx.send(embed=embed)
 
 
 
457
 
458
  # Helper function: Get uptime
459
  start_time = datetime.now()
 
475
 
476
  return " ".join(parts)
477
 
478
+ # Run the bot
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
479
  if __name__ == "__main__":
480
  try:
481
+ bot.run(TOKEN)
482
  except Exception as e:
483
  logger.error(f"Failed to start bot: {e}")
484
  raise