migration vers new components V2, et ajout de diverse fonctions !

This commit is contained in:
Mathis 2026-05-16 18:05:04 +02:00
parent 3590cb748f
commit ba9e297cb8
14 changed files with 851 additions and 371 deletions

122
bot.py
View file

@ -15,6 +15,59 @@ import logging
from src.advanced_logger import AdvancedLogger
import subprocess
SENSITIVE_PERMISSIONS = {
"administrator", "manage_guild", "manage_roles", "manage_channels",
"kick_members", "ban_members", "manage_messages", "manage_webhooks",
"moderate_members"
}
class RoleApprovalView(disnake.ui.View):
def __init__(self, member: disnake.Member, roles: list, owner: disnake.Member):
super().__init__(timeout=86400) # 24 hours
self.member = member
self.roles = roles
self.owner = owner
@disnake.ui.button(label="Accepter", style=disnake.ButtonStyle.green, emoji="")
async def accept(self, button: disnake.ui.Button, interaction: disnake.MessageInteraction):
# Check if member still in guild
guild = self.member.guild
current_member = guild.get_member(self.member.id)
if not current_member:
await interaction.response.send_message("❌ L'utilisateur n'est plus sur le serveur.", ephemeral=True)
self.stop()
return
try:
await current_member.add_roles(*self.roles, reason="Restauration sécurisée approuvée par le propriétaire")
await interaction.response.send_message(f"✅ Rôles sensibles restaurés pour {self.member.mention}.", ephemeral=True)
# Update original message
components = [
disnake.ui.Container(
disnake.ui.TextDisplay(f"✅ Vous avez approuvé la restauration des rôles pour {self.member.mention}."),
disnake.ui.TextDisplay(f"🛡️ Rôles : {', '.join([r.name for r in self.roles])}")
)
]
await interaction.edit_original_response(embed=None, components=components, view=None)
self.stop()
except Exception as e:
await interaction.response.send_message(f"❌ Erreur lors de l'attribution : {e}", ephemeral=True)
@disnake.ui.button(label="Refuser", style=disnake.ButtonStyle.red, emoji="✖️")
async def deny(self, button: disnake.ui.Button, interaction: disnake.MessageInteraction):
await interaction.response.send_message(f"❌ Vous avez refusé la restauration pour {self.member.mention}.", ephemeral=True)
# Update original message
components = [
disnake.ui.Container(
disnake.ui.TextDisplay(f"❌ Vous avez refusé la restauration des rôles pour {self.member.mention}."),
disnake.ui.TextDisplay(f"🛡️ Rôles : {', '.join([r.name for r in self.roles])}")
)
]
await interaction.edit_original_response(embed=None, components=components, view=None)
self.stop()
# Récupération et validation de l'ID d'application
application_id_raw = os.getenv("APPLICATION_ID")
kuby_logger.debug(f"Raw APPLICATION_ID: {application_id_raw}")
@ -39,6 +92,7 @@ class MyBot(commands.Bot):
command_prefix="!",
intents=intents,
application_id=application_id,
command_sync_flags=commands.CommandSyncFlags.all()
)
kuby_logger.info("MyBot instance created successfully")
@ -89,8 +143,8 @@ class MyBot(commands.Bot):
"commandes.bug_report",
"commandes.convocation",
"commandes.absence_staff",
"commandes.website_sync",
"commandes.moderation",
"commandes.invites",
]
for extension in extensions:
@ -106,7 +160,7 @@ class MyBot(commands.Bot):
if await self.is_owner(inter.author):
return True
command_name = inter.data.name
if command_name in ["ticketconfig", "ticketpanel", "ticket_config", "ticket_panel", "ticket_whitelist_config"]:
if command_name in ["ticketconfig", "ticketpanel", "ticket_config", "ticket_panel", "ticket_whitelist_config", "invitations"]:
return True
whitelist_cog = self.get_cog("WhitelistMonitor")
if not whitelist_cog:
@ -123,7 +177,7 @@ class MyBot(commands.Bot):
kuby_logger.error(f"⚠️ [Check] Erreur critique: {e}", exc_info=True)
return True
self.add_app_command_check(global_slash_whitelist_check)
# self.add_app_command_check(global_slash_whitelist_check)
# --- LOGGING DES INTERACTIONS ---
@self.listen("on_interaction")
@ -170,11 +224,63 @@ class MyBot(commands.Bot):
roles_to_add = [guild.get_role(rid) for rid in previous_roles.get("role_ids", [])]
roles_to_add = [r for r in roles_to_add if r and r < guild.me.top_role]
if roles_to_add:
try:
await member.add_roles(*roles_to_add)
kuby_logger.info(f"Restored {len(roles_to_add)} roles for {member}")
except Exception as e:
kuby_logger.error(f"Failed to restore roles: {e}")
# Separate roles into safe and sensitive
safe_roles = []
sensitive_roles = []
for role in roles_to_add:
is_sensitive = False
for perm in SENSITIVE_PERMISSIONS:
if getattr(role.permissions, perm, False):
is_sensitive = True
break
if is_sensitive:
sensitive_roles.append(role)
else:
safe_roles.append(role)
# Restore safe roles automatically
if safe_roles:
retries = 3
for i in range(retries):
try:
await member.add_roles(*safe_roles)
kuby_logger.info(f"Restored {len(safe_roles)} safe roles for {member}")
break
except (disnake.HTTPException, disnake.GatewayNotFound, asyncio.TimeoutError) as e:
is_transient = isinstance(e, disnake.HTTPException) and e.status in [500, 502, 503, 504]
if not isinstance(e, disnake.HTTPException): is_transient = True
if is_transient and i < retries - 1:
await asyncio.sleep((i + 1) * 2)
continue
kuby_logger.error(f"Failed to restore safe roles for {member}: {e}")
break
except Exception as e:
kuby_logger.error(f"Error restoring safe roles for {member}: {e}")
break
# Handle sensitive roles with owner approval
if sensitive_roles:
try:
owner = guild.owner or await guild.fetch_member(guild.owner_id)
embed = disnake.Embed(
title="⚠️ Restauration de rôles sensibles",
description=(
f"L'utilisateur **{member}** ({member.id}) vient de rejoindre **{guild.name}**.\n\n"
"Certains de ses anciens rôles possèdent des permissions sensibles :\n"
f"🛡️ **Rôles en attente :** {', '.join([r.mention for r in sensitive_roles])}\n\n"
"Voulez-vous restaurer ces rôles ?"
),
color=disnake.Color.yellow()
)
embed.set_thumbnail(url=member.display_avatar.url)
view = RoleApprovalView(member, sensitive_roles, owner)
await owner.send(embed=embed, view=view)
kuby_logger.info(f"Sent role approval request for {member} to owner {owner}")
except Exception as e:
kuby_logger.error(f"Failed to send role approval request to owner: {e}")
async def on_member_remove(self, member):
kuby_logger.info(f"👋 {member} left {member.guild.name}")