Bladeren bron

Version 4.2.0

Johnounet 2 maanden geleden
bovenliggende
commit
a9fa0db398
1 gewijzigde bestanden met toevoegingen van 82 en 28 verwijderingen
  1. 82 28
      chatbot.py

+ 82 - 28
chatbot.py

@@ -4,15 +4,14 @@ import requests
 import json
 import os
 import random
+import re
 from dotenv import load_dotenv
-from datetime import datetime
 import logging
 from logging.handlers import RotatingFileHandler
 
 # Configuration du logger
 logger = logging.getLogger('discord_bot')
 logger.setLevel(logging.INFO)
-
 formatter = logging.Formatter('[%(asctime)s] %(levelname)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
 
 # Créer un gestionnaire de fichier avec rotation
@@ -29,20 +28,53 @@ logger.addHandler(console_handler)
 load_dotenv()
 
 # Version du bot
-VERSION = "4.1.1"  # Modifiable selon la version actuelle
+VERSION = "4.2.0"  # Modifiable selon la version actuelle
+
+# Récupérer les variables d'environnement avec validation
+def get_env_variable(var_name, is_critical=True, default=None, var_type=str):
+    value = os.getenv(var_name)
+    if value is None:
+        if is_critical:
+            logger.error(f"Variable d'environnement critique manquante: {var_name}")
+            if default is not None:
+                logger.warning(f"Utilisation de la valeur par défaut pour {var_name}")
+                return default
+            else:
+                raise ValueError(f"La variable d'environnement {var_name} est requise mais non définie.")
+        else:
+            logger.warning(f"Variable d'environnement non critique manquante: {var_name}. Utilisation de la valeur par défaut: {default}")
+            return default
+    if var_type == int:
+        try:
+            return int(value)
+        except ValueError:
+            logger.error(f"La variable d'environnement {var_name} doit être un entier. Valeur actuelle: {value}")
+            if default is not None:
+                return default
+            else:
+                raise ValueError(f"La variable d'environnement {var_name} doit être un entier.")
+    return value
+
+try:
+    # Variables d'environnement critiques
+    MISTRAL_API_KEY = get_env_variable('MISTRAL_API_KEY')
+    DISCORD_TOKEN = get_env_variable('DISCORD_TOKEN')
+    CHANNEL_ID = get_env_variable('CHANNEL_ID', var_type=int)
+
+    # Variables d'environnement non critiques avec valeurs par défaut
+    MAX_HISTORY_LENGTH = get_env_variable('MAX_HISTORY_LENGTH', is_critical=False, default=10, var_type=int)
+    HISTORY_FILE = get_env_variable('HISTORY_FILE', is_critical=False, default="conversation_history.json")
 
-# Récupérer les variables d'environnement
-MISTRAL_API_KEY = os.getenv('MISTRAL_API_KEY')
-DISCORD_TOKEN = os.getenv('DISCORD_TOKEN')
-CHANNEL_ID = int(os.getenv('CHANNEL_ID'))
+    logger.info("Toutes les variables d'environnement critiques ont été chargées avec succès.")
+except ValueError as e:
+    logger.error(f"Erreur lors du chargement des variables d'environnement: {e}")
+    # Si une variable critique est manquante, le bot ne peut pas fonctionner correctement.
+    # Il est donc préférable de quitter le programme avec un code d'erreur.
+    exit(1)
 
 # Endpoint API Mistral
 MISTRAL_API_URL = "https://api.mistral.ai/v1/chat/completions"
 
-# Fichier pour stocker l'historique
-HISTORY_FILE = "conversation_history.json"
-MAX_HISTORY_LENGTH = 10  # Limité à 10 messages
-
 def load_history():
     """Charge l'historique depuis un fichier JSON."""
     if os.path.exists(HISTORY_FILE):
@@ -222,6 +254,11 @@ async def on_message(message):
     # Ignorer les messages du bot lui-même
     if message.author == bot.user:
         return
+        
+    # Vérifier si le message provient du channel spécifique
+    if message.channel.id != CHANNEL_ID:
+        return
+        
     # Vérifier si le message contient des stickers
     if message.stickers:
         # Obtenir le serveur (guild) du message
@@ -248,43 +285,60 @@ async def on_message(message):
                 await message.channel.send("Aucun sticker personnalisé trouvé sur ce serveur.")
         else:
             await message.channel.send("Ce message ne provient pas d'un serveur.")
-        return  # Retourner pour éviter que le reste du code ne s'exécute
-    # Vérifier si le message provient du channel spécifique
-    if message.channel.id != CHANNEL_ID:
+        return 
+    
+    # Vérifier si le message contient uniquement un emoji personnalisé
+    emoji_pattern = re.compile(r'^<a?:\w+:\d+>$|^[\u2600-\u27BF\u1F300-\u1F6FF\u1F900-\u1F9FF]+$', re.UNICODE)
+    content = message.content.strip()
+    if emoji_pattern.match(content):
+        guild = message.guild
+        if guild and guild.emojis:
+            # Choisir un emoji aléatoire parmi ceux du serveur
+            random_emoji = random.choice(guild.emojis)
+            try:
+                await message.channel.send(str(random_emoji))
+                return  # Retourner pour éviter que le reste du code ne s'exécute
+            except discord.errors.Forbidden as e:
+                logger.error(f"Erreur lors de l'envoi de l'emoji: {random_emoji.name} (ID: {random_emoji.id}). Erreur: {e}")
+                await message.channel.send("Je n'ai pas pu envoyer d'emoji en réponse.")
+        else:
+            await message.channel.send("Aucun emoji personnalisé trouvé sur ce serveur.")
         return
+        
     # Si le message commence par le préfixe du bot, traiter comme une commande
     if message.content.startswith('!'):
         await bot.process_commands(message)
         return
+        
     # Résolution des mentions dans le message
     resolved_content = message.content
     for user in message.mentions:
         # Remplacer chaque mention par le nom d'utilisateur
         resolved_content = resolved_content.replace(f"<@{user.id}>", f"@{user.display_name}")
-    # Vérifier le nombre d'images dans le message
-    image_count = 0
-    if message.attachments:
-        for attachment in message.attachments:
-            if attachment.content_type and attachment.content_type.startswith('image/'):
-                image_count += 1
-        # Vérifier si le nombre d'images dépasse la limite
-        if image_count > 3:
-            await message.channel.send("Erreur : Vous ne pouvez pas envoyer plus de trois images dans un seul message. Veuillez diviser votre envoi en plusieurs messages.")
-            return
-    # Vérifier les pièces jointes pour la taille des images
+        
+    # Vérifier les pièces jointes pour les images
     if message.attachments:
-        # D'abord, vérifier toutes les images pour leur taille
+        image_count = 0
         too_large_images = []
+        max_size = 5 * 1024 * 1024  # 5 Mo en octets
+
         for attachment in message.attachments:
             if attachment.content_type and attachment.content_type.startswith('image/'):
-                max_size = 5 * 1024 * 1024  # 2 Mo en octets
+                image_count += 1
                 if attachment.size > max_size:
                     too_large_images.append(attachment.filename)
-        # Si des images trop grandes sont trouvées, envoyer un message d'erreur et arrêter
+
+        # Vérifier le nombre d'images
+        if image_count > 1:
+            await message.channel.send("Erreur : Vous ne pouvez pas envoyer plus de trois images dans un seul message. Veuillez diviser votre envoi en plusieurs messages.")
+            return
+
+        # Vérifier la taille des images
         if too_large_images:
             image_list = ", ".join(too_large_images)
             await message.channel.send(f"Erreur : Les images suivantes dépassent la limite de 5 Mo : {image_list}. Veuillez envoyer des images plus petites.")
             return
+
     # Récupérer ou initialiser l'historique pour ce channel
     channel_id = str(message.channel.id)
     global conversation_history