Debug GitLab note DM v7
This commit is contained in:
parent
4dad380a50
commit
2a3d57159a
1 changed files with 22 additions and 81 deletions
91
bot.py
91
bot.py
|
|
@ -13,7 +13,6 @@ import asyncio
|
||||||
from src.logger import kuby_logger, log_performance
|
from src.logger import kuby_logger, log_performance
|
||||||
import logging
|
import logging
|
||||||
from src.advanced_logger import AdvancedLogger
|
from src.advanced_logger import AdvancedLogger
|
||||||
import subprocess
|
|
||||||
|
|
||||||
SENSITIVE_PERMISSIONS = {
|
SENSITIVE_PERMISSIONS = {
|
||||||
"administrator", "manage_guild", "manage_roles", "manage_channels",
|
"administrator", "manage_guild", "manage_roles", "manage_channels",
|
||||||
|
|
@ -30,7 +29,6 @@ class RoleApprovalView(disnake.ui.View):
|
||||||
|
|
||||||
@disnake.ui.button(label="Accepter", style=disnake.ButtonStyle.green, emoji="✅")
|
@disnake.ui.button(label="Accepter", style=disnake.ButtonStyle.green, emoji="✅")
|
||||||
async def accept(self, button: disnake.ui.Button, interaction: disnake.MessageInteraction):
|
async def accept(self, button: disnake.ui.Button, interaction: disnake.MessageInteraction):
|
||||||
# Check if member still in guild
|
|
||||||
guild = self.member.guild
|
guild = self.member.guild
|
||||||
current_member = guild.get_member(self.member.id)
|
current_member = guild.get_member(self.member.id)
|
||||||
if not current_member:
|
if not current_member:
|
||||||
|
|
@ -42,7 +40,6 @@ class RoleApprovalView(disnake.ui.View):
|
||||||
await current_member.add_roles(*self.roles, reason="Restauration sécurisée approuvée par le propriétaire")
|
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)
|
await interaction.response.send_message(f"✅ Rôles sensibles restaurés pour {self.member.mention}.", ephemeral=True)
|
||||||
|
|
||||||
# Update original message
|
|
||||||
components = [
|
components = [
|
||||||
disnake.ui.Container(
|
disnake.ui.Container(
|
||||||
disnake.ui.TextDisplay(f"✅ Vous avez approuvé la restauration des rôles pour {self.member.mention}."),
|
disnake.ui.TextDisplay(f"✅ Vous avez approuvé la restauration des rôles pour {self.member.mention}."),
|
||||||
|
|
@ -58,7 +55,6 @@ class RoleApprovalView(disnake.ui.View):
|
||||||
async def deny(self, button: disnake.ui.Button, interaction: disnake.MessageInteraction):
|
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)
|
await interaction.response.send_message(f"❌ Vous avez refusé la restauration pour {self.member.mention}.", ephemeral=True)
|
||||||
|
|
||||||
# Update original message
|
|
||||||
components = [
|
components = [
|
||||||
disnake.ui.Container(
|
disnake.ui.Container(
|
||||||
disnake.ui.TextDisplay(f"❌ Vous avez refusé la restauration des rôles pour {self.member.mention}."),
|
disnake.ui.TextDisplay(f"❌ Vous avez refusé la restauration des rôles pour {self.member.mention}."),
|
||||||
|
|
@ -68,6 +64,7 @@ class RoleApprovalView(disnake.ui.View):
|
||||||
await interaction.edit_original_response(embed=None, components=components, view=None)
|
await interaction.edit_original_response(embed=None, components=components, view=None)
|
||||||
self.stop()
|
self.stop()
|
||||||
|
|
||||||
|
|
||||||
# Récupération et validation de l'ID d'application
|
# Récupération et validation de l'ID d'application
|
||||||
application_id_raw = os.getenv("APPLICATION_ID")
|
application_id_raw = os.getenv("APPLICATION_ID")
|
||||||
kuby_logger.debug(f"Raw APPLICATION_ID: {application_id_raw}")
|
kuby_logger.debug(f"Raw APPLICATION_ID: {application_id_raw}")
|
||||||
|
|
@ -85,6 +82,7 @@ intents.members = True
|
||||||
intents.voice_states = True
|
intents.voice_states = True
|
||||||
kuby_logger.debug(f"Disnake intents configured: {intents}")
|
kuby_logger.debug(f"Disnake intents configured: {intents}")
|
||||||
|
|
||||||
|
|
||||||
class MyBot(commands.Bot):
|
class MyBot(commands.Bot):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
kuby_logger.debug("Initializing MyBot class")
|
kuby_logger.debug("Initializing MyBot class")
|
||||||
|
|
@ -100,29 +98,11 @@ class MyBot(commands.Bot):
|
||||||
self.advanced_logger = AdvancedLogger(self)
|
self.advanced_logger = AdvancedLogger(self)
|
||||||
kuby_logger.info("✅ Advanced logger initialized")
|
kuby_logger.info("✅ Advanced logger initialized")
|
||||||
|
|
||||||
# Start the Flask Webhook Server
|
# Flask est géré par PM2 (kuby-flask), pas besoin de le lancer ici
|
||||||
self.flask_process = None
|
|
||||||
try:
|
|
||||||
flask_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "serveur_flask.py")
|
|
||||||
if os.path.exists(flask_path):
|
|
||||||
self.flask_process = subprocess.Popen(
|
|
||||||
[sys.executable, flask_path],
|
|
||||||
stdout=subprocess.DEVNULL,
|
|
||||||
stderr=subprocess.DEVNULL,
|
|
||||||
cwd=os.path.dirname(flask_path)
|
|
||||||
)
|
|
||||||
kuby_logger.info(f"✅ Serveur Flask démarré (PID: {self.flask_process.pid})")
|
|
||||||
else:
|
|
||||||
kuby_logger.warning(f"⚠️ Fichier serveur_flask.py introuvable")
|
|
||||||
except Exception as e:
|
|
||||||
kuby_logger.error(f"❌ Impossible de démarrer le serveur Flask: {e}")
|
|
||||||
|
|
||||||
|
|
||||||
async def do_async_setup(self):
|
async def do_async_setup(self):
|
||||||
# --- INITIALIZATION LOGIC (Called before start() in kuby.py) ---
|
|
||||||
kuby_logger.info("🚀 Configuration initiale du bot Kuby...")
|
kuby_logger.info("🚀 Configuration initiale du bot Kuby...")
|
||||||
|
|
||||||
# Charger les extensions
|
|
||||||
extensions = [
|
extensions = [
|
||||||
"commandes.whitelist",
|
"commandes.whitelist",
|
||||||
"commandes.whitelist_monitor",
|
"commandes.whitelist_monitor",
|
||||||
|
|
@ -154,31 +134,6 @@ class MyBot(commands.Bot):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
kuby_logger.error(f"❌ Erreur lors du chargement de {extension} : {e}", exc_info=True)
|
kuby_logger.error(f"❌ Erreur lors du chargement de {extension} : {e}", exc_info=True)
|
||||||
|
|
||||||
# --- SYSTÈME DE WHITELIST (DÉDIÉ SLASH COMMANDS) ---
|
|
||||||
async def global_slash_whitelist_check(inter: disnake.ApplicationCommandInteraction):
|
|
||||||
try:
|
|
||||||
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", "invitations"]:
|
|
||||||
return True
|
|
||||||
whitelist_cog = self.get_cog("WhitelistMonitor")
|
|
||||||
if not whitelist_cog:
|
|
||||||
return True
|
|
||||||
is_whitelisted = whitelist_cog.is_whitelisted(inter.guild.id, inter.author.id)
|
|
||||||
if not is_whitelisted:
|
|
||||||
kuby_logger.info(f"🚫 [Check] Accès refusé : {inter.author} sur /{command_name}")
|
|
||||||
msg = "❌ Vous n'êtes pas autorisé à utiliser cette commande. Veuillez demander à être ajouté à la whitelist."
|
|
||||||
if not inter.response.is_done():
|
|
||||||
await inter.response.send_message(msg, ephemeral=True)
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
except Exception as e:
|
|
||||||
kuby_logger.error(f"⚠️ [Check] Erreur critique: {e}", exc_info=True)
|
|
||||||
return True
|
|
||||||
|
|
||||||
# self.add_app_command_check(global_slash_whitelist_check)
|
|
||||||
|
|
||||||
# --- LOGGING DES INTERACTIONS ---
|
# --- LOGGING DES INTERACTIONS ---
|
||||||
@self.listen("on_interaction")
|
@self.listen("on_interaction")
|
||||||
async def log_interaction(inter: disnake.Interaction):
|
async def log_interaction(inter: disnake.Interaction):
|
||||||
|
|
@ -187,17 +142,6 @@ class MyBot(commands.Bot):
|
||||||
|
|
||||||
kuby_logger.info("✅ Configuration terminée")
|
kuby_logger.info("✅ Configuration terminée")
|
||||||
|
|
||||||
async def close(self):
|
|
||||||
if hasattr(self, 'flask_process') and self.flask_process:
|
|
||||||
kuby_logger.info("Arrêt du serveur Flask interne...")
|
|
||||||
self.flask_process.terminate()
|
|
||||||
try:
|
|
||||||
self.flask_process.wait(timeout=5)
|
|
||||||
except subprocess.TimeoutExpired:
|
|
||||||
self.flask_process.kill()
|
|
||||||
await super().close()
|
|
||||||
|
|
||||||
# --- ÉVÉNEMENTS RESTAURÉS ---
|
|
||||||
async def on_ready(self):
|
async def on_ready(self):
|
||||||
kuby_logger.info(f"🤖 Bot connecté : {self.user} (ID : {self.user.id})")
|
kuby_logger.info(f"🤖 Bot connecté : {self.user} (ID : {self.user.id})")
|
||||||
kuby_logger.info(f"📊 Serveurs : {len(self.guilds)}")
|
kuby_logger.info(f"📊 Serveurs : {len(self.guilds)}")
|
||||||
|
|
@ -224,23 +168,16 @@ class MyBot(commands.Bot):
|
||||||
roles_to_add = [guild.get_role(rid) for rid in previous_roles.get("role_ids", [])]
|
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]
|
roles_to_add = [r for r in roles_to_add if r and r < guild.me.top_role]
|
||||||
if roles_to_add:
|
if roles_to_add:
|
||||||
# Separate roles into safe and sensitive
|
|
||||||
safe_roles = []
|
safe_roles = []
|
||||||
sensitive_roles = []
|
sensitive_roles = []
|
||||||
|
|
||||||
for role in roles_to_add:
|
for role in roles_to_add:
|
||||||
is_sensitive = False
|
is_sensitive = any(getattr(role.permissions, perm, False) for perm in SENSITIVE_PERMISSIONS)
|
||||||
for perm in SENSITIVE_PERMISSIONS:
|
|
||||||
if getattr(role.permissions, perm, False):
|
|
||||||
is_sensitive = True
|
|
||||||
break
|
|
||||||
|
|
||||||
if is_sensitive:
|
if is_sensitive:
|
||||||
sensitive_roles.append(role)
|
sensitive_roles.append(role)
|
||||||
else:
|
else:
|
||||||
safe_roles.append(role)
|
safe_roles.append(role)
|
||||||
|
|
||||||
# Restore safe roles automatically
|
|
||||||
if safe_roles:
|
if safe_roles:
|
||||||
retries = 3
|
retries = 3
|
||||||
for i in range(retries):
|
for i in range(retries):
|
||||||
|
|
@ -250,8 +187,8 @@ class MyBot(commands.Bot):
|
||||||
break
|
break
|
||||||
except (disnake.HTTPException, disnake.GatewayNotFound, asyncio.TimeoutError) as e:
|
except (disnake.HTTPException, disnake.GatewayNotFound, asyncio.TimeoutError) as e:
|
||||||
is_transient = isinstance(e, disnake.HTTPException) and e.status in [500, 502, 503, 504]
|
is_transient = isinstance(e, disnake.HTTPException) and e.status in [500, 502, 503, 504]
|
||||||
if not isinstance(e, disnake.HTTPException): is_transient = True
|
if not isinstance(e, disnake.HTTPException):
|
||||||
|
is_transient = True
|
||||||
if is_transient and i < retries - 1:
|
if is_transient and i < retries - 1:
|
||||||
await asyncio.sleep((i + 1) * 2)
|
await asyncio.sleep((i + 1) * 2)
|
||||||
continue
|
continue
|
||||||
|
|
@ -261,7 +198,6 @@ class MyBot(commands.Bot):
|
||||||
kuby_logger.error(f"Error restoring safe roles for {member}: {e}")
|
kuby_logger.error(f"Error restoring safe roles for {member}: {e}")
|
||||||
break
|
break
|
||||||
|
|
||||||
# Handle sensitive roles with owner approval
|
|
||||||
if sensitive_roles:
|
if sensitive_roles:
|
||||||
try:
|
try:
|
||||||
owner = guild.owner or await guild.fetch_member(guild.owner_id)
|
owner = guild.owner or await guild.fetch_member(guild.owner_id)
|
||||||
|
|
@ -298,19 +234,23 @@ class MyBot(commands.Bot):
|
||||||
kuby_logger.error(f"Error in leave notification: {e}")
|
kuby_logger.error(f"Error in leave notification: {e}")
|
||||||
|
|
||||||
async def on_message_delete(self, message):
|
async def on_message_delete(self, message):
|
||||||
if message.author.bot: return
|
if message.author.bot:
|
||||||
|
return
|
||||||
if hasattr(self, 'advanced_logger'):
|
if hasattr(self, 'advanced_logger'):
|
||||||
self.advanced_logger.log_message_event(message, "deleted")
|
self.advanced_logger.log_message_event(message, "deleted")
|
||||||
|
|
||||||
async def on_message_edit(self, before, after):
|
async def on_message_edit(self, before, after):
|
||||||
if before.author.bot or before.content == after.content: return
|
if before.author.bot or before.content == after.content:
|
||||||
|
return
|
||||||
if hasattr(self, 'advanced_logger'):
|
if hasattr(self, 'advanced_logger'):
|
||||||
self.advanced_logger.log_message_event(before, "edited", {
|
self.advanced_logger.log_message_event(before, "edited", {
|
||||||
"before_content": before.content, "after_content": after.content
|
"before_content": before.content,
|
||||||
|
"after_content": after.content
|
||||||
})
|
})
|
||||||
|
|
||||||
async def on_voice_state_update(self, member, before, after):
|
async def on_voice_state_update(self, member, before, after):
|
||||||
if member.bot: return
|
if member.bot:
|
||||||
|
return
|
||||||
if before.channel != after.channel and hasattr(self, 'advanced_logger'):
|
if before.channel != after.channel and hasattr(self, 'advanced_logger'):
|
||||||
if before.channel is None:
|
if before.channel is None:
|
||||||
self.advanced_logger.log_voice_event(member, after.channel, "joined")
|
self.advanced_logger.log_voice_event(member, after.channel, "joined")
|
||||||
|
|
@ -322,9 +262,10 @@ class MyBot(commands.Bot):
|
||||||
|
|
||||||
async def on_command_error(self, ctx, error):
|
async def on_command_error(self, ctx, error):
|
||||||
if isinstance(error, commands.CommandNotFound):
|
if isinstance(error, commands.CommandNotFound):
|
||||||
return # Ignorer les erreurs "Command not found" pour éviter de polluer les logs (ex: !!)
|
return
|
||||||
if isinstance(error, commands.CheckFailure):
|
if isinstance(error, commands.CheckFailure):
|
||||||
return
|
return
|
||||||
kuby_logger.error(f"Command error in {ctx.command}: {str(error)}", exc_info=True)
|
kuby_logger.error(f"Command error in {ctx.command}: {str(error)}", exc_info=True)
|
||||||
|
|
||||||
|
|
||||||
bot = MyBot()
|
bot = MyBot()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue