Rifat Azad commited on
Commit
e03e842
·
1 Parent(s): 3ec0c8c

1.4.0 update now all embeds

Browse files
Files changed (2) hide show
  1. feedback/issues/issues.json +26 -0
  2. pydvpl_bot.py +557 -221
feedback/issues/issues.json ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "author_id": 289085424348168194,
4
+ "author_name": "rifsxd",
5
+ "timestamp": "2024-04-06 00:42:03.796000+00:00",
6
+ "message": "test"
7
+ },
8
+ {
9
+ "author_id": 289085424348168194,
10
+ "author_name": "rifsxd",
11
+ "timestamp": "2024-04-06 00:43:53.579000+00:00",
12
+ "message": "test"
13
+ },
14
+ {
15
+ "author_id": 289085424348168194,
16
+ "author_name": "rifsxd",
17
+ "timestamp": "2024-04-06 00:44:45.699000+00:00",
18
+ "message": "test"
19
+ },
20
+ {
21
+ "author_id": 289085424348168194,
22
+ "author_name": "rifsxd",
23
+ "timestamp": "2024-04-06 00:45:50.606000+00:00",
24
+ "message": "test"
25
+ }
26
+ ]
pydvpl_bot.py CHANGED
@@ -35,7 +35,7 @@ load_dotenv()
35
  # DEFINES ------------------------------------------------------ START
36
 
37
 
38
- BOT_VERSION = '1.3.4'
39
 
40
  AUTHORIZED_USER_ID = os.getenv('AUTHORIZED_ID')
41
 
@@ -45,6 +45,10 @@ LOG_CHANNEL_ID = os.getenv('CHANNEL_ID')
45
 
46
  AUTHORIZED_AI_ACCESS_ID = os.getenv('AUTHORIZED_AI_ID')
47
 
 
 
 
 
48
  UPDATE_INTERVAL = 60
49
 
50
  activity_start_time = 0
@@ -312,23 +316,21 @@ bot.remove_command("help")
312
 
313
  @bot.hybrid_command(help="Displays the list of available commands.")
314
  async def help(ctx):
315
- embed = discord.Embed(title="Command List", description="Here's a list of available commands:", color=discord.Color.yellow())
 
316
 
317
- # Add commands to the embed with descriptions
318
  embed.add_field(name="PyDVPL Prefix:", value="`/` - Discord's slash command prefix.\n`>>` - PyDVPL default prefix.")
319
  embed.add_field(name="Dvpl Commands:", value="`compress` - Compresses files.\n`decompress` - Decompresses files.", inline=False)
320
- embed.add_field(name="User Utility Commands:", value="`ping` - Checks the bot's latency.\n`invite` - Get the bot's invite link.\n`uptime` - Displays the bot's uptime.\n`clock` - Shows the current date and time.\n`chat` - Chat with ai llm models like 'phind', 'chatgpt' & 'blackboxai'.", inline=False)
321
- embed.add_field(name="Premium User Commands:", value="`chat` - Chat with ai llm models like 'phind', 'chatgpt' & 'blackboxai'.\n`image` - Generate images with 'craiyon' ai.", inline=False)
322
  embed.add_field(name="Moderator Commands:", value="`kick` - Kick a member from the server.\n`ban` - Ban a member from the server.\n`timeout` - Timeout a member for a specified duration.\n`purge` - Bulk deletes set amount of messages in guilds.", inline=False)
323
- embed.add_field(name="Admin Utility Commands:", value="`stats` - Displays bot statistics.\n`list` - Lists server members.\n`say` - Make the bot say something.\n`announce` - Announces a message to a channel.\n`activity` - Sets bot activity status.\n`online` - Sets bot status to online.\n`dnd` - Sets bot status to Do Not Disturb.\n`offline` - Sets bot status to offline.\n`clean` - Cleans up bot's messages.\n`update` - Update a Python package using pip.\n`ip` - Shows the ip address of the current server.", inline=False)
324
  embed.add_field(name="Feedback Commands:", value="`feedback` - Sends feedback to bot developers. (usage: >>feedback issues/requests <message>)", inline=False)
325
 
326
- # Customize based on your commands
327
-
328
- # Set the footer
329
- # embed.set_footer(value="Use /help or >>help <command> for more details on a specific command.")
330
-
331
- # Send the embed as an ephemeral message
332
  await ctx.reply(embed=embed, ephemeral=True)
333
 
334
  #await ctx.reply(f"The command `help` was executed by - {ctx.author.mention}")
@@ -343,8 +345,6 @@ async def compress(ctx , attachments: discord.Attachment):
343
 
344
  if not attachments:
345
  await ctx.reply("No file attached.")
346
- #await ctx.reply(f"The command `compress` was executed by - {ctx.author.mention}")
347
-
348
  return
349
 
350
  for attachment in attachments:
@@ -354,26 +354,39 @@ async def compress(ctx , attachments: discord.Attachment):
354
 
355
  # Check if the file is already in .dvpl format, if so, skip it
356
  if file_path.endswith(".dvpl"):
357
- await ctx.reply(f"File {attachment.filename} is already in .dvpl format. Skipping.")
358
-
 
 
 
 
 
 
359
  continue
360
 
361
  await attachment.save(file_path)
362
  compressed_file_path = await compress_file(file_path)
363
  if compressed_file_path:
364
- await msg.edit(content=f"File {attachment.filename} has succesfully compressed.")
 
 
 
 
 
 
 
365
  await ctx.reply(file=discord.File(compressed_file_path))
366
  os.remove(file_path) # Delete the original file
367
  os.remove(compressed_file_path) # Delete the compressed file
368
  else:
369
- await ctx.reply("Failed to `compress` the file.")
370
-
371
- #await ctx.reply(f"The command `compress` was executed by - {ctx.author.mention}")
372
-
373
-
374
-
375
- # FUNCTION ------------------------------------------------------ SPLIT
376
-
377
 
378
  @bot.hybrid_command(help="Decompresses attached files.")
379
  async def decompress(ctx, attachments: discord.Attachment):
@@ -381,8 +394,6 @@ async def decompress(ctx, attachments: discord.Attachment):
381
 
382
  if not attachments:
383
  await ctx.reply("No file attached.")
384
- #await ctx.reply(f"The command `decompress` was executed by - {ctx.author.mention}")
385
-
386
  return
387
 
388
  for attachment in attachments:
@@ -392,18 +403,39 @@ async def decompress(ctx, attachments: discord.Attachment):
392
 
393
  # Check if the file is not in .dvpl format, if so, skip it
394
  if not file_path.endswith(".dvpl"):
395
- await ctx.reply(f"File {attachment.filename} is not in .dvpl format. Skipping.")
 
 
 
 
 
 
 
396
  continue
397
 
398
  await attachment.save(file_path)
399
  decompressed_file_path = await decompress_file(file_path)
400
  if decompressed_file_path:
401
- await msg.edit(content=f"File {attachment.filename} has succesfully decompressed.")
 
 
 
 
 
 
 
402
  await ctx.reply(file=discord.File(decompressed_file_path))
403
  os.remove(file_path) # Delete the original file
404
  os.remove(decompressed_file_path) # Delete the decompressed file
405
  else:
406
- await ctx.reply("Failed to decompress the file.")
 
 
 
 
 
 
 
407
 
408
  #await ctx.reply(f"The command `decompress` was executed by - {ctx.author.mention}")
409
 
@@ -414,15 +446,26 @@ async def decompress(ctx, attachments: discord.Attachment):
414
 
415
  @bot.hybrid_command(help="Pings to check bot's latency")
416
  async def ping(ctx):
 
417
  msg = await ctx.reply("Pinging...")
418
 
419
- # Calculate client latency
420
- client_latency = (msg.created_at - ctx.message.created_at).total_seconds() * 1000
 
 
 
 
421
 
422
- # Calculate shared latency
423
- shared_latency = round(bot.latency * 1000)
 
 
 
 
 
 
424
 
425
- await msg.edit(content=f"🏓 Pong! Client latency is `{client_latency:.2f}ms` - Shared latency is `{shared_latency}ms`.")
426
 
427
  #await ctx.reply(f"The command `ping` was executed by - {ctx.author.mention}")
428
 
@@ -430,7 +473,7 @@ async def ping(ctx):
430
  # FUNCTION ------------------------------------------------------ SPLIT
431
 
432
 
433
- @bot.command()
434
  async def pinger(ctx, target):
435
  try:
436
  # Attempt to resolve the target to an IP address
@@ -451,15 +494,44 @@ async def pinger(ctx, target):
451
  # Calculate the round trip time (RTT)
452
  rtt = (time.time() - start_time) * 1000 # Convert to milliseconds
453
 
454
- # Send a message indicating success with latency
455
- await ctx.send(f'Ping to {target} successful! 🟢 Latency: {rtt:.2f}ms')
456
-
457
  # Close the socket
458
  s.close()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
459
  except socket.gaierror:
460
- await ctx.send(f'Error: Unable to resolve {target} to an IP address. 🔴')
 
 
 
 
 
 
 
 
461
  except socket.error:
462
- await ctx.send(f'Error: {target} is unreachable. 🔴')
 
 
 
 
 
 
 
 
463
 
464
 
465
 
@@ -489,12 +561,51 @@ async def invite(ctx):
489
  client_id = bot.user.id
490
  invite_link = discord.utils.oauth_url(client_id, permissions=permissions, scopes=['bot'])
491
 
492
- # Send the invite link to the user's DM
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
493
  try:
494
- await ctx.author.send(f"Invite link for PyDVPL: {invite_link}")
495
- await ctx.reply(f"Sent the invite link to your DM. {ctx.author.mention}")
 
 
 
 
 
 
 
 
 
 
 
496
  except discord.Forbidden:
497
- await ctx.reply(f"Failed to send the invite link to your DM. {ctx.author.mention} Please make sure your DMs are open.")
 
 
 
 
 
 
 
