Merge branch 'dev' into 'main'

Nettoyage du repository

See merge request Omega_Kube/kuby!2
This commit is contained in:
Lucas Durand 2026-02-27 00:57:27 +01:00
commit d41339f196
22 changed files with 285 additions and 49268 deletions

4
.gitignore vendored
View file

@ -1,10 +1,11 @@
# Fichiers d'environnement (contiennent des tokens/clés sensibles)
.env
# Fichiers de configuration générés
config.json
whitelist.json
bridges.json
config.db
malware.json
# Cache Python
__pycache__/
@ -23,4 +24,5 @@ env/
# Logs
*.Logs
*.log
.data

7
bot.py
View file

@ -132,6 +132,13 @@ class MyBot(commands.Bot):
async def on_ready(self):
kuby_logger.info(f"🤖 Bot connecté : {self.user} (ID : {self.user.id})")
kuby_logger.info(f"📊 Serveurs : {len(self.guilds)}")
# Log intents status
kuby_logger.info(f"🔍 Intents Status - Members: {self.intents.members}, Presences: {self.intents.presences}, Core: {self.intents.message_content}")
if not self.intents.members:
kuby_logger.warning("⚠️ L'intent MEMBERS est désactivé ! Les événements de join/leave et les DMs pourraient ne pas fonctionner correctement.")
for guild in self.guilds:
kuby_logger.debug(f"Guild: {guild.name} (ID: {guild.id}) - Members: {guild.member_count}")

18
check_cols.py Normal file
View file

@ -0,0 +1,18 @@
import sqlite3
import os
db_path = "/home/gameurpro12/Documents/Mes_projets/Discord_bot/backup_kuby/config.db"
if os.path.exists(db_path):
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
try:
cursor.execute("SELECT * FROM server_configs LIMIT 1")
col_names = [description[0] for description in cursor.description]
print(f"Columns: {col_names}")
row = cursor.fetchone()
print(f"Data: {row}")
except Exception as e:
print(f"Error: {e}")
conn.close()
else:
print("Database not found")

18
check_db.py Normal file
View file

@ -0,0 +1,18 @@
import sqlite3
import os
db_path = "/home/gameurpro12/Documents/Mes_projets/Discord_bot/backup_kuby/config.db"
if os.path.exists(db_path):
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
try:
cursor.execute("SELECT * FROM server_configs")
rows = cursor.fetchall()
print(f"Server Configs ({len(rows)} rows):")
for row in rows:
print(row)
except Exception as e:
print(f"Error reading database: {e}")
conn.close()
else:
print("Database not found")

18
check_schema.py Normal file
View file

@ -0,0 +1,18 @@
import sqlite3
import os
db_path = "/home/gameurpro12/Documents/Mes_projets/Discord_bot/backup_kuby/config.db"
if os.path.exists(db_path):
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
try:
cursor.execute("PRAGMA table_info(server_configs)")
rows = cursor.fetchall()
print("Table Schema (server_configs):")
for row in rows:
print(row)
except Exception as e:
print(f"Error reading schema: {e}")
conn.close()
else:
print("Database not found")

View file

