From 8998d0765aee888e6c4d4e78b73c3859449717e7 Mon Sep 17 00:00:00 2001 From: Tryno Date: Fri, 13 Feb 2026 13:44:00 +0100 Subject: [PATCH 1/6] Add server info command with error handling for missing guild --- features/utils/feature.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/features/utils/feature.py b/features/utils/feature.py index a6176b7..e8f7b79 100644 --- a/features/utils/feature.py +++ b/features/utils/feature.py @@ -38,4 +38,21 @@ async def help_commands(interaction: discord.Interaction): help_message, ephemeral=config.get("ephemeral_default", True) if isinstance(config, dict) else True ) + @group.command(name="serverinfo", description="Affiche les informations du serveur") + async def server_info_command(interaction: discord.Interaction): + guild = interaction.guild + if not guild: + await interaction.response.send_message( + "❌ Impossible de récupérer les informations du serveur.", ephemeral=True + ) + return + embed = discord.Embed(title=f"Informations sur {guild.name}", color=discord.Color.blue()) + embed.add_field(name="ID", value=guild.id, inline=False) + embed.add_field(name="Propriétaire", value=guild.owner, inline=False) + embed.add_field(name="Membres", value=guild.member_count, inline=False) + embed.set_thumbnail(url=guild.icon.url if guild.icon else None) + await interaction.response.send_message( + embed=embed, ephemeral=config.get("ephemeral_default", True) if isinstance(config, dict) else True + ) + tree.add_command(group) From e7870aee5de1407eb8502688600b1bfdee2ed5ce Mon Sep 17 00:00:00 2001 From: Tryno Date: Fri, 13 Feb 2026 13:57:35 +0100 Subject: [PATCH 2/6] Enhance BotApp initialization with additional intents and improve server info command error handling --- bot/core/app.py | 3 +++ features/utils/feature.py | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/bot/core/app.py b/bot/core/app.py index 796c9b0..12b9a1e 100644 --- a/bot/core/app.py +++ b/bot/core/app.py @@ -46,6 +46,9 @@ def setup_logging(level: str = "INFO") -> None: class BotApp(commands.Bot): def __init__(self, guild_id: int) -> None: intents = discord.Intents.default() + intents.message_content = True + intents.guilds = True + intents.members = True super().__init__(command_prefix="!", intents=intents) self.guild = discord.Object(id=guild_id) diff --git a/features/utils/feature.py b/features/utils/feature.py index e8f7b79..0bfc736 100644 --- a/features/utils/feature.py +++ b/features/utils/feature.py @@ -41,6 +41,7 @@ async def help_commands(interaction: discord.Interaction): @group.command(name="serverinfo", description="Affiche les informations du serveur") async def server_info_command(interaction: discord.Interaction): guild = interaction.guild + print(guild.owner if guild else "No guild found") if not guild: await interaction.response.send_message( "❌ Impossible de récupérer les informations du serveur.", ephemeral=True @@ -48,7 +49,7 @@ async def server_info_command(interaction: discord.Interaction): return embed = discord.Embed(title=f"Informations sur {guild.name}", color=discord.Color.blue()) embed.add_field(name="ID", value=guild.id, inline=False) - embed.add_field(name="Propriétaire", value=guild.owner, inline=False) + embed.add_field(name="Propriétaire", value=guild.owner.name if guild.owner else "Inconnu", inline=False) embed.add_field(name="Membres", value=guild.member_count, inline=False) embed.set_thumbnail(url=guild.icon.url if guild.icon else None) await interaction.response.send_message( From 5ebedabd659e423224528e92b11a86eb9df0eed7 Mon Sep 17 00:00:00 2001 From: Tryno Date: Fri, 13 Feb 2026 14:27:32 +0100 Subject: [PATCH 3/6] Enhance server info command with additional guild details and improved error handling --- features/utils/feature.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/features/utils/feature.py b/features/utils/feature.py index 0bfc736..794a5c9 100644 --- a/features/utils/feature.py +++ b/features/utils/feature.py @@ -41,19 +41,31 @@ async def help_commands(interaction: discord.Interaction): @group.command(name="serverinfo", description="Affiche les informations du serveur") async def server_info_command(interaction: discord.Interaction): guild = interaction.guild - print(guild.owner if guild else "No guild found") if not guild: await interaction.response.send_message( "❌ Impossible de récupérer les informations du serveur.", ephemeral=True ) return embed = discord.Embed(title=f"Informations sur {guild.name}", color=discord.Color.blue()) + embed.set_image(url=guild.banner.url if guild.banner else None) + embed.add_field(name="Date de création", value=guild.created_at.strftime("%d/%m/%Y"), inline=False) embed.add_field(name="ID", value=guild.id, inline=False) - embed.add_field(name="Propriétaire", value=guild.owner.name if guild.owner else "Inconnu", inline=False) - embed.add_field(name="Membres", value=guild.member_count, inline=False) + if guild.owner: + embed.add_field(name="Propriétaire", value=guild.owner.name if guild.owner else "Inconnu", inline=False) + embed.add_field(name="Membres", value=guild.member_count, inline=True) + embed.add_field(name="Rôles", value=len(guild.roles), inline=True) + embed.add_field(name="Salons", value=len(guild.channels), inline=True) + embed.add_field(name="Emojis", value=len(guild.emojis), inline=True) + embed.add_field(name="Boosts", value=f"{guild.premium_subscription_count}", inline=True) embed.set_thumbnail(url=guild.icon.url if guild.icon else None) + embed.set_footer( + text="PyBot - Utils Feature", + icon_url=interaction.client.user.avatar.url if interaction.client.user.avatar else None, + ) await interaction.response.send_message( embed=embed, ephemeral=config.get("ephemeral_default", True) if isinstance(config, dict) else True ) + + async tree.add_command(group) From 0eeb496a22cd4d117344d90fae22eeaedd43550b Mon Sep 17 00:00:00 2001 From: Tryno Date: Fri, 13 Feb 2026 14:42:08 +0100 Subject: [PATCH 4/6] Add remind command with time unit validation and response handling --- features/utils/feature.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/features/utils/feature.py b/features/utils/feature.py index 794a5c9..e58d4d0 100644 --- a/features/utils/feature.py +++ b/features/utils/feature.py @@ -65,7 +65,21 @@ async def server_info_command(interaction: discord.Interaction): await interaction.response.send_message( embed=embed, ephemeral=config.get("ephemeral_default", True) if isinstance(config, dict) else True ) - - async + + @group.command(name="remind", description="Créer un rappel") + async def remind(interaction: discord.Interaction, count: int, unit: str, *, message: str): + time_units = {"s": 1, "m": 60, "h": 3600, "d": 86400} + if unit not in time_units: + await interaction.response.send_message( + "❌ Unité de temps invalide. Utilisez 's' pour secondes, 'm' pour minutes, 'h' pour heures ou 'd' pour jours.", + ephemeral=True, + ) + return + delay = count * time_units[unit] + await interaction.response.send_message( + f"⏰ Rappel créé ! Je vous rappellerai dans {count} {unit}.", ephemeral=True + ) + await discord.utils.sleep_until(discord.utils.utcnow() + discord.timedelta(seconds=delay)) + await interaction.followup.send(f"🔔 Rappel : {message}", ephemeral=True) tree.add_command(group) From 4a6bb5bab1cc4cc8edd77f1e6f18c3555e74793d Mon Sep 17 00:00:00 2001 From: Tryno Date: Fri, 13 Feb 2026 14:49:18 +0100 Subject: [PATCH 5/6] Fix remind command to use datetime module for delay calculation and change notification method --- features/utils/feature.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/features/utils/feature.py b/features/utils/feature.py index e58d4d0..da79254 100644 --- a/features/utils/feature.py +++ b/features/utils/feature.py @@ -1,3 +1,5 @@ +import datetime + import discord from discord import app_commands @@ -79,7 +81,7 @@ async def remind(interaction: discord.Interaction, count: int, unit: str, *, mes await interaction.response.send_message( f"⏰ Rappel créé ! Je vous rappellerai dans {count} {unit}.", ephemeral=True ) - await discord.utils.sleep_until(discord.utils.utcnow() + discord.timedelta(seconds=delay)) - await interaction.followup.send(f"🔔 Rappel : {message}", ephemeral=True) + await discord.utils.sleep_until(discord.utils.utcnow() + datetime.timedelta(seconds=delay)) + await interaction.user.send(f"⏰ Rappel : {message}") tree.add_command(group) From 5e5a3deaa7e736ea683008089511ffe8623a5d99 Mon Sep 17 00:00:00 2001 From: Tryno Date: Fri, 13 Feb 2026 15:26:18 +0100 Subject: [PATCH 6/6] Add new commands: ping, uptime, invite, and embed_message with validation and error handling --- features/utils/feature.py | 51 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/features/utils/feature.py b/features/utils/feature.py index da79254..5be6c61 100644 --- a/features/utils/feature.py +++ b/features/utils/feature.py @@ -3,6 +3,8 @@ import discord from discord import app_commands +from bot.core.checks import is_staff + FEATURE = { "slug": "utils", "name": "Utils Feature", @@ -84,4 +86,53 @@ async def remind(interaction: discord.Interaction, count: int, unit: str, *, mes await discord.utils.sleep_until(discord.utils.utcnow() + datetime.timedelta(seconds=delay)) await interaction.user.send(f"⏰ Rappel : {message}") + @group.command(name="ping", description="Affiche la latence du bot") + async def ping(interaction: discord.Interaction): + latency = interaction.client.latency * 1000 # Convertir en millisecondes + await interaction.response.send_message(f"🏓 Pong ! Latence : {latency:.2f} ms", ephemeral=True) + + @group.command(name="uptime", description="Affiche le temps de fonctionnement du bot") + async def uptime(interaction: discord.Interaction): + if not hasattr(interaction.client, "start_time"): + await interaction.response.send_message( + "❌ Impossible de récupérer le temps de fonctionnement.", ephemeral=True + ) + return + uptime_seconds = (discord.utils.utcnow() - interaction.client.start_time).total_seconds() + uptime_str = str(datetime.timedelta(seconds=int(uptime_seconds))) + await interaction.response.send_message(f"⏱️ Temps de fonctionnement : {uptime_str}", ephemeral=True) + + @group.command(name="invite", description="Affiche le lien d'invitation du bot") + async def invite(interaction: discord.Interaction): + invite_link = f"https://discord.com/api/oauth2/authorize?client_id={interaction.client.user.id}&permissions=8&scope=bot%20applications.commands" + await interaction.response.send_message(f"🔗 Voici le lien d'invitation du bot : {invite_link}", ephemeral=True) + + @group.command(name="embed_message", description="Affiche un message dans un embed") + @app_commands.describe( + title="Le titre de l'embed", + description="La description de l'embed", + color="La couleur de l'embed (blue, red, green, yellow, purple, orange)", + ) + @is_staff() + async def embed_message(interaction: discord.Interaction, title: str, description: str, color: str = "blue"): + if color.lower() not in ["blue", "red", "green", "yellow", "purple", "orange"]: + await interaction.response.send_message( + "❌ Couleur invalide. Utilisez 'blue', 'red', 'green', 'yellow', 'purple' ou 'orange'.", ephemeral=True + ) + return + color_mapping = { + "blue": discord.Color.blue(), + "red": discord.Color.red(), + "green": discord.Color.green(), + "yellow": discord.Color.gold(), + "purple": discord.Color.purple(), + "orange": discord.Color.orange(), + } + embed = discord.Embed( + title=title, description=description, color=color_mapping.get(color.lower(), discord.Color.blue()) + ) + await interaction.response.send_message( + embed=embed, ephemeral=config.get("ephemeral_default", True) if isinstance(config, dict) else True + ) + tree.add_command(group)