498
 
499
  #await ctx.reply(f"The command `invite` was executed by - {ctx.author.mention}")
500
 
@@ -503,7 +614,6 @@ async def invite(ctx):
503
  # FUNCTION ------------------------------------------------------ SPLIT
504
 
505
 
506
- # Command: Feedback
507
  @bot.hybrid_command(help="Send feedback or report issues", usage="<requests/issues> <message>")
508
  async def feedback(ctx, category: str, *, message: str):
509
  if category.lower() not in ["requests", "issues"]:
@@ -534,19 +644,27 @@ async def feedback(ctx, category: str, *, message: str):
534
  await ctx.reply(f"Thank you for your {category.lower()}. It has been recorded.")
535
 
536
  # Create an Embed object for the feedback data
537
- embed = discord.Embed(title=f"New {category.lower()} feedback", color=discord.Color.yellow())
538
- embed.add_field(name="Author ID", value=feedback_data["author_id"], inline=False)
539
- embed.add_field(name="Author Name", value=feedback_data["author_name"], inline=False)
540
- embed.add_field(name="Timestamp", value=feedback_data["timestamp"], inline=False)
541
- embed.add_field(name="Message", value=feedback_data["message"], inline=False)
542
-
543
- # Send the embed to the specified channel
544
- feedback_channel_id = 1225913942564540616
545
- feedback_channel = ctx.guild.get_channel(feedback_channel_id)
546
- if feedback_channel:
547
- await feedback_channel.send(embed=embed)
 
 
 
 
 
 
 
 
548
  else:
549
- print("Feedback channel not found.")
550
 
551
 
552
  #await ctx.reply(f"The command `feedback` was executed by - {ctx.author.mention}")
@@ -562,8 +680,7 @@ async def uptime(ctx):
562
 
563
  if activity_start_time == 0:
564
  bot_mention = ctx.me.mention
565
- await ctx.reply("{bot_mention}'s activity hasn't been set yet.")
566
-
567
  return
568
 
569
  current_time = time.time()
@@ -572,9 +689,21 @@ async def uptime(ctx):
572
  hours, minutes = divmod(minutes, 60)
573
 
574
  bot_mention = ctx.me.mention
575
- uptime_message = f"{bot_mention} has been playing for - {hours} hours, {minutes} minutes, {seconds} seconds."
576
- await ctx.reply(uptime_message)
577
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
578
  #await ctx.reply(f"The command `uptime` was executed by - {ctx.author.mention}")
579
 
580
 
@@ -595,6 +724,9 @@ async def version(ctx):
595
  embed.add_field(name="Discord PY Version:", value=f"``{discord.__version__}``", inline=False)
596
  embed.add_field(name="PyTGPT Lib Version:", value=f"``{pytgpt.__version__}``", inline=False)
597
  embed.add_field(name="Craiyon Lib Version:", value=f"``{craiyon.__version__}``", inline=False)
 
 
 
598
 
599
  # Send the embed message
600
  await ctx.reply(embed=embed)
@@ -612,7 +744,18 @@ async def clock(ctx):
612
  # Format the date and time
613
  formatted_now = now.strftime("%Y-%m-%d %H:%M:%S")
614
 
615
- await ctx.reply(f"Current date and time: `{formatted_now}`")
 
 
 
 
 
 
 
 
 
 
 
616
 
617
  #await ctx.reply(f"The command `clock` was executed by - {ctx.author.mention}")
618
 
@@ -643,10 +786,28 @@ async def chat(ctx, model, *, message):
643
  half_length = len(response) // 2
644
  first_half = response[:half_length]
645
  second_half = response[half_length:]
646
- await msg.edit(content=f"{first_half}-")
647
- await ctx.send(f"-{second_half}")
 
 
 
 
 
 
 
 
 
648
  else:
649
- await msg.edit(content=response)
 
 
 
 
 
 
 
 
 
650
 
651
 
652
  #await ctx.reply(f"The command `chat` was executed by - {ctx.author.mention}")
@@ -679,9 +840,19 @@ async def image(ctx, *, prompt: str):
679
  image_file = discord.File(img_bytes, filename=f"result{index}.webp")
680
  images.append(image_file)
681
 
682
- await msg.edit(content=f"Sucessfully generated {prompt} images.")
683
- # Send images to the user
684
- await ctx.reply(files=images)
 
 
 
 
 
 
 
 
 
 
685
 
686
  except Exception as e:
687
  # Print the specific exception message for debugging
@@ -703,19 +874,33 @@ async def clean(ctx, clean_mode):
703
  # Check if the author is authorized to use this command
704
  if str(ctx.author.id) != AUTHORIZED_USER_ID:
705
  await ctx.reply("You are not authorized to use this command.")
706
-
707
  return
708
 
 
 
709
  if clean_mode.lower() == 'compress':
710
  await clean_directory(ctx, COMPRESS_FOLDER)
 
711
  elif clean_mode.lower() == 'decompress':
712
  await clean_directory(ctx, DECOMPRESS_FOLDER)
 
713
  elif clean_mode.lower() == 'issues':
714
  await clean_directory(ctx, ISSUES_FOLDER)
 
715
  elif clean_mode.lower() == 'requests':
716
  await clean_directory(ctx, REQUESTS_FOLDER)
 
717
  else:
718
- await ctx.reply("Invalid clean mode. Please choose 'received_to_compress', 'received_to_decompress', 'feedback_issues', or 'feedback_requests'.")
 
 
 
 
 
 
 
 
 
719
 
720
 
721
  # FUNCTION ------------------------------------------------------ SPLIT
@@ -726,10 +911,23 @@ async def online(ctx):
726
  # Check if the author is authorized to use this command
727
  if str(ctx.author.id) != AUTHORIZED_USER_ID:
728
  await ctx.reply("You are not authorized to use this command.")
729
-
730
  return
 
 
 
 
 
731
  await bot.change_presence(activity=discord.Game(name=playing_time_activity))
732
- await ctx.reply("Bot's presence set to online.")
 
 
 
 
 
 
 
 
 
733
 
734
 
735
 
@@ -741,10 +939,20 @@ async def dnd(ctx):
741
  # Check if the author is authorized to use this command
742
  if str(ctx.author.id) != AUTHORIZED_USER_ID:
743
  await ctx.reply("You are not authorized to use this command.")
744
-
745
  return
 
 
746
  await bot.change_presence(status=discord.Status.dnd)
747
- await ctx.reply("Bot's presence set to Do Not Disturb.")
 
 
 
 
 
 
 
 
 
748
 
749
 
750
 
@@ -756,10 +964,20 @@ async def offline(ctx):
756
  # Check if the author is authorized to use this command
757
  if str(ctx.author.id) != AUTHORIZED_USER_ID:
758
  await ctx.reply("You are not authorized to use this command.")
759
-
760
  return
 
 
761
  await bot.change_presence(status=discord.Status.offline)
762
- await ctx.reply("Bot's presence set to offline.")
 
 
 
 
 
 
 
 
 
763
 
764
 
765
 
@@ -771,27 +989,47 @@ async def activity(ctx, activity_type, *, activity_text=None):
771
  # Check if the author is authorized to use this command
772
  if str(ctx.author.id) != AUTHORIZED_USER_ID:
773
  await ctx.reply("You are not authorized to use this command.")
774
-
775
  return
776
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
777
  if activity_type.lower() == 'listening':
778
  activity = discord.Activity(type=discord.ActivityType.listening, name=activity_text)
779
  elif activity_type.lower() == 'watching':
780
  activity = discord.Activity(type=discord.ActivityType.watching, name=activity_text)
781
  elif activity_type.lower() == 'playing':
782
  activity = discord.Activity(type=discord.ActivityType.playing, name=activity_text)
783
- else:
784
- await ctx.reply('Invalid activity type. Please choose either "listening", "playing" or "watching".')
785
-
786
- return
787
-
788
- if not activity_text:
789
- await ctx.reply('Please provide an activity text.')
790
-
791
- return
792
 
 
793
  await bot.change_presence(activity=activity)
794
- await ctx.reply(f'Activity set to {activity_type} {activity_text}')
 
 
 
 
 
 
 
 
 
795
 
796
 
797
 
@@ -805,69 +1043,75 @@ async def say(ctx, destination_type, *, id, message):
805
  await ctx.reply("You are not authorized to use this command.")
806
  return
807
 
 
 
 
 
 
 
 
 
 
808
  if destination_type.lower() == 'channel':
809
  try:
810
  channel_id = int(id)
 
 
 
 
 
 
811
  except ValueError:
812
- await ctx.reply("Channel ID must be a valid integer.")
813
- return
814
- channel = bot.get_channel(channel_id)
815
- if channel:
816
- await channel.send(message)
817
- await ctx.reply(f"Message `{message}` sent to channel `{channel.name}`.")
818
- else:
819
- await ctx.reply("Channel not found.")
820
-
821
  elif destination_type.lower() == 'server':
822
  try:
823
  server_id = int(id)
824
- except ValueError:
825
- await ctx.reply("Server ID must be a valid integer.")
826
- return
827
- server = bot.get_guild(server_id)
828
- if server:
829
- announcement_channel = discord.utils.get(server.channels, name="important-announcements")
830
- if announcement_channel:
831
- await announcement_channel.send(message)
832
- await ctx.reply(f"Message `{message}` sent to server `{server.name}` in `important-announcements` channel.")
833
- else:
834
- announcements_channel = discord.utils.get(server.channels, name="announcements")
835
- if announcements_channel:
836
- await announcements_channel.send(message)
837
- await ctx.reply(f"Message `{message}` sent to server `{server.name}` in `announcements` channel.")
838
  else:
