wpms commited on
Commit
e423c06
·
verified ·
1 Parent(s): 9330668

Update main.py

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