@ -69,6 +69,43 @@ class BugReportModal(discord.ui.Modal, title="Signaler un Bug"):
else:
await interaction.edit_original_response(content="❌ Une erreur est survenue lors de l'envoi du rapport à GitLab. Veuillez contacter un administrateur.")
class FeatureSuggestionModal(discord.ui.Modal, title="Suggérer une fonctionnalité"):
suggestion_title = discord.ui.TextInput(
label="Titre de la suggestion",
placeholder="Que voulez-vous ajouter ?",
required=True,
max_length=100
)
description = discord.ui.TextInput(
label="Détails de la fonctionnalité",
style=discord.TextStyle.paragraph,
placeholder="Décrivez comment cela devrait fonctionner...",
required=True,
max_length=1000
)
async def on_submit(self, interaction: discord.Interaction):
await interaction.response.send_message("Envoi de votre suggestion à GitLab...", ephemeral=True)
description_text = f"**Suggéré par:** {interaction.user} ({interaction.user.id})\n\n"
description_text += f"**Description:**\n{self.description.value}"
labels = ["enhancement", "manual-suggestion"]
result = await gitlab_client.create_issue(
title=f"[SUGGESTION] {self.suggestion_title.value}",
description=description_text,
labels=labels
)
if result:
issue_iid = result.get("iid")
save_report(issue_iid, interaction.user.id)
await interaction.edit_original_response(content=f"✅ Votre suggestion a été envoyée avec succès ! Merci de contribuer à l'amélioration du bot. [Voir l'issue]({result.get('web_url')})")
else:
await interaction.edit_original_response(content="❌ Une erreur est survenue lors de l'envoi de la suggestion à GitLab.")
class BugReport(commands.Cog):
def __init__(self, bot):
self.bot = bot
@ -98,12 +135,17 @@ class BugReport(commands.Cog):
user = self.bot.get_user(user_id)
if user:
try:
is_suggestion = "[SUGGESTION]" in issue.get('title', '')
title_type = "Suggestion Implémentée !" if is_suggestion else "🛠️ Bug Résolu !"
msg_type = "suggestion" if is_suggestion else "bug"
status_val = "Implémenté / Terminé" if is_suggestion else "Terminé / Résolu"
embed = discord.Embed(
title="🛠️ Bug Résolu !",
description=f"Bonne nouvelle ! Le bug que vous avez signalé (**{issue.get('title')}**) a été marqué comme terminé sur GitLab.",
title=title_type,
description=f"Bonne nouvelle ! Votre {msg_type} (**{issue.get('title')}**) a été marqué comme terminé sur GitLab.",
color=discord.Color.green()
)
embed.add_field(name="Statut", value="Terminé / Résolu")
embed.add_field(name="Statut", value=status_val)
embed.add_field(name="Prochaine étape", value="La mise à jour arrive prochainement !")
embed.set_footer(text="Merci de votre aide pour améliorer le bot.")
await user.send(embed=embed)
@ -133,5 +175,9 @@ class BugReport(commands.Cog):
async def signaler_bug(self, interaction: discord.Interaction, priority: app_commands.Choice[str]):
await interaction.response.send_modal(BugReportModal(priority))
@app_commands.command(name="suggerer_fonctionnalite", description="Proposer une nouvelle fonctionnalité pour le bot")
async def suggerer_fonctionnalite(self, interaction: discord.Interaction):
await interaction.response.send_modal(FeatureSuggestionModal())
async def setup(bot):
await bot.add_cog(BugReport(bot))

View file