839
- public_updates_channel = server.public_updates_channel
840
- if public_updates_channel:
841
- await public_updates_channel.send(message)
842
- await ctx.reply(f"Message `{message}` sent to server `{server.name}` in `public updates` channel.")
843
  else:
844
- default_channel = server.system_channel or server.text_channels[0] # Default to the first text channel
845
- if default_channel:
846
- await default_channel.send(message)
847
- await ctx.reply(f"Message `{message}` sent to server `{server.name}` in the default channel.")
848
  else:
849
- await ctx.reply("No announcement channels found in the server. Also, no default `public updates` neither `default` channels found.")
850
- else:
851
- await ctx.reply("Server not found.")
852
-
 
 
 
 
 
 
 
853
  elif destination_type.lower() == 'user':
854
  try:
855
  user_id = int(id)
 
 
 
 
 
 
 
 
 
856
  except ValueError:
857
- await ctx.reply("User ID must be a valid integer.")
858
- return
859
- user = bot.get_user(user_id)
860
- if user:
861
- try:
862
- await user.send(message)
863
- await ctx.reply(f"Message `{message}` sent to user '{user.display_name}'.")
864
- except discord.Forbidden:
865
- await ctx.reply(f"Couldn't send message to `{user.display_name}`. Their DMs are closed.")
866
- else:
867
- await ctx.reply("User not found.")
868
-
869
  else:
870
- await ctx.reply("Invalid destination type. Use either 'channel', 'server', or 'user'.")
871
 
872
 
873
 
@@ -879,32 +1123,42 @@ async def announce(ctx, *, message):
879
  # Check if the author is authorized to use this command
880
  if str(ctx.author.id) != AUTHORIZED_USER_ID:
881
  await ctx.reply("You are not authorized to use this command.")
882
-
883
  return
884
 
 
885
  embed = discord.Embed(title="Announcement!", description=message, color=discord.Color.yellow())
886
 
 
 
887
  for server in bot.guilds:
888
  # First, check for an "important-announcements" channel
889
  announcement_channel = discord.utils.get(server.channels, name="important-announcements")
890
  if announcement_channel:
 
 
891
  await announcement_channel.send(embed=embed)
892
  await ctx.reply(f"Message `{message}` sent to server `{server.name}` in `important-announcements` channel.")
893
  else:
894
  # If no "important-announcements" channel, check for "announcements" channel
895
  announcements_channel = discord.utils.get(server.channels, name="announcements")
896
  if announcements_channel:
 
 
897
  await announcements_channel.send(embed=embed)
898
  await ctx.reply(f"Message `{message}` sent to server `{server.name}` in `announcements` channel.")
899
  else:
900
  # If neither channel exists, send to the default channel or public updates channel
901
  public_updates_channel = server.public_updates_channel
902
  if public_updates_channel:
 
 
903
  await public_updates_channel.send(embed=embed)
904
  await ctx.reply(f"Message `{message}` sent to server `{server.name}` in `public updates` channel.")
905
  else:
906
  default_channel = server.system_channel or server.text_channels[0]
907
- if default_channel:
 
 
908
  await default_channel.send(embed=embed)
909
  await ctx.reply(f"Message `{message}` sent to server `{server.name}` in `defaults` channel.")
910
  else:
@@ -922,11 +1176,12 @@ async def stats(ctx):
922
  # Check if the author is authorized to use this command
923
  if str(ctx.author.id) != AUTHORIZED_USER_ID:
924
  await ctx.reply("You are not authorized to use this command.")
925
-
926
  return
927
 
928
- msg = await ctx.reply("Monitoring...")
 
929
 
 
930
  guild_count = len(bot.guilds)
931
  member_count = len(set(bot.get_all_members()))
932
 
@@ -943,17 +1198,20 @@ async def stats(ctx):
943
  # Get memory usage
944
  memory_usage = psutil.virtual_memory().percent
945
 
946
- bot_mention = ctx.me.mention
947
- stats_message = (
948
- f"**{bot_mention}'s Statistics & Vitals -**\n\n"
949
- f"Servers: `{guild_count}`\n"
950
- f"Members: `{member_count}`\n"
951
- f"Uptime: `{uptime_days} days`, `{uptime_hours} hours`, `{uptime_minutes} minutes`, `{uptime_seconds} seconds`\n"
952
- f"Latency: `{latency}ms`\n"
953
- f"CPU Usage: `{cpu_usage}%`\n"
954
- f"Memory Usage: `{memory_usage}%`"
955
- )
956
- await msg.edit(content=stats_message)
 
 
 
957
 
958
 
959
  # FUNCTION ------------------------------------------------------ SPLIT
@@ -964,17 +1222,35 @@ async def list(ctx, list_type):
964
  # Check if the author is authorized to use this command
965
  if str(ctx.author.id) != AUTHORIZED_USER_ID:
966
  await ctx.reply("You are not authorized to use this command.")
967
-
968
  return
969
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
970
  if list_type.lower() == 'servers':
971
  servers_info = "\n".join([f"{server.name} - ID: {server.id}" for server in bot.guilds])
972
- await ctx.reply(f"List of servers the bot is on:\n```{servers_info}```")
 
 
 
973
 
974
  elif list_type.lower() == 'issues':
975
  await list_feedback(ctx, ISSUES_FOLDER, "List of issues:")
 
976
  elif list_type.lower() == 'requests':
977
  await list_feedback(ctx, REQUESTS_FOLDER, "List of requests:")
 
978
  else:
979
  await ctx.reply("Invalid list type. Please choose 'servers', 'issues', or 'requests'.")
980
 
@@ -990,37 +1266,66 @@ async def update(ctx, pkg_name):
990
  return
991
 
992
  try:
993
-
994
- msg = await ctx.reply("Updating package `{pkg_name}`...")
995
 
996
  # Run pip install command to upgrade the package
997
  process = subprocess.Popen(['pip', 'install', pkg_name, '--upgrade'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
998
  output, error = process.communicate()
999
 
 
1000
  if error:
1001
- await msg.edit(content=f"Failed to update package `{pkg_name}`. Error: {error.decode('utf-8')}")
 
 
 
 
1002
  else:
1003
- await msg.edit(content=f"Package `{pkg_name}` successfully updated.")
 
 
 
 
1004
  except Exception as e:
1005
- await msg.edit(content=f"An error occurred while updating package `{pkg_name}`: {e}")
 
 
1006
 
1007
 
1008
  # FUNCTION ------------------------------------------------------ SPLIT
1009
 
1010
 
1011
- @bot.hybrid_command(help="Shows the ip address of the current server.")
1012
  async def ip(ctx):
1013
  # Check if the author is authorized to use this command
1014
  if str(ctx.author.id) != AUTHORIZED_USER_ID:
1015
  await ctx.reply("You are not authorized to use this command.")
1016
-
1017
  return
1018
 
1019
- response = requests.get('https://api.ipify.org')
1020
- if response.status_code == 200:
1021
- await ctx.reply(f'Your IP address is: `{response.text}`')
1022
- else:
1023
- await ctx.reply('Failed to fetch IP address.')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1024
 
1025
 
1026
  # UTILITY ADMIN_CMD ------------------------------------------------------ END
@@ -1034,26 +1339,32 @@ async def ip(ctx):
1034
 
1035
  @bot.hybrid_command(help="Kick a member from the server.")
1036
  async def kick(ctx, member: discord.Member, *, reason=None):
 
1037
  if ctx.author.guild_permissions.kick_members or ctx.author == ctx.guild.owner:
1038
-
1039
  if ctx.author.top_role.position > member.top_role.position:
1040
-
1041
- # Attempt to send a DM to the kicked member
1042
  try:
 
1043
  dm_message = f"You have been kicked from the server `{ctx.guild.name}`"
1044
  if reason:
1045
  dm_message += f" for the following reason: `{reason}`"
1046
  await member.send(dm_message)
1047
  except discord.Forbidden:
 
1048
  await ctx.reply(f"Failed to send a direct message to {member}.")
1049
 
1050
  # Kick the member from the server
1051
  await member.kick(reason=reason)
1052
- await ctx.reply(f"{member} has been kicked from the server.")
 
 
 
 
1053
  else:
 
1054
  await ctx.reply("You do not have permission to kick this member.")
1055
-
1056
  else:
 
1057
  await ctx.reply("You do not have permission to use this command.")
1058
 
1059
 
@@ -1062,67 +1373,72 @@ async def kick(ctx, member: discord.Member, *, reason=None):
1062
 
1063
  @bot.hybrid_command(help="Ban a member from the server.")
1064
  async def ban(ctx, member: discord.Member, *, reason=None):
 
1065
  if ctx.author.guild_permissions.ban_members or ctx.author == ctx.guild.owner:
1066
-
1067
  if ctx.author.top_role.position > member.top_role.position:
1068
-
1069
- # Attempt to send a DM to the banned member
1070
  try:
 
1071
  dm_message = f"You have been banned from the server `{ctx.guild.name}`"
1072
  if reason:
1073
  dm_message += f" for the following reason: `{reason}`"
1074
  await member.send(dm_message)
1075
  except discord.Forbidden:
 
1076
  await ctx.reply(f"Failed to send a direct message to {member}.")
1077
 
1078
  # Ban the member from the server
1079
  await member.ban(reason=reason)
1080
- await ctx.reply(f"{member} has been banned from the server.")
 
 
 
 
1081
  else:
 
1082
  await ctx.reply("You do not have permission to ban this member.")
1083
-
1084
  else:
 
1085
  await ctx.reply("You do not have permission to use this command.")
1086
 
1087
 
1088
 
1089
-
1090
  # FUNCTION ------------------------------------------------------ SPLIT
1091
 
1092
 
1093
 
1094
  @bot.hybrid_command(help="Timeout a member for a specified duration.")
1095
  async def timeout(ctx, member: discord.Member, duration: int, *, reason=None):
1096
-
1097
- # Check if the author is owner of the guild to use this command
1098
  if ctx.author.guild_permissions.manage_roles or ctx.author == ctx.guild.owner:
1099
-
1100
  if ctx.author.top_role.position > member.top_role.position:
1101
-
1102
  try:
1103
- # Duration in seconds
1104
  timeout_duration = duration
1105
 
1106
  # Timeout the member by removing all roles
1107
  await member.edit(roles=[], reason=reason)
1108
-
1109
- await ctx.reply(f"`{member}` has been timed out for `{duration} seconds`. Reason: `{reason}`")
1110
 
1111
- # Construct the message to be sent as a DM
1112
- dm_message_init = f"You have been timed out in the server `{ctx.guild.name}` for `{duration} seconds`"
1113
- if reason:
1114
- dm_message_init += f" for the following reason: `{reason}`"
 
1115
 
1116
  # Send a DM to the timed-out member
1117
- try:
1118
- await member.send(dm_message_init)
1119
- except discord.Forbidden:
1120
- # If unable to send DM, log the error and continue
1121
- await ctx.reply(f"Failed to send DM to `{member}` for timeout.")
1122
 
1123
  except Exception as e:
1124
- await ctx.reply(f"An error occurred: {e}")
1125
- return # Stop execution if there's an error
 
 
 
 
1126
 
1127
  # Wait for the duration of the timeout
1128
  await asyncio.sleep(timeout_duration)
@@ -1131,23 +1447,27 @@ async def timeout(ctx, member: discord.Member, duration: int, *, reason=None):
1131
  try:
1132
  await member.edit(roles=member.roles, reason=reason)
1133
  except Exception as e:
 
1134
  print(f"An error occurred while restoring roles to `{member}`: {e}")
1135
- return # Stop execution if there's an error
1136
 
1137
- dm_message_exit = f"Your previous timeout in the server `{ctx.guild.name}` for `{duration} seconds`"
 
1138
  if reason:
1139
- dm_message_exit += f" for the following reason: `{reason}` has been expired!"
1140
-
1141
  try:
1142
- await member.send(dm_message_exit)
1143
  except discord.Forbidden:
1144
- # If unable to send DM, log the error and continue
1145
- await ctx.reply(f"Failed to send DM to `{member}` to notify timeout expiration.")
1146
-
 
 
1147
  else:
 
1148
  await ctx.reply("You do not have permission to timeout this member.")
1149
-
1150
  else:
 
1151
  await ctx.reply("You do not have permission to use this command.")
1152
 
1153
 
@@ -1156,37 +1476,53 @@ async def timeout(ctx, member: discord.Member, duration: int, *, reason=None):
1156
 
1157
  @bot.hybrid_command(help="Bulk deletes set amount of messages in guilds.")
1158
  async def purge(ctx, amount: int):
1159
-
1160
  if isinstance(ctx.channel, discord.DMChannel):
1161
- msg = await ctx.reply(f"Purging `{amount}` messages...")
1162
- await msg.edit(content="Purging is not supported in direct messages.")
1163
- return
 
1164
 
1165
- # Check if the author is owner of the guild to use this command
1166
  if ctx.author.guild_permissions.manage_roles or ctx.author == ctx.guild.owner:
1167
-
1168
  try:
1169
-
1170
  msg = await ctx.reply(f"Purging `{amount}` messages...")
1171
 
1172
  try:
1173
  # Use the before parameter to only purge messages before the command is invoked
1174
  await ctx.channel.purge(limit=amount, before=ctx.message)
1175
- await msg.edit(content=f"`{amount}` messages purged successfully.")
 
 
 
 
1176
  except discord.Forbidden:
1177
- await msg.edit(content="I don't have permission to delete messages in this channel.")
 
 
 
 
1178
  except discord.HTTPException:
1179
- await msg.edit(content="Failed to purge messages due to an error.")
1180
-
 
 
 
1181
 
1182
  except Exception as e:
1183
- await ctx.reply(f"An error occurred: {e}")
1184
- return # Stop execution if there's an error
1185
-
1186
-
 
 
1187
  else:
1188
- await ctx.reply("You do not have permission to use this command.")
1189
-
 
 
 
1190
 
1191
  # UTILITY MODERATOR_CMD ------------------------------------------------------ END
1192
 
 
35
  # DEFINES ------------------------------------------------------ START
36
 
37
 
38
+ BOT_VERSION = '1.4.0'
39
 
40
  AUTHORIZED_USER_ID = os.getenv('AUTHORIZED_ID')
41
 
 
45
 
46
  AUTHORIZED_AI_ACCESS_ID = os.getenv('AUTHORIZED_AI_ID')
47
 
48
+ MY_SERVER_ID = os.getenv('MY_SERVER_ID')
49
+
50
+ FEEDBACK_CHANNEL_ID = os.getenv('FEEDBACK_CHANNEL_ID')
51
+
52
  UPDATE_INTERVAL = 60
53
 
54
  activity_start_time = 0
 
316
 
317
  @bot.hybrid_command(help="Displays the list of available commands.")
318
  async def help(ctx):
319
+ # Create an embed to display the list of available commands
320
+ embed = discord.Embed(title="Command List", description="Here's a list of available commands:", color=discord.Color.blue())
321
 
322
+ # Add fields for different categories of commands with their descriptions
323
  embed.add_field(name="PyDVPL Prefix:", value="`/` - Discord's slash command prefix.\n`>>` - PyDVPL default prefix.")
324
  embed.add_field(name="Dvpl Commands:", value="`compress` - Compresses files.\n`decompress` - Decompresses files.", inline=False)
325
+ embed.add_field(name="User Utility Commands:", value="`ping` - Checks the bot's latency.\n`invite` - Get the bot's invite link.\n`uptime` - Displays the bot's uptime.\n`clock` - Shows the current date and time.\n`chat` - Chat with AI LLM models like 'phind', 'chatgpt' & 'blackboxai'.", inline=False)
326
+ embed.add_field(name="Premium User Commands:", value="`chat` - Chat with AI LLM models like 'phind', 'chatgpt' & 'blackboxai'.\n`image` - Generate images with 'craiyon' AI.", inline=False)
327
  embed.add_field(name="Moderator Commands:", value="`kick` - Kick a member from the server.\n`ban` - Ban a member from the server.\n`timeout` - Timeout a member for a specified duration.\n`purge` - Bulk deletes set amount of messages in guilds.", inline=False)
328
+ embed.add_field(name="Admin Utility Commands:", value="`stats` - Displays bot statistics.\n`list` - Lists server members.\n`say` - Make the bot say something.\n`announce` - Announces a message to a channel.\n`activity` - Sets bot activity status.\n`online` - Sets bot status to online.\n`dnd` - Sets bot status to Do Not Disturb.\n`offline` - Sets bot status to offline.\n`clean` - Cleans up bot's messages.\n`update` - Update a Python package using pip.\n`ip` - Shows the IP address of the current server.", inline=False)
329
  embed.add_field(name="Feedback Commands:", value="`feedback` - Sends feedback to bot developers. (usage: >>feedback issues/requests <message>)", inline=False)
330
 
331
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
332
+ embed.timestamp = ctx.message.created_at
333
+ # Send the embed as an ephemeral message, visible only to the command invoker
 
 
 
334
  await ctx.reply(embed=embed, ephemeral=True)
335
 
336
  #await ctx.reply(f"The command `help` was executed by - {ctx.author.mention}")
 
345
 
346
  if not attachments:
347
  await ctx.reply("No file attached.")
 
 
348
  return
349
 
350
  for attachment in attachments:
 
354
 
355
  # Check if the file is already in .dvpl format, if so, skip it
356
  if file_path.endswith(".dvpl"):
357
+ embed = discord.Embed(
358
+ title="Compression Skipped",
359
+ description=f"File {attachment.filename} is already in .dvpl format.",
360
+ color=discord.Color.gold()
361
+ )
362
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
363
+ embed.timestamp = ctx.message.created_at
364
+ await msg.edit(content=None, embed=embed)
365
  continue
366
 
367
  await attachment.save(file_path)
368
  compressed_file_path = await compress_file(file_path)
369
  if compressed_file_path:
370
+ embed = discord.Embed(
371
+ title="Compression Successful",
372
+ description=f"File {attachment.filename} has been successfully compressed.",
373
+ color=discord.Color.green()
374
+ )
375
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
376
+ embed.timestamp = ctx.message.created_at
377
+ await msg.edit(content=None, embed=embed)
378
  await ctx.reply(file=discord.File(compressed_file_path))
379
  os.remove(file_path) # Delete the original file
380
  os.remove(compressed_file_path) # Delete the compressed file
381
  else:
382
+ embed = discord.Embed(
383
+ title="Compression Failed",
384
+ description="Failed to compress the file.",
385
+ color=discord.Color.red()
386
+ )
387
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
388
+ embed.timestamp = ctx.message.created_at
389
+ await msg.edit(content=None, embed=embed)
390
 
391
  @bot.hybrid_command(help="Decompresses attached files.")
392
  async def decompress(ctx, attachments: discord.Attachment):
 
394
 
395
  if not attachments:
396
  await ctx.reply("No file attached.")
 
 
397
  return
398
 
399
  for attachment in attachments:
 
403
 
404
  # Check if the file is not in .dvpl format, if so, skip it
405
  if not file_path.endswith(".dvpl"):
406
+ embed = discord.Embed(
407
+ title="Decompression Skipped",
408
+ description=f"File {attachment.filename} is not in .dvpl format.",
409
+ color=discord.Color.gold()
410
+ )
411
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
412
+ embed.timestamp = ctx.message.created_at
413
+ await msg.edit(content=None, embed=embed)
414
  continue
415
 
416
  await attachment.save(file_path)
417
  decompressed_file_path = await decompress_file(file_path)
418
  if decompressed_file_path:
419
+ embed = discord.Embed(
420
+ title="Decompression Successful",
421
+ description=f"File {attachment.filename} has been successfully decompressed.",
422
+ color=discord.Color.green()
423
+ )
424
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
425
+ embed.timestamp = ctx.message.created_at
426
+ await msg.edit(content=None, embed=embed)
427
  await ctx.reply(file=discord.File(decompressed_file_path))
428
  os.remove(file_path) # Delete the original file
429
  os.remove(decompressed_file_path) # Delete the decompressed file
430
  else:
431
+ embed = discord.Embed(
432
+ title="Decompression Failed",
433
+ description="Failed to decompress the file.",
434
+ color=discord.Color.red()
435
+ )
436
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
437
+ embed.timestamp = ctx.message.created_at
438
+ await msg.edit(content=None, embed=embed)
439
 
440
  #await ctx.reply(f"The command `decompress` was executed by - {ctx.author.mention}")
441
 
 
446
 
447
  @bot.hybrid_command(help="Pings to check bot's latency")
448
  async def ping(ctx):
449
+ start_time = time.monotonic()
450
  msg = await ctx.reply("Pinging...")
451
 
452
+ # Measure WebSocket latency
453
+ ws_latency = bot.latency * 1000
454
+
455
+ # Calculate elapsed time since sending the message
456
+ end_time = time.monotonic()
457
+ elapsed_time = (end_time - start_time) * 1000
458
 
459
+ # Create an embedded message
460
+ embed = discord.Embed(
461
+ title="Pong! 🏓",
462
+ description=f"WebSocket latency: `{ws_latency:.2f}ms`\nResponse time: `{elapsed_time:.2f}ms`",
463
+ color=discord.Color.blurple()
464
+ )
465
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
466
+ embed.timestamp = ctx.message.created_at
467
 
468
+ await msg.edit(content=None, embed=embed)
469
 
470
  #await ctx.reply(f"The command `ping` was executed by - {ctx.author.mention}")
471
 
 
473
  # FUNCTION ------------------------------------------------------ SPLIT
474
 
475
 
476
+ @bot.hybrid_command()
477
  async def pinger(ctx, target):
478
  try:
479
  # Attempt to resolve the target to an IP address
 
494
  # Calculate the round trip time (RTT)
495
  rtt = (time.time() - start_time) * 1000 # Convert to milliseconds
496
 
 
 
 
497
  # Close the socket
498
  s.close()
499
+
500
+ # Create an embedded message
501
+ embed = discord.Embed(
502
+ title="Ping Result",
503
+ color=discord.Color.green()
504
+ )
505
+ embed.add_field(name="Target", value=target, inline=False)
506
+ embed.add_field(name="Status", value="Successful 🟢", inline=False)
507
+ embed.add_field(name="Latency", value=f"{rtt:.2f}ms", inline=False)
508
+
509
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
510
+ embed.timestamp = ctx.message.created_at
511
+
512
+ # Send the embedded message
513
+ await ctx.send(embed=embed)
514
+
515
  except socket.gaierror:
516
+ # Create an embedded message for resolution error
517
+ embed = discord.Embed(
518
+ title="Ping Result",
519
+ description=f"Error: Unable to resolve {target} to an IP address. 🔴",
520
+ color=discord.Color.red()
521
+ )
522
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
523
+ embed.timestamp = ctx.message.created_at
524
+ await ctx.send(embed=embed)
525
  except socket.error:
526
+ # Create an embedded message for unreachable error
527
+ embed = discord.Embed(
528
+ title="Ping Result",
529
+ description=f"Error: {target} is unreachable. 🔴",
530
+ color=discord.Color.red()
531
+ )
532
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
533
+ embed.timestamp = ctx.message.created_at
534
+ await ctx.send(embed=embed)
535
 
536
 
537
 
 
561
  client_id = bot.user.id
562
  invite_link = discord.utils.oauth_url(client_id, permissions=permissions, scopes=['bot'])
563
 
564
+ # Create an embedded message for the invite link
565
+ invite_embed = discord.Embed(
566
+ title="Invite Link",
567
+ description=f"Click the button below to invite PyDVPL to your server",
568
+ color=discord.Color.blue()
569
+ )
570
+
571
+ invite_embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
572
+ invite_embed.timestamp = ctx.message.created_at
573
+
574
+ # Create a button for the invite link
575
+ invite_button = discord.ui.Button(
576
+ style=discord.ButtonStyle.link,
577
+ label="Invite PyDVPL",
578
+ url=invite_link
579
+ )
580
+
581
+ # Create a View to hold the button
582
+ view = discord.ui.View()
583
+ view.add_item(invite_button)
584
+
585
+ # Send the embed with the button to the user's DM
586
  try:
587
+ await ctx.author.send(
588
+ embed=invite_embed,
589
+ view=view
590
+ )
591
+
592
+ invite_confirmation_embed = discord.Embed(
593
+ title="Invite Link Sent",
594
+ description=f"The invite link has been sent to your DM, {ctx.author.mention}.",
595
+ color=discord.Color.green()
596
+ )
597
+ invite_confirmation_embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
598
+ invite_confirmation_embed.timestamp = ctx.message.created_at
599
+ await ctx.reply(embed=invite_confirmation_embed)
600
  except discord.Forbidden:
601
+ invite_error_embed = discord.Embed(
602
+ title="Invite Link Sending Failed",
603
+ description=f"Failed to send the invite link to your DM, {ctx.author.mention}. Please make sure your DMs are open.",
604
+ color=discord.Color.red()
605
+ )
606
+ invite_error_embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
607
+ invite_error_embed.timestamp = ctx.message.created_at
608
+ await ctx.reply(embed=invite_error_embed)
609
 
610
  #await ctx.reply(f"The command `invite` was executed by - {ctx.author.mention}")
611
 
 
614
  # FUNCTION ------------------------------------------------------ SPLIT
615
 
616
 
 
617
  @bot.hybrid_command(help="Send feedback or report issues", usage="<requests/issues> <message>")
618
  async def feedback(ctx, category: str, *, message: str):
619
  if category.lower() not in ["requests", "issues"]:
 
644
  await ctx.reply(f"Thank you for your {category.lower()}. It has been recorded.")
645
 
646
  # Create an Embed object for the feedback data
647
+ embed = discord.Embed(
648
+ title=f"New {category.lower()} feedback",
649
+ description=f"**Author Name:** {feedback_data['author_name']}\n**Timestamp:** {feedback_data['timestamp']}\n**Message:** {feedback_data['message']}",
650
+ color=discord.Color.yellow()
651
+ )
652
+
653
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
654
+ embed.timestamp = ctx.message.created_at
655
+
656
+ # Send the embed to the specified server's feedback channel
657
+ server_id = MY_SERVER_ID # Replace with your server ID
658
+ feedback_channel_id = FEEDBACK_CHANNEL_ID # Replace with your feedback channel ID
659
+ server = bot.get_guild(server_id)
660
+ if server:
661
+ feedback_channel = server.get_channel(feedback_channel_id)
662
+ if feedback_channel:
663
+ await feedback_channel.send(embed=embed)
664
+ else:
665
+ print("Feedback channel not found in the server.")
666
  else:
667
+ print("Server not found.")
668
 
669
 
670
  #await ctx.reply(f"The command `feedback` was executed by - {ctx.author.mention}")
 
680
 
681
  if activity_start_time == 0:
682
  bot_mention = ctx.me.mention
683
+ await ctx.reply(f"{bot_mention}'s activity hasn't been set yet.")
 
684
  return
685
 
686
  current_time = time.time()
 
689
  hours, minutes = divmod(minutes, 60)
690
 
691
  bot_mention = ctx.me.mention
 
 
692
 
693
+ # Create an embedded message for the uptime
694
+ embed = discord.Embed(
695
+ title="Bot Uptime",
696
+ description=f"{bot_mention} has been playing for:",
697
+ color=discord.Color.blue()
698
+ )
699
+ embed.add_field(name="Hours", value=hours)
700
+ embed.add_field(name="Minutes", value=minutes)
701
+ embed.add_field(name="Seconds", value=seconds)
702
+
703
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
704
+ embed.timestamp = ctx.message.created_at
705
+
706
+ await ctx.reply(embed=embed)
707
  #await ctx.reply(f"The command `uptime` was executed by - {ctx.author.mention}")
708
 
709
 
 
724
  embed.add_field(name="Discord PY Version:", value=f"``{discord.__version__}``", inline=False)
725
  embed.add_field(name="PyTGPT Lib Version:", value=f"``{pytgpt.__version__}``", inline=False)
726
  embed.add_field(name="Craiyon Lib Version:", value=f"``{craiyon.__version__}``", inline=False)
727
+
728
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
729
+ embed.timestamp = ctx.message.created_at
730
 
731
  # Send the embed message
732
  await ctx.reply(embed=embed)
 
744
  # Format the date and time
745
  formatted_now = now.strftime("%Y-%m-%d %H:%M:%S")
746
 
747
+ # Create an embed message to display the current date and time
748
+ embed = discord.Embed(
749
+ title="Current Date and Time",
750
+ description=f"```\n{formatted_now}\n```",
751
+ color=discord.Color.blue()
752
+ )
753
+
754
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
755
+ embed.timestamp = ctx.message.created_at
756
+
757
+ # Send the embed message
758
+ await ctx.reply(embed=embed)
759
 
760
  #await ctx.reply(f"The command `clock` was executed by - {ctx.author.mention}")
761
 
 
786
  half_length = len(response) // 2
787
  first_half = response[:half_length]
788
  second_half = response[half_length:]
789
+ embed = discord.Embed(
790
+ title="Response",
791
+ color=discord.Color.green()
792
+ )
793
+ embed.add_field(name="First Half", value=f"{first_half}-")
794
+ embed.add_field(name="Second Half", value=f"-{second_half}")
795
+
796
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
797
+ embed.timestamp = ctx.message.created_at
798
+
799
+ await msg.edit(content=None, embed=embed)
800
  else:
801
+ embed = discord.Embed(
802
+ title="Response",
803
+ description=response,
804
+ color=discord.Color.green()
805
+ )
806
+
807
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
808
+ embed.timestamp = ctx.message.created_at
809
+
810
+ await msg.edit(content=None, embed=embed)
811
 
812
 
813
  #await ctx.reply(f"The command `chat` was executed by - {ctx.author.mention}")
 
840
  image_file = discord.File(img_bytes, filename=f"result{index}.webp")
841
  images.append(image_file)
842
 
843
+ embed = discord.Embed(
844
+ title="Generated Images",
845
+ description=f"Sucessfully generated images for prompt: `{prompt}`.",
846
+ color=discord.Color.green()
847
+ )
848
+ # Add a field for each generated image
849
+ for index, image in enumerate(images):
850
+ embed.add_field(name=f"Image {index+1}", value=f"[Click here to view]({image.url})")
851
+
852
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
853
+ embed.timestamp = ctx.message.created_at
854
+
855
+ await msg.edit(content=None, embed=embed)
856
 
857
  except Exception as e:
858
  # Print the specific exception message for debugging
 
874
  # Check if the author is authorized to use this command
875
  if str(ctx.author.id) != AUTHORIZED_USER_ID:
876
  await ctx.reply("You are not authorized to use this command.")
 
877
  return
878
 
879
+ embed = discord.Embed(title="File Cleaning Command", color=0x00ff00) # Green color for the embed
880
+
881
  if clean_mode.lower() == 'compress':
882
  await clean_directory(ctx, COMPRESS_FOLDER)
883
+ embed.add_field(name="Action", value="Compress Folder Cleaning", inline=False)
884
  elif clean_mode.lower() == 'decompress':
885
  await clean_directory(ctx, DECOMPRESS_FOLDER)
886
+ embed.add_field(name="Action", value="Decompress Folder Cleaning", inline=False)
887
  elif clean_mode.lower() == 'issues':
888
  await clean_directory(ctx, ISSUES_FOLDER)
889
+ embed.add_field(name="Action", value="Issues Folder Cleaning", inline=False)
890
  elif clean_mode.lower() == 'requests':
891
  await clean_directory(ctx, REQUESTS_FOLDER)
892
+ embed.add_field(name="Action", value="Requests Folder Cleaning", inline=False)
893
  else:
894
+ embed.add_field(name="Error", value="Invalid clean mode. Please choose 'compress', 'decompress', 'issues', or 'requests'.", inline=False)
895
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
896
+ embed.timestamp = ctx.message.created_at
897
+ await ctx.reply(embed=embed)
898
+ return
899
+
900
+ embed.add_field(name="Status", value="Cleaning completed successfully.", inline=False)
901
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
902
+ embed.timestamp = ctx.message.created_at
903
+ await ctx.reply(embed=embed)
904
 
905
 
906
  # FUNCTION ------------------------------------------------------ SPLIT
 
911
  # Check if the author is authorized to use this command
912
  if str(ctx.author.id) != AUTHORIZED_USER_ID:
913
  await ctx.reply("You are not authorized to use this command.")
 
914
  return
915
+
916
+ # Your playing_time_activity variable should be defined somewhere
917
+ playing_time_activity = "Your default activity here"
918
+
919
+ # Change the bot's presence
920
  await bot.change_presence(activity=discord.Game(name=playing_time_activity))
921
+
922
+ # Prepare an embed for response
923
+ embed = discord.Embed(title="Bot Presence Update", color=0x00ff00) # Green color for the embed
924
+ embed.add_field(name="Status", value="Bot's presence set to online with activity: " + playing_time_activity, inline=False)
925
+
926
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
927
+ embed.timestamp = ctx.message.created_at
928
+
929
+ # Send the embed as a reply
930
+ await ctx.reply(embed=embed)
931
 
932
 
933
 
 
939
  # Check if the author is authorized to use this command
940
  if str(ctx.author.id) != AUTHORIZED_USER_ID:
941
  await ctx.reply("You are not authorized to use this command.")
 
942
  return
943
+
944
+ # Change the bot's presence to Do Not Disturb
945
  await bot.change_presence(status=discord.Status.dnd)
946
+
947
+ # Prepare an embed for response
948
+ embed = discord.Embed(title="Bot Presence Update", color=0xff0000) # Red color for the embed
949
+ embed.add_field(name="Status", value="Bot's presence set to Do Not Disturb", inline=False)
950
+
951
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
952
+ embed.timestamp = ctx.message.created_at
953
+
954
+ # Send the embed as a reply
955
+ await ctx.reply(embed=embed)
956
 
957
 
958
 
 
964
  # Check if the author is authorized to use this command
965
  if str(ctx.author.id) != AUTHORIZED_USER_ID:
966
  await ctx.reply("You are not authorized to use this command.")
 
967
  return
968
+
969
+ # Change the bot's presence to offline
970
  await bot.change_presence(status=discord.Status.offline)
971
+
972
+ # Prepare an embed for response
973
+ embed = discord.Embed(title="Bot Presence Update", color=0x000000) # Black color for the embed
974
+ embed.add_field(name="Status", value="Bot's presence set to offline", inline=False)
975
+
976
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
977
+ embed.timestamp = ctx.message.created_at
978
+
979
+ # Send the embed as a reply
980
+ await ctx.reply(embed=embed)
981
 
982
 
983
 
 
989
  # Check if the author is authorized to use this command
990
  if str(ctx.author.id) != AUTHORIZED_USER_ID:
991
  await ctx.reply("You are not authorized to use this command.")
 
992
  return
993
 
994
+ # Check if a valid activity type is provided
995
+ valid_activity_types = ['listening', 'watching', 'playing']
996
+ if activity_type.lower() not in valid_activity_types:
997
+ embed = discord.Embed(title="Invalid Activity Type", color=0xff0000) # Red color for the embed
998
+ embed.add_field(name="Error", value='Invalid activity type. Please choose either "listening", "playing" or "watching".', inline=False)
999
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1000
+ embed.timestamp = ctx.message.created_at
1001
+ await ctx.reply(embed=embed)
1002
+ return
1003
+
1004
+ # Check if activity text is provided
1005
+ if not activity_text:
1006
+ embed = discord.Embed(title="Activity Text Missing", color=0xff0000) # Red color for the embed
1007
+ embed.add_field(name="Error", value='Please provide an activity text.', inline=False)
1008
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1009
+ embed.timestamp = ctx.message.created_at
1010
+ await ctx.reply(embed=embed)
1011
+ return
1012
+
1013
+ # Determine the activity based on the provided type
1014
  if activity_type.lower() == 'listening':
1015
  activity = discord.Activity(type=discord.ActivityType.listening, name=activity_text)
1016
  elif activity_type.lower() == 'watching':
1017
  activity = discord.Activity(type=discord.ActivityType.watching, name=activity_text)
1018
  elif activity_type.lower() == 'playing':
1019
  activity = discord.Activity(type=discord.ActivityType.playing, name=activity_text)
 
 
 
 
 
 
 
 
 
1020
 
1021
+ # Change the bot's presence
1022
  await bot.change_presence(activity=activity)
1023
+
1024
+ # Prepare an embed for response
1025
+ embed = discord.Embed(title="Bot Activity Update", color=0x00ff00) # Green color for the embed
1026
+ embed.add_field(name="Status", value=f'Activity set to {activity_type.capitalize()} {activity_text}', inline=False)
1027
+
1028
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1029
+ embed.timestamp = ctx.message.created_at
1030
+
1031
+ # Send the embed as a reply
1032
+ await ctx.reply(embed=embed)
1033
 
1034
 
1035
 
 
1043
  await ctx.reply("You are not authorized to use this command.")
1044
  return
1045
 
1046
+ # Define function to send reply and return
1047
+ async def send_reply(reply):
1048
+ embed = discord.Embed(title="Message Sent", color=0x00ff00) # Green color for the embed
1049
+ embed.add_field(name="Status", value=reply, inline=False)
1050
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1051
+ embed.timestamp = ctx.message.created_at
1052
+ await ctx.reply(embed=embed)
1053
+
1054
+ # Check destination type and send message accordingly
1055
  if destination_type.lower() == 'channel':
1056
  try:
1057
  channel_id = int(id)
1058
+ channel = bot.get_channel(channel_id)
1059
+ if channel:
1060
+ await channel.send(message)
1061
+ await send_reply(f"Message `{message}` sent to channel `{channel.name}`.")
1062
+ else:
1063
+ await send_reply("Channel not found.")
1064
  except ValueError:
1065
+ await send_reply("Channel ID must be a valid integer.")
1066
+
 
 
 
 
 
 
 
1067
  elif destination_type.lower() == 'server':
1068
  try:
1069
  server_id = int(id)
1070
+ server = bot.get_guild(server_id)
1071
+ if server:
1072
+ announcement_channel = discord.utils.get(server.channels, name="important-announcements")
1073
+ if announcement_channel:
1074
+ await announcement_channel.send(message)
1075
+ await send_reply(f"Message `{message}` sent to server `{server.name}` in `important-announcements` channel.")
 
 
 
 
 
 
 
 
1076
  else:
1077
+ announcements_channel = discord.utils.get(server.channels, name="announcements")
1078
+ if announcements_channel:
1079
+ await announcements_channel.send(message)
1080
+ await send_reply(f"Message `{message}` sent to server `{server.name}` in `announcements` channel.")
1081
  else:
1082
+ public_updates_channel = server.public_updates_channel
1083
+ if public_updates_channel:
1084
+ await public_updates_channel.send(message)
1085
+ await send_reply(f"Message `{message}` sent to server `{server.name}` in `public updates` channel.")
1086
  else:
1087
+ default_channel = server.system_channel or server.text_channels[0] # Default to the first text channel
1088
+ if default_channel:
1089
+ await default_channel.send(message)
1090
+ await send_reply(f"Message `{message}` sent to server `{server.name}` in the default channel.")
1091
+ else:
1092
+ await send_reply("No announcement channels found in the server. Also, no default `public updates` neither `default` channels found.")
1093
+ else:
1094
+ await send_reply("Server not found.")
1095
+ except ValueError:
1096
+ await send_reply("Server ID must be a valid integer.")
1097
+
1098
  elif destination_type.lower() == 'user':
1099
  try:
1100
  user_id = int(id)
1101
+ user = bot.get_user(user_id)
1102
+ if user:
1103
+ try:
1104
+ await user.send(message)
1105
+ await send_reply(f"Message `{message}` sent to user '{user.display_name}'.")
1106
+ except discord.Forbidden:
1107
+ await send_reply(f"Couldn't send message to `{user.display_name}`. Their DMs are closed.")
1108
+ else:
1109
+ await send_reply("User not found.")
1110
  except ValueError:
1111
+ await send_reply("User ID must be a valid integer.")
1112
+
 
 
 
 
 
 
 
 
 
 
1113
  else:
1114
+ await send_reply("Invalid destination type. Use either 'channel', 'server', or 'user'.")
1115
 
1116
 
1117
 
 
1123
  # Check if the author is authorized to use this command
1124
  if str(ctx.author.id) != AUTHORIZED_USER_ID:
1125
  await ctx.reply("You are not authorized to use this command.")
 
1126
  return
1127
 
1128
+ # Prepare an embed for the announcement message
1129
  embed = discord.Embed(title="Announcement!", description=message, color=discord.Color.yellow())
1130
 
1131
+
1132
+ # Iterate through all servers the bot is in and send the announcement
1133
  for server in bot.guilds:
1134
  # First, check for an "important-announcements" channel
1135
  announcement_channel = discord.utils.get(server.channels, name="important-announcements")
1136
  if announcement_channel:
1137
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1138
+ embed.timestamp = ctx.message.created_at
1139
  await announcement_channel.send(embed=embed)
1140
  await ctx.reply(f"Message `{message}` sent to server `{server.name}` in `important-announcements` channel.")
1141
  else:
1142
  # If no "important-announcements" channel, check for "announcements" channel
1143
  announcements_channel = discord.utils.get(server.channels, name="announcements")
1144
  if announcements_channel:
1145
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1146
+ embed.timestamp = ctx.message.created_at
1147
  await announcements_channel.send(embed=embed)
1148
  await ctx.reply(f"Message `{message}` sent to server `{server.name}` in `announcements` channel.")
1149
  else:
1150
  # If neither channel exists, send to the default channel or public updates channel
1151
  public_updates_channel = server.public_updates_channel
1152
  if public_updates_channel:
1153
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1154
+ embed.timestamp = ctx.message.created_at
1155
  await public_updates_channel.send(embed=embed)
1156
  await ctx.reply(f"Message `{message}` sent to server `{server.name}` in `public updates` channel.")
1157
  else:
1158
  default_channel = server.system_channel or server.text_channels[0]
1159
+ if default_channel:
1160
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1161
+ embed.timestamp = ctx.message.created_at
1162
  await default_channel.send(embed=embed)
1163
  await ctx.reply(f"Message `{message}` sent to server `{server.name}` in `defaults` channel.")
1164
  else:
 
1176
  # Check if the author is authorized to use this command
1177
  if str(ctx.author.id) != AUTHORIZED_USER_ID:
1178
  await ctx.reply("You are not authorized to use this command.")
 
1179
  return
1180
 
1181
+ # Send a message to indicate that statistics are being fetched
1182
+ msg = await ctx.reply("Fetching statistics...")
1183
 
1184
+ # Get bot's statistics
1185
  guild_count = len(bot.guilds)
1186
  member_count = len(set(bot.get_all_members()))
1187
 
 
1198
  # Get memory usage
1199
  memory_usage = psutil.virtual_memory().percent
1200
 
1201
+ # Prepare an embed for the statistics
1202
+ embed = discord.Embed(title="Bot Statistics & Vitals", color=discord.Color.blue())
1203
+ embed.add_field(name="Servers", value=f"`{guild_count}`", inline=True)
1204
+ embed.add_field(name="Members", value=f"`{member_count}`", inline=True)
1205
+ embed.add_field(name="Uptime", value=f"`{uptime_days} days`, `{uptime_hours} hours`, `{uptime_minutes} minutes`, `{uptime_seconds} seconds`", inline=False)
1206
+ embed.add_field(name="Latency", value=f"`{latency}ms`", inline=True)
1207
+ embed.add_field(name="CPU Usage", value=f"`{cpu_usage}%`", inline=True)
1208
+ embed.add_field(name="Memory Usage", value=f"`{memory_usage}%`", inline=True)
1209
+
1210
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1211
+ embed.timestamp = ctx.message.created_at
1212
+
1213
+ # Edit the initial message with the statistics embed
1214
+ await msg.edit(content=None, embed=embed)
1215
 
1216
 
1217
  # FUNCTION ------------------------------------------------------ SPLIT
 
1222
  # Check if the author is authorized to use this command
1223
  if str(ctx.author.id) != AUTHORIZED_USER_ID:
1224
  await ctx.reply("You are not authorized to use this command.")
 
1225
  return
1226
+
1227
+ # Function to list issues or requests
1228
+ async def list_feedback(ctx, folder, title):
1229
+ files = os.listdir(folder)
1230
+ if not files:
1231
+ await ctx.reply("No items found.")
1232
+ return
1233
+
1234
+ feedback_list = "\n".join(files)
1235
+ embed = discord.Embed(title=title, description=f"```{feedback_list}```", color=discord.Color.blue())
1236
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1237
+ embed.timestamp = ctx.message.created_at
1238
+ await ctx.reply(embed=embed)
1239
+
1240
+ # Execute based on the provided list type
1241
  if list_type.lower() == 'servers':
1242
  servers_info = "\n".join([f"{server.name} - ID: {server.id}" for server in bot.guilds])
1243
+ embed = discord.Embed(title="Servers List", description=f"```{servers_info}```", color=discord.Color.green())
1244
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1245
+ embed.timestamp = ctx.message.created_at
1246
+ await ctx.reply(embed=embed)
1247
 
1248
  elif list_type.lower() == 'issues':
1249
  await list_feedback(ctx, ISSUES_FOLDER, "List of issues:")
1250
+
1251
  elif list_type.lower() == 'requests':
1252
  await list_feedback(ctx, REQUESTS_FOLDER, "List of requests:")
1253
+
1254
  else:
1255
  await ctx.reply("Invalid list type. Please choose 'servers', 'issues', or 'requests'.")
1256
 
 
1266
  return
1267
 
1268
  try:
1269
+ # Send a message to indicate that the package update process has started
1270
+ msg = await ctx.reply(f"Updating package `{pkg_name}`...")
1271
 
1272
  # Run pip install command to upgrade the package
1273
  process = subprocess.Popen(['pip', 'install', pkg_name, '--upgrade'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
1274
  output, error = process.communicate()
1275
 
1276
+ # Check if any errors occurred during the update process
1277
  if error:
1278
+ # If there was an error, update the message with the error information
1279
+ embed = discord.Embed(title="Package Update Failed", description=f"Failed to update package `{pkg_name}`.\nError: {error.decode('utf-8')}", color=discord.Color.red())
1280
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1281
+ embed.timestamp = ctx.message.created_at
1282
+ await msg.edit(embed=embed)
1283
  else:
1284
+ # If the update was successful, update the message to indicate success
1285
+ embed = discord.Embed(title="Package Update Successful", description=f"Package `{pkg_name}` successfully updated.", color=discord.Color.green())
1286
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1287
+ embed.timestamp = ctx.message.created_at
1288
+ await msg.edit(embed=embed)
1289
  except Exception as e:
1290
+ # If an exception occurs during the update process, update the message with the exception information
1291
+ embed = discord.Embed(title="An Error Occurred", description=f"An error occurred while updating package `{pkg_name}`: {e}", color=discord.Color.red())
1292
+ await msg.edit(embed=embed)
1293
 
1294
 
1295
  # FUNCTION ------------------------------------------------------ SPLIT
1296
 
1297
 
1298
+ @bot.hybrid_command(help="Shows the IP address of the current server.")
1299
  async def ip(ctx):
1300
  # Check if the author is authorized to use this command
1301
  if str(ctx.author.id) != AUTHORIZED_USER_ID:
1302
  await ctx.reply("You are not authorized to use this command.")
 
1303
  return
1304
 
1305
+ try:
1306
+ # Send a message to indicate that the IP address is being fetched
1307
+ msg = await ctx.reply("Fetching IP address...")
1308
+
1309
+ # Fetch the IP address using the ipify API
1310
+ response = requests.get('https://api.ipify.org')
1311
+ if response.status_code == 200:
1312
+ # If the request was successful, send the IP address as a reply
1313
+ embed = discord.Embed(title="IP Address", description=f"Your IP address is: `{response.text}`", color=discord.Color.green())
1314
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1315
+ embed.timestamp = ctx.message.created_at
1316
+ await msg.edit(embed=embed)
1317
+ else:
1318
+ # If the request failed, update the message to indicate failure
1319
+ embed = discord.Embed(title="Failed to Fetch IP Address", description="Failed to fetch IP address.", color=discord.Color.red())
1320
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1321
+ embed.timestamp = ctx.message.created_at
1322
+ await msg.edit(embed=embed)
1323
+ except Exception as e:
1324
+ # If an exception occurs during the process, update the message with the exception information
1325
+ embed = discord.Embed(title="An Error Occurred", description=f"An error occurred while fetching IP address: {e}", color=discord.Color.red())
1326
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1327
+ embed.timestamp = ctx.message.created_at
1328
+ await msg.edit(embed=embed)
1329
 
1330
 
1331
  # UTILITY ADMIN_CMD ------------------------------------------------------ END
 
1339
 
1340
  @bot.hybrid_command(help="Kick a member from the server.")
1341
  async def kick(ctx, member: discord.Member, *, reason=None):
1342
+ # Check if the command invoker has the necessary permissions to kick members
1343
  if ctx.author.guild_permissions.kick_members or ctx.author == ctx.guild.owner:
1344
+ # Check if the invoker has a higher role than the member to be kicked
1345
  if ctx.author.top_role.position > member.top_role.position:
 
 
1346
  try:
1347
+ # Attempt to send a direct message to the kicked member
1348
  dm_message = f"You have been kicked from the server `{ctx.guild.name}`"
1349
  if reason:
1350
  dm_message += f" for the following reason: `{reason}`"
1351
  await member.send(dm_message)
1352
  except discord.Forbidden:
1353
+ # If unable to send a DM to the kicked member, inform the invoker
1354
  await ctx.reply(f"Failed to send a direct message to {member}.")
1355
 
1356
  # Kick the member from the server
1357
  await member.kick(reason=reason)
1358
+ # Send an embedded message confirming the member has been kicked
1359
+ embed = discord.Embed(title="Member Kicked", description=f"{member} has been kicked from the server.", color=discord.Color.green())
1360
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1361
+ embed.timestamp = ctx.message.created_at
1362
+ await ctx.reply(embed=embed)
1363
  else:
1364
+ # If the invoker does not have a higher role than the member, inform them
1365
  await ctx.reply("You do not have permission to kick this member.")
 
1366
  else:
1367
+ # If the invoker does not have the necessary permissions, inform them
1368
  await ctx.reply("You do not have permission to use this command.")
1369
 
1370
 
 
1373
 
1374
  @bot.hybrid_command(help="Ban a member from the server.")
1375
  async def ban(ctx, member: discord.Member, *, reason=None):
1376
+ # Check if the command invoker has the necessary permissions to ban members
1377
  if ctx.author.guild_permissions.ban_members or ctx.author == ctx.guild.owner:
1378
+ # Check if the invoker has a higher role than the member to be banned
1379
  if ctx.author.top_role.position > member.top_role.position:
 
 
1380
  try:
1381
+ # Attempt to send a direct message to the banned member
1382
  dm_message = f"You have been banned from the server `{ctx.guild.name}`"
1383
  if reason:
1384
  dm_message += f" for the following reason: `{reason}`"
1385
  await member.send(dm_message)
1386
  except discord.Forbidden:
1387
+ # If unable to send a DM to the banned member, inform the invoker
1388
  await ctx.reply(f"Failed to send a direct message to {member}.")
1389
 
1390
  # Ban the member from the server
1391
  await member.ban(reason=reason)
1392
+ # Send an embedded message confirming the member has been banned
1393
+ embed = discord.Embed(title="Member Banned", description=f"{member} has been banned from the server.", color=discord.Color.green())
1394
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1395
+ embed.timestamp = ctx.message.created_at
1396
+ await ctx.reply(embed=embed)
1397
  else:
1398
+ # If the invoker does not have a higher role than the member, inform them
1399
  await ctx.reply("You do not have permission to ban this member.")
 
1400
  else:
1401
+ # If the invoker does not have the necessary permissions, inform them
1402
  await ctx.reply("You do not have permission to use this command.")
1403
 
1404
 
1405
 
 
1406
  # FUNCTION ------------------------------------------------------ SPLIT
1407
 
1408
 
1409
 
1410
  @bot.hybrid_command(help="Timeout a member for a specified duration.")
1411
  async def timeout(ctx, member: discord.Member, duration: int, *, reason=None):
1412
+ # Check if the author is authorized to use this command
 
1413
  if ctx.author.guild_permissions.manage_roles or ctx.author == ctx.guild.owner:
1414
+ # Check if the invoker has a higher role than the member to be timed out
1415
  if ctx.author.top_role.position > member.top_role.position:
 
1416
  try:
1417
+ # Timeout duration in seconds
1418
  timeout_duration = duration
1419
 
1420
  # Timeout the member by removing all roles
1421
  await member.edit(roles=[], reason=reason)
 
 
1422
 
1423
+ # Inform about the timeout
1424
+ embed = discord.Embed(title="Member Timed Out", description=f"`{member}` has been timed out for `{duration} seconds`.\nReason: `{reason}`", color=discord.Color.green())
1425
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1426
+ embed.timestamp = ctx.message.created_at
1427
+ await ctx.reply(embed=embed)
1428
 
1429
  # Send a DM to the timed-out member
1430
+ dm_message = f"You have been timed out in the server `{ctx.guild.name}` for `{duration} seconds`"
1431
+ if reason:
1432
+ dm_message += f" for the following reason: `{reason}`"
1433
+ await member.send(dm_message)
 
1434
 
1435
  except Exception as e:
1436
+ # If an error occurs during the timeout process, inform the invoker
1437
+ embed = discord.Embed(title="Error", description=f"An error occurred while timing out `{member}`: {e}", color=discord.Color.red())
1438
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1439
+ embed.timestamp = ctx.message.created_at
1440
+ await ctx.reply(embed=embed)
1441
+ return
1442
 
1443
  # Wait for the duration of the timeout
1444
  await asyncio.sleep(timeout_duration)
 
1447
  try:
1448
  await member.edit(roles=member.roles, reason=reason)
1449
  except Exception as e:
1450
+ # If an error occurs while restoring roles, inform the invoker
1451
  print(f"An error occurred while restoring roles to `{member}`: {e}")
1452
+ return
1453
 
1454
+ # Inform the member that their timeout has expired
1455
+ dm_message = f"Your timeout in the server `{ctx.guild.name}` for `{duration} seconds`"
1456
  if reason:
1457
+ dm_message += f" for the following reason: `{reason}` has expired."
 
1458
  try:
1459
+ await member.send(dm_message)
1460
  except discord.Forbidden:
1461
+ # If unable to send a DM, inform the invoker
1462
+ embed = discord.Embed(title="Error", description=f"Failed to send DM to `{member}` to notify timeout expiration.", color=discord.Color.red())
1463
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1464
+ embed.timestamp = ctx.message.created_at
1465
+ await ctx.reply(embed=embed)
1466
  else:
1467
+ # If the invoker does not have a higher role than the member, inform them
1468
  await ctx.reply("You do not have permission to timeout this member.")
 
1469
  else:
1470
+ # If the invoker does not have the necessary permissions, inform them
1471
  await ctx.reply("You do not have permission to use this command.")
1472
 
1473
 
 
1476
 
1477
  @bot.hybrid_command(help="Bulk deletes set amount of messages in guilds.")
1478
  async def purge(ctx, amount: int):
1479
+ # Check if the command is invoked in a direct message channel
1480
  if isinstance(ctx.channel, discord.DMChannel):
1481
+ # Inform that purging is not supported in direct messages
1482
+ embed = discord.Embed(title="Purge Error", description="Purging is not supported in direct messages.", color=discord.Color.red())
1483
+ await ctx.reply(embed=embed)
1484
+ return
1485
 
1486
+ # Check if the invoker has the necessary permissions to manage roles or is the guild owner
1487
  if ctx.author.guild_permissions.manage_roles or ctx.author == ctx.guild.owner:
 
1488
  try:
1489
+ # Send a message to indicate that purging is in progress
1490
  msg = await ctx.reply(f"Purging `{amount}` messages...")
1491
 
1492
  try:
1493
  # Use the before parameter to only purge messages before the command is invoked
1494
  await ctx.channel.purge(limit=amount, before=ctx.message)
1495
+ # Update the message to indicate successful purging
1496
+ embed = discord.Embed(title="Purge Successful", description=f"`{amount}` messages purged successfully.", color=discord.Color.green())
1497
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1498
+ embed.timestamp = ctx.message.created_at
1499
+ await msg.edit(content="", embed=embed) # Edit the message to remove content and set the new embed
1500
  except discord.Forbidden:
1501
+ # If the bot doesn't have permission to delete messages, inform the invoker
1502
+ embed = discord.Embed(title="Purge Error", description="I don't have permission to delete messages in this channel.", color=discord.Color.red())
1503
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1504
+ embed.timestamp = ctx.message.created_at
1505
+ await msg.edit(content="", embed=embed) # Edit the message to remove content and set the new embed
1506
  except discord.HTTPException:
1507
+ # If an error occurs during purging, inform the invoker
1508
+ embed = discord.Embed(title="Purge Error", description="Failed to purge messages due to an error.", color=discord.Color.red())
1509
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1510
+ embed.timestamp = ctx.message.created_at
1511
+ await msg.edit(content="", embed=embed) # Edit the message to remove content and set the new embed
1512
 
1513
  except Exception as e:
1514
+ # If an error occurs during the process, inform the invoker
1515
+ embed = discord.Embed(title="Error", description=f"An error occurred: {e}", color=discord.Color.red())
1516
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1517
+ embed.timestamp = ctx.message.created_at
1518
+ await msg.edit(content="", embed=embed)
1519
+ return
1520
  else:
1521
+ # If the invoker doesn't have the necessary permissions, inform them
1522
+ embed = discord.Embed(title="Permission Denied", description="You do not have permission to use this command.", color=discord.Color.red())
1523
+ embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.display_avatar.url if ctx.author.display_avatar else discord.Embed.Empty)
1524
+ embed.timestamp = ctx.message.created_at
1525
+ await msg.edit(content="", embed=embed)
1526
 
1527
  # UTILITY MODERATOR_CMD ------------------------------------------------------ END
1528