@ -12,6 +12,38 @@ class Goodbye(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.db_path = os.path.join(os.path.dirname(__file__), "..", "config.db")
self._init_db()
def _init_db(self):
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
# On s'assure que la table existe au cas où (normalement gérée par welcome.py)
cursor.execute('''
CREATE TABLE IF NOT EXISTS server_configs (
server_id INTEGER PRIMARY KEY,
welcome_channel INTEGER,
goodbye_channel INTEGER,
welcome_dm_message TEXT,
welcome_server_name TEXT,
welcome_banner_background TEXT,
welcome_channel_message TEXT,
goodbye_server_name TEXT,
goodbye_message TEXT
)
''')
# Migration pour ajouter les colonnes si elles n'existent pas
cursor.execute("PRAGMA table_info(server_configs)")
columns = [col[1] for col in cursor.fetchall()]
if 'goodbye_server_name' not in columns:
cursor.execute('ALTER TABLE server_configs ADD COLUMN goodbye_server_name TEXT')
if 'goodbye_message' not in columns:
cursor.execute('ALTER TABLE server_configs ADD COLUMN goodbye_message TEXT')
conn.commit()
conn.close()
def humanize_time_delta(self, date):
if date is None: return "date inconnue"
@ -41,7 +73,7 @@ class Goodbye(commands.Cog):
seconds = delta.seconds % 60
return f"il y a {seconds} {'seconde' if seconds <= 1 else 'secondes'}"
async def create_goodbye_image(self, username, avatar_url):
async def create_goodbye_image(self, username, avatar_url, server_name=None):
current_dir = os.path.dirname(__file__)
base_dir = os.path.abspath(os.path.join(current_dir, ".."))
@ -58,7 +90,10 @@ class Goodbye(commands.Cog):
draw.text((325, 70), "A Bientot", font=font_large, fill=(255,255,255))
draw.text((325, 135), f"{username} chez", font=font_small, fill=(255,255,255))
draw.text((325, 195), "OMEGA KUBE", font=font_large_omega, fill=(255,255,255))
# Afficher le nom du serveur personnalisé s'il existe, sinon OMEGA KUBE
display_name = server_name if server_name else "OMEGA KUBE"
draw.text((325, 195), display_name, font=font_large_omega, fill=(255,255,255))
avatar = Image.open(io.BytesIO(avatar_bytes)).convert("RGBA").resize((224, 224), Image.LANCZOS)
mask = Image.new('L', avatar.size, 0)
@ -75,35 +110,53 @@ class Goodbye(commands.Cog):
async def on_member_remove(self, member):
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute('SELECT goodbye_channel FROM server_configs WHERE server_id = ?', (member.guild.id,))
cursor.execute('SELECT goodbye_channel, goodbye_server_name, goodbye_message FROM server_configs WHERE server_id = ?', (member.guild.id,))
result = cursor.fetchone()
conn.close()
if result and result[0]:
channel = member.guild.get_channel(result[0])
goodbye_channel = result[0]
server_name = result[1]
custom_message = result[2]
channel = member.guild.get_channel(goodbye_channel)
if channel:
img = await self.create_goodbye_image(member.name, member.avatar.url if member.avatar else member.default_avatar.url)
img = await self.create_goodbye_image(
member.name,
member.avatar.url if member.avatar else member.default_avatar.url,
server_name=server_name
)
joined_message = self.humanize_time_delta(member.joined_at)
# Utiliser le message personnalisé ou un par défaut
description = custom_message if custom_message else "Nous espérons vous revoir bientôt <a:rain:1317973615714504806>"
embed = discord.Embed(title=f"{member} viens de nous quitter.",
description="Nous espérons vous revoir bientôt <a:rain:1317973615714504806>",
description=description,
color=discord.Color.dark_magenta())
embed.set_footer(text=f"Avait rejoint {joined_message}")
embed.set_image(url="attachment://goodbye.png")
await channel.send(embed=embed, file=discord.File(img, filename="goodbye.png"))
@app_commands.command(name="setgoodbye", description="Définit le salon d'aurevoir")
@app_commands.command(name="setgoodbye", description="Définit le salon d'aurevoir et les paramètres personnalisés")
@app_commands.checks.has_permissions(administrator=True)
async def set_goodbye(self, interaction: discord.Interaction, channel: discord.TextChannel):
async def set_goodbye(self, interaction: discord.Interaction, channel: discord.TextChannel, server_name: str = None, message: str = None):
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute('''INSERT INTO server_configs (server_id, goodbye_channel)
VALUES (?, ?) ON CONFLICT(server_id)
DO UPDATE SET goodbye_channel=excluded.goodbye_channel''',
(interaction.guild_id, channel.id))
cursor.execute('''INSERT INTO server_configs (server_id, goodbye_channel, goodbye_server_name, goodbye_message)
VALUES (?, ?, ?, ?) ON CONFLICT(server_id)
DO UPDATE SET goodbye_channel=excluded.goodbye_channel,
goodbye_server_name=COALESCE(excluded.goodbye_server_name, goodbye_server_name),
goodbye_message=COALESCE(excluded.goodbye_message, goodbye_message)''',
(interaction.guild_id, channel.id, server_name, message))
conn.commit()
conn.close()
await interaction.response.send_message(f"Salon d'aurevoir défini sur {channel.mention}", ephemeral=True)
msg = f"✅ Salon d'aurevoir défini sur {channel.mention}"
if server_name: msg += f"\nNom du serveur: {server_name}"
if message: msg += f"\nMessage: {message}"
await interaction.response.send_message(msg, ephemeral=True)
async def setup(bot):
await bot.add_cog(Goodbye(bot))

View file

@ -1,20 +0,0 @@
# Fix Plan: Missing _config_roles_callback method
## Problem
The `TicketSetupView` class has a button that references `_config_roles_callback`, but this method doesn't exist. This causes an `AttributeError` when the `/ticketconfig` command is used.
## Solution
1. Add `_config_roles_callback` method to `TicketSetupView` class
2. Create `ConfigRolesSetupView` class to handle config roles selection
## Files to modify
- `commandes/ticket/__init__.py`
## Changes
1. Add `_config_roles_callback` method in `TicketSetupView` (after `_categories_callback`)
2. Add `ConfigRolesSetupView` class (after `StaffRolesSetupView`)
## Status
- [x] Add `_config_roles_callback` method
- [x] Add `ConfigRolesSetupView` class

View file

@ -1,54 +0,0 @@
# Ticket System Fixes - Implementation Status
## ✅ Completed Fixes
### 1. UI Synchronization Issue
- **Problem**: TicketManagementView._claim_callback didn't update Discord UI after removing claim button
- **Fix**: Added `await interaction.response.edit_message(view=self)` after view modification
- **Status**: ✅ FIXED
### 2. Resource Leak and API Overload
- **Problem**: @tasks.loop(seconds=30) on _register_views caused rate limits and memory consumption
- **Fix**: Moved view registration to cog_load() method, removed looped task
- **Status**: ✅ FIXED
### 3. Permission Logic in _reopen_callback
- **Problem**: Loop overwrote permissions for all members instead of targeting ticket.user_id
- **Fix**: Modified logic to specifically restore send_messages permission for ticket.user_id only
- **Status**: ✅ FIXED
### 4. Missing Error Handling in Modals
- **Problem**: TicketPriorityModal and CloseTicketModal lacked on_error methods
- **Fix**: Added try/except blocks in on_submit and implemented on_error methods
- **Status**: ✅ FIXED
### 5. Input Validation in StaffRolesModal
- **Problem**: Regex (\d{17,20}) was too permissive, didn't validate role existence
- **Fix**: Added validation to check if extracted role IDs correspond to existing guild roles
- **Status**: ✅ FIXED
### 6. Circular Import Risk
- **Problem**: Local imports suggested potential circular dependencies
- **Fix**: Verified models.py doesn't import from __init__.py - no circular import exists
- **Status**: ✅ VERIFIED (No fix needed)
## 🧪 Testing Recommendations
1. **UI Updates**: Test ticket claiming - UI should update immediately after claiming
2. **Performance**: Monitor API usage - should be significantly reduced
3. **Permissions**: Test ticket reopening - only ticket creator should regain send_messages
4. **Error Handling**: Trigger errors in modals to verify graceful failure
5. **Role Validation**: Try invalid role IDs in staff configuration
6. **Import Safety**: Verify no import errors on bot startup
## 📋 Files Modified
- `commandes/ticket/__init__.py`: All fixes applied
- `commandes/ticket/data/models.py`: Verified for circular imports (none found)
## 🎯 Impact
- Improved user experience with immediate UI updates
- Reduced API load and memory usage
- Enhanced security with proper permission handling
- Better error resilience
- More robust input validation
- Maintained clean architecture

View file

@ -1,67 +0,0 @@
# Ticket Close Confirmation and Delay - Implementation Plan
## Objective
Add confirmation dialog and waiting delay before ticket closure.
## Changes to make
### 1. Create `CloseConfirmationView` class
- Yes/No confirmation buttons
- Cancel option
- Shows before closing
### 2. Create `CloseDelayView` class
- Countdown display (5 seconds)
- Progress steps:
- 📄 Génération du transcript...
- 📝 Sauvegarde des données...
- 🗑️ Suppression du canal...
- Cancel option during delay
### 3. Modify `TicketManagementView._close_callback`
- Show confirmation view first
- After Yes, show delay view with countdown
- After delay completes, proceed with closing
## Files to modify
- `commandes/ticket/__init__.py`
## Status
- [x] Add CloseConfirmationView class ✅
- [x] Add CloseDelayView class ✅
- [x] Modify TicketManagementView._close_callback ✅
- [x] Add cancel button to CloseDelayView ✅
- [x] Test the flow ✅
## Implementation Details
### CloseConfirmationView
```python
class CloseConfirmationView(discord.ui.View):
"""Confirmation dialog before closing ticket"""
def __init__(self, bot, storage, config, ticket):
super().__init__(timeout=60)
# Yes button (green)
# No button (red) - cancels and removes message
```
### CloseDelayView
```python
class CloseDelayView(discord.ui.View):
"""Countdown and progress before ticket deletion"""
def __init__(self, bot, storage, config, ticket, close_reason):
super().__init__(timeout=None)
# Disable all buttons during countdown
# Update embed with countdown
# After delay, call actual close function
```
## Flow
1. User clicks "Fermer"
2. Show confirmation embed with Yes/No buttons
3. If Yes → Show delay view with countdown
4. After delay → Close ticket and delete channel
5. If No or timeout → Remove confirmation message

View file

@ -1,23 +0,0 @@
# TODO - Correction du système de tickets pour les rôles staff/config
## Problème
Les utilisateurs avec les rôles staff et config ne peuvent pas interagir avec le système de tickets.
## Cause
La méthode `_is_whitelisted` retourne `False` quand le cog WhitelistMonitor n'est pas disponible, les utilisateurs bloquant même staff/config.
## Plan de correction
### Étape 1: Corriger TicketPanelView._is_whitelisted()
- [ ] Modifier pour que les rôles staff/config soient toujours autorisés
### Étape 2: Corriger CategorySelectionView._is_whitelisted()
- [ ] Modifier pour que les rôles staff/config soient toujours autorisés
### Étape 3: Vérifier les autres vues
- [ ] Vérifier TicketManagementView._is_staff()
## État d'avancement
- [x] TicketPanelView._is_whitelisted() corrigé
- [x] CategorySelectionView._is_whitelisted() corrigé
- [x] Tests de vérification

View file

@ -8,6 +8,8 @@ import os
import logging
from PIL import Image, ImageDraw, ImageFont
kuby_logger = logging.getLogger("KubyBot")
class Welcome(commands.Cog):
def __init__(self, bot):
self.bot = bot
@ -42,6 +44,15 @@ class Welcome(commands.Cog):
if 'welcome_channel_message' not in columns:
cursor.execute('ALTER TABLE server_configs ADD COLUMN welcome_channel_message TEXT')
# Migration: Conversion des chemins absolus en chemins relatifs pour les bannières
cursor.execute("SELECT server_id, welcome_banner_background FROM server_configs WHERE welcome_banner_background IS NOT NULL")
for server_id, path in cursor.fetchall():
if path and os.path.isabs(path):
filename = os.path.basename(path)
# Vérifier si c'est bien une bannière dans le dossier banners
if "banner_" in filename:
cursor.execute("UPDATE server_configs SET welcome_banner_background = ? WHERE server_id = ?", (filename, server_id))
conn.commit()
conn.close()
@ -55,8 +66,19 @@ class Welcome(commands.Cog):
avatar_bytes = await resp.read()
# Utiliser le fond personnalisé ou celui par défaut
if banner_background and os.path.exists(banner_background):
background = Image.open(banner_background)
bg_path = None
if banner_background:
# Si c'est un chemin absolu (pour compatibilité temporaire)
if os.path.isabs(banner_background) and os.path.exists(banner_background):
bg_path = banner_background
else:
# Sinon on cherche dans le dossier banners/
potential_path = os.path.join(base_dir, "banners", banner_background)
if os.path.exists(potential_path):
bg_path = potential_path
if bg_path:
background = Image.open(bg_path)
else:
background = Image.open(os.path.join(base_dir, 'background_template.png'))
@ -89,30 +111,47 @@ class Welcome(commands.Cog):
@commands.Cog.listener()
async def on_member_join(self, member):
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute('SELECT welcome_channel, welcome_dm_message, welcome_server_name, welcome_banner_background, welcome_channel_message FROM server_configs WHERE server_id = ?', (member.guild.id,))
result = cursor.fetchone()
conn.close()
welcome_channel = result[0] if result else None
welcome_dm_text = result[1] if result and result[1] else None
server_name = result[2] if result and result[2] else None
banner_background = result[3] if result and result[3] else None
welcome_channel_message = result[4] if result and result[4] else None
kuby_logger.info(f"📥 [Welcome] Événement on_member_join reçu pour {member.name} (ID: {member.id}) sur {member.guild.name}")
# 1. Gestion du DM
if welcome_dm_text:
try:
formatted_message = welcome_dm_text.format(
username=member.name,
servername=member.guild.name,
member_count=member.guild.member_count
)
await member.send(formatted_message)
await member.send("https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExNXV1NW02NTk0bGF2ZHcyMGFna2F6amRrbGpobGpsMHowOW5xa2E5eCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/ZtFuW4rsUbfrRzPauJ/giphy.gif")
except Exception as e:
logging.warning(f"Impossible d'envoyer le DM à {member.name}: {e}")
try:
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute('SELECT welcome_channel, welcome_dm_message, welcome_server_name, welcome_banner_background, welcome_channel_message FROM server_configs WHERE server_id = ?', (member.guild.id,))
result = cursor.fetchone()
conn.close()
if not result:
kuby_logger.warning(f"⚠️ [Welcome] Aucune configuration trouvée dans la base de données pour le serveur {member.guild.id}")
return
welcome_channel = result[0]
welcome_dm_text = result[1]
server_name = result[2]
banner_background = result[3]
welcome_channel_message = result[4]
kuby_logger.debug(f"🔍 [Welcome] Config récupérée: DM={bool(welcome_dm_text)}, Channel={welcome_channel}")
# 1. Gestion du DM
if welcome_dm_text:
kuby_logger.info(f"✉️ [Welcome] Tentative d'envoi de DM à {member.name}")
try:
formatted_message = welcome_dm_text.format(
username=member.name,
servername=member.guild.name,
member_count=member.guild.member_count
)
await member.send(formatted_message)
await member.send("https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExNXV1NW02NTk0bGF2ZHcyMGFna2F6amRrbGpobGpsMHowOW5xa2E5eCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/ZtFuW4rsUbfrRzPauJ/giphy.gif")
kuby_logger.info(f"✅ [Welcome] DM envoyé avec succès à {member.name}")
except discord.Forbidden:
kuby_logger.warning(f"🚫 [Welcome] Impossible d'envoyer le DM à {member.name} (DMs fermés)")
except Exception as e:
kuby_logger.error(f"❌ [Welcome] Erreur lors de l'envoi du DM à {member.name}: {e}", exc_info=True)
else:
kuby_logger.info(f" [Welcome] Aucun message de DM configuré pour le serveur {member.guild.id}")
except Exception as e:
kuby_logger.error(f"❌ [Welcome] Erreur critique dans on_member_join: {e}", exc_info=True)
# 2. Gestion du salon de bienvenue
if welcome_channel:
@ -168,7 +207,7 @@ class Welcome(commands.Cog):
with open(banner_path, 'wb') as f:
f.write(img_data)
return banner_path
return os.path.basename(banner_path)
@app_commands.command(name="setwelcome", description="Définit le salon, les messages de bienvenue et le fond de la bannière")
@app_commands.checks.has_permissions(administrator=True)

BIN
config.db

Binary file not shown.

View file

@ -1,5 +1,5 @@
{
"4": 971446412690722826,
"5": 971446412690722826,
"11": 971446412690722826
"15": 971446412690722826
}

View file

@ -0,0 +1,24 @@
[
{
"timestamp": "2026-02-08T11:49:12.200722",
"event_type": "member_join",
"member_id": 1470008249322438678,
"member_name": "truc_19275",
"member_discriminator": "0",
"member_avatar": null
},
{
"timestamp": "2026-02-08T12:38:12.823655",
"event_type": "member_leave",
"member_id": 1470008249322438678,
"member_name": "truc_19275",
"member_discriminator": "0",
"member_avatar": null,
"roles": {
"role_ids": [],
"role_names": [],
"permissions": []
},
"joined_at": "2026-02-08T10:49:12.106083+00:00"
}
]

View file

@ -0,0 +1,16 @@
[
{
"timestamp": "2026-02-08T12:38:12.823655",
"event_type": "member_leave",
"member_id": 1470008249322438678,
"member_name": "truc_19275",
"member_discriminator": "0",
"member_avatar": null,
"roles": {
"role_ids": [],
"role_names": [],
"permissions": []
},
"joined_at": "2026-02-08T10:49:12.106083+00:00"
}
]

View file

@ -1,44 +0,0 @@
nohup: les entrées sont ignorées
[2026-01-16 18:41:19] [DEBUG] [KubyBot] [debug:50] Raw APPLICATION_ID: 1390778748097527808
[2026-01-16 18:41:19] [INFO] [KubyBot] [info:53] ✅ APPLICATION_ID loaded successfully: 1390778748097527808
[2026-01-16 18:41:19] [DEBUG] [KubyBot] [debug:50] Discord intents configured: <Intents value=53608191>
[2026-01-16 18:41:19] [DEBUG] [KubyBot] [debug:50] Initializing MyBot class
[2026-01-16 18:41:19] [INFO] [KubyBot] [info:53] MyBot instance created successfully
[2026-01-16 18:41:19] [INFO] [KubyBot] [info:53] 🚀 Lancement du bot Kuby...
[2026-01-16 18:41:19] [DEBUG] [KubyBot] [debug:50] Starting __main__.py execution
[2026-01-16 18:41:19] [INFO] [KubyBot] [info:53] 📋 Chargement des variables d'environnement...
[2026-01-16 18:41:19] [DEBUG] [KubyBot] [debug:50] Environment variables loaded
[2026-01-16 18:41:19] [DEBUG] [KubyBot] [debug:50] Token retrieved from environment: ***
[2026-01-16 18:41:19] [INFO] [KubyBot] [info:53] ✅ Token Discord chargé avec succès
[2026-01-16 18:41:19] [INFO] [KubyBot] [info:53] 🚀 Lancement du bot Kuby...
[2026-01-16 18:41:19] [DEBUG] [KubyBot] [debug:50] Entering main with args: (), kwargs: {}
[2026-01-16 18:41:19] [INFO] [KubyBot] [info:53] 🔄 Démarrage de la connexion Discord...
[2026-01-16 18:41:19] [DEBUG] [KubyBot] [debug:50] Starting async context manager
[2026-01-16 18:41:19] [INFO] [KubyBot] [info:53] 🔗 Connexion établie avec Discord...
[2026-01-16 18:41:20] [INFO] [KubyBot] [info:53] 🚀 Démarrage du bot Kuby...
[2026-01-16 18:41:20] [INFO] [KubyBot] [info:53] ✅ Advanced logger initialized
[2026-01-16 18:41:20] [INFO] [KubyBot] [info:53] ✅ Extension chargée : commandes.whitelist
[WhitelistMonitor] Persistent view registered
[2026-01-16 18:41:20] [INFO] [KubyBot] [info:53] ✅ Extension chargée : commandes.whitelist_monitor
[2026-01-16 18:41:20] [INFO] [KubyBot] [info:53] ✅ Extension chargée : commandes.sendbotmessages
[2026-01-16 18:41:20] [INFO] [KubyBot] [info:53] ✅ Extension chargée : commandes.goodbye
[2026-01-16 18:41:20] [INFO] [KubyBot] [info:53] ✅ Extension chargée : commandes.welcome
[2026-01-16 18:41:20] [INFO] [KubyBot] [info:53] ✅ Extension chargée : commandes.security
[2026-01-16 18:41:20] [INFO] [KubyBot] [info:53] ✅ Extension chargée : commandes.snipe
[2026-01-16 18:41:20] [INFO] [KubyBot] [info:53] ✅ Extension chargée : commandes.scan
[2026-01-16 18:41:20] [INFO] [KubyBot] [info:53] ✅ Extension chargée : commandes.no_link
[Blacklist] 0 vues de tickets enregistrées
[2026-01-16 18:41:20] [INFO] [KubyBot] [info:53] ✅ Extension chargée : commandes.blacklist
[Ticket] Views registered for guild 1369669999345537145
[2026-01-16 18:41:20] [INFO] [KubyBot] [info:53] ✅ Extension chargée : commandes.ticket
[2026-01-16 18:41:20] [INFO] [KubyBot] [info:53] ✅ Extension chargée : commandes.modules_security.antispam
[2026-01-16 18:41:20] [INFO] [KubyBot] [info:53] ✅ Extension chargée : commandes.modules_security.antiraid
[2026-01-16 18:41:20] [INFO] [KubyBot] [info:53] ✅ Extension chargée : commandes.modules_security.logs_manager
[Rules] View registered for guild 1369669999345537145
[2026-01-16 18:41:20] [INFO] [KubyBot] [info:53] ✅ Extension chargée : commandes.modules_security.rules
[2026-01-16 18:41:20] [INFO] [KubyBot] [info:53] ✅ Commandes slash synchronisées avec Discord
[2026-01-16 18:41:22] [INFO] [KubyBot] [info:53] 🤖 Bot connecté : Kuby Alpha#6731 (ID : 1390778748097527808)
[2026-01-16 18:41:22] [INFO] [KubyBot] [info:53] 📊 Serveurs : 1
[2026-01-16 18:41:22] [DEBUG] [KubyBot] [debug:50] Guild: Omega Kube Bêta Test (ID: 1369669999345537145) - Members: 19
[2026-01-16 18:41:22] [INFO] [KubyBot] [info:53] 📊 Total members across all guilds: 19
[2026-01-16 18:41:22] [INFO] [KubyBot] [info:53] ✅ Bot prêt et opérationnel !

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1 +0,0 @@
[]