2 次代码提交 c68c1e1758 ... 18180b86de

作者 SHA1 备注 提交日期
  Johnounet 18180b86de Version 4.5.1 2 月之前
  Johnounet c7521b95be Version 4.5.0 2 月之前
共有 1 个文件被更改,包括 70 次插入29 次删除
  1. 70 29
      chatbot.py

+ 70 - 29
chatbot.py

@@ -28,7 +28,7 @@ logger.addHandler(console_handler)
 load_dotenv()
 load_dotenv()
 
 
 # Version du bot
 # Version du bot
-VERSION = "4.4.0"  # Modifiable selon la version actuelle
+VERSION = "4.5.0"  # Modifiable selon la version actuelle
 
 
 # Récupérer les variables d'environnement avec validation
 # Récupérer les variables d'environnement avec validation
 def get_env_variable(var_name, is_critical=True, default=None, var_type=str):
 def get_env_variable(var_name, is_critical=True, default=None, var_type=str):
@@ -250,30 +250,83 @@ async def on_message(message):
     if message.author == bot.user:
     if message.author == bot.user:
         return
         return
 
 
+    # Vérifier si le bot est mentionné dans le message
+    if bot.user.mentioned_in(message):
+        # Vérifier si le message provient du channel spécifique
+        if message.channel.id == CHANNEL_ID:
+            # Traiter comme avant (ignorer pour l'instant, car nous voulons que la nouvelle fonctionnalité s'applique partout sauf dans CHANNEL_ID)
+            pass
+        else:
+            # Récupérer les vingt derniers messages dans ce canal (sans compter le message actuel)
+            context_messages = []
+            async for msg in message.channel.history(limit=20, before=message):
+                # Remplacer les mentions par les noms d'utilisateur pour éviter les références circulaires
+                resolved_content = msg.content
+                for user in msg.mentions:
+                    resolved_content = resolved_content.replace(f"<@{user.id}>", f"@{user.display_name}")
+                # Ajouter le nom de l'auteur avant le contenu du message
+                author_name = msg.author.display_name
+                context_messages.append(f"{author_name}: {resolved_content}")
+            # Inverser l'ordre pour avoir les messages du plus ancien au plus récent
+            context_messages.reverse()
+            # Construire le contexte
+            context = "\n".join(context_messages)
+            # Préparer le prompt avec le contexte
+            # Remplacer les mentions dans le message actuel
+            resolved_content = message.content
+            for user in message.mentions:
+                resolved_content = resolved_content.replace(f"<@{user.id}>", f"@{user.display_name}")
+            # Supprimer la mention du bot du message pour éviter les répétitions
+            bot_mention = f"<@{bot.user.id}>"
+            if bot_mention in resolved_content:
+                resolved_content = resolved_content.replace(bot_mention, "").strip()
+            prompt = f"Contexte de la conversation récente:\n{context}\n\nNouveau message: {resolved_content}"
+            # Utiliser le prompt pour appeler l'API Mistral
+            channel_id = str(message.channel.id)
+            # Créer un historique temporaire pour cette conversation
+            temp_history = {
+                "messages": [
+                    {"role": "system", "content": get_personality_prompt()},
+                    {"role": "user", "content": prompt}
+                ]
+            }
+            # Appeler l'API Mistral
+            async with message.channel.typing():
+                try:
+                    response = call_mistral_api(
+                        prompt,
+                        temp_history,  # Utiliser l'historique temporaire
+                        None,  # Pas d'image ici
+                        user_id=str(message.author.id),
+                        username=message.author.display_name
+                    )
+                    await message.channel.send(response)
+                except Exception as e:
+                    logger.error(f"Erreur lors de l'appel à l'API: {e}")
+                    await message.channel.send("Désolé, une erreur est survenue lors du traitement de votre demande.")
+            return
+
     # Vérifier si le message provient du channel spécifique
     # Vérifier si le message provient du channel spécifique
     if message.channel.id != CHANNEL_ID:
     if message.channel.id != CHANNEL_ID:
         return
         return
 
 
-    # Vérifier si le message contient des stickers
+    # Le reste de la fonction on_message pour le traitement normal dans le canal spécifique
+    # Gestion des stickers (code existant)
     if message.stickers:
     if message.stickers:
-        # Obtenir le serveur (guild) du message
         guild = message.guild
         guild = message.guild
         if guild:
         if guild:
-            # Obtenir la liste des stickers personnalisés du serveur
             stickers = guild.stickers
             stickers = guild.stickers
             if stickers:
             if stickers:
-                # Mélanger la liste des stickers pour essayer dans un ordre aléatoire
                 random_stickers = random.sample(stickers, len(stickers))
                 random_stickers = random.sample(stickers, len(stickers))
                 for sticker in random_stickers:
                 for sticker in random_stickers:
                     try:
                     try:
                         logger.info(f"Envoi du sticker: {sticker.name} (ID: {sticker.id})")
                         logger.info(f"Envoi du sticker: {sticker.name} (ID: {sticker.id})")
                         await message.channel.send(stickers=[sticker])
                         await message.channel.send(stickers=[sticker])
-                        break  # Si ça marche, on sort de la boucle
+                        break
                     except discord.errors.Forbidden as e:
                     except discord.errors.Forbidden as e:
                         logger.error(f"Erreur lors de l'envoi du sticker: {sticker.name} (ID: {sticker.id}). Erreur: {e}")
                         logger.error(f"Erreur lors de l'envoi du sticker: {sticker.name} (ID: {sticker.id}). Erreur: {e}")
                         continue
                         continue
                 else:
                 else:
-                    # Si aucun sticker n'a pu être envoyé
                     logger.error("Aucun sticker utilisable trouvé sur ce serveur.")
                     logger.error("Aucun sticker utilisable trouvé sur ce serveur.")
                     await message.channel.send("Aucun sticker utilisable trouvé sur ce serveur.")
                     await message.channel.send("Aucun sticker utilisable trouvé sur ce serveur.")
             else:
             else:
@@ -282,17 +335,16 @@ async def on_message(message):
             await message.channel.send("Ce message ne provient pas d'un serveur.")
             await message.channel.send("Ce message ne provient pas d'un serveur.")
         return
         return
 
 
-    # Vérifier si le message contient uniquement un emoji personnalisé
+    # Gestion des emojis personnalisés (code existant)
     emoji_pattern = re.compile(r'^<a?:\w+:\d+>$')
     emoji_pattern = re.compile(r'^<a?:\w+:\d+>$')
     content = message.content.strip()
     content = message.content.strip()
     if emoji_pattern.match(content):
     if emoji_pattern.match(content):
         guild = message.guild
         guild = message.guild
         if guild and guild.emojis:
         if guild and guild.emojis:
-            # Choisir un emoji aléatoire parmi ceux du serveur
             random_emoji = random.choice(guild.emojis)
             random_emoji = random.choice(guild.emojis)
             try:
             try:
                 await message.channel.send(str(random_emoji))
                 await message.channel.send(str(random_emoji))
-                return  # Retourner pour éviter que le reste du code ne s'exécute
+                return
             except discord.errors.Forbidden as e:
             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}")
                 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.")
                 await message.channel.send("Je n'ai pas pu envoyer d'emoji en réponse.")
@@ -300,13 +352,7 @@ async def on_message(message):
             await message.channel.send("Aucun emoji personnalisé trouvé sur ce serveur.")
             await message.channel.send("Aucun emoji personnalisé trouvé sur ce serveur.")
         return
         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 les pièces jointes pour les images et autres fichiers
+    # Traitement des images et autres fonctionnalités (code existant)
     if message.attachments:
     if message.attachments:
         image_count = 0
         image_count = 0
         non_image_files = []
         non_image_files = []
@@ -314,34 +360,25 @@ async def on_message(message):
         max_size = 5 * 1024 * 1024  # 5 Mo en octets
         max_size = 5 * 1024 * 1024  # 5 Mo en octets
         for attachment in message.attachments:
         for attachment in message.attachments:
             is_image = False
             is_image = False
-            # Vérifier le content_type si disponible
             if attachment.content_type and attachment.content_type.startswith('image/'):
             if attachment.content_type and attachment.content_type.startswith('image/'):
                 is_image = True
                 is_image = True
             else:
             else:
-                # Si content_type n'est pas disponible ou pas une image, vérifier l'extension
                 image_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.tiff', '.svg']
                 image_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.tiff', '.svg']
                 if any(attachment.filename.lower().endswith(ext) for ext in image_extensions):
                 if any(attachment.filename.lower().endswith(ext) for ext in image_extensions):
                     is_image = True
                     is_image = True
-
             if is_image:
             if is_image:
                 image_count += 1
                 image_count += 1
                 if attachment.size > max_size:
                 if attachment.size > max_size:
                     too_large_images.append(attachment.filename)
                     too_large_images.append(attachment.filename)
             else:
             else:
                 non_image_files.append(attachment.filename)
                 non_image_files.append(attachment.filename)
-
-        # Vérifier la présence de fichiers non-image
         if non_image_files:
         if non_image_files:
             file_list = ", ".join(non_image_files)
             file_list = ", ".join(non_image_files)
             await message.channel.send(f"Erreur : Les fichiers suivants ne sont pas des images et ne sont pas pris en charge : {file_list}. Veuillez envoyer uniquement des images.")
             await message.channel.send(f"Erreur : Les fichiers suivants ne sont pas des images et ne sont pas pris en charge : {file_list}. Veuillez envoyer uniquement des images.")
             return
             return
-
-        # Vérifier le nombre d'images
         if image_count > 1:
         if image_count > 1:
             await message.channel.send("Erreur : Vous ne pouvez pas envoyer plus d'une image en un seul message.")
             await message.channel.send("Erreur : Vous ne pouvez pas envoyer plus d'une image en un seul message.")
             return
             return
-
-        # Vérifier la taille des images
         if too_large_images:
         if too_large_images:
             image_list = ", ".join(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.")
             await message.channel.send(f"Erreur : Les images suivantes dépassent la limite de 5 Mo : {image_list}. Veuillez envoyer des images plus petites.")
@@ -360,7 +397,7 @@ async def on_message(message):
     if "messages" not in conversation_history[channel_id]:
     if "messages" not in conversation_history[channel_id]:
         conversation_history[channel_id]["messages"] = []
         conversation_history[channel_id]["messages"] = []
 
 
-    # Traitement des images dans le message
+    # Traitement des images dans le message (code existant)
     image_url = None
     image_url = None
     if message.attachments:
     if message.attachments:
         for attachment in message.attachments:
         for attachment in message.attachments:
@@ -369,11 +406,14 @@ async def on_message(message):
                 break
                 break
 
 
     # Utiliser le contenu résolu (avec les mentions remplacées)
     # Utiliser le contenu résolu (avec les mentions remplacées)
+    resolved_content = message.content
+    for user in message.mentions:
+        resolved_content = resolved_content.replace(f"<@{user.id}>", f"@{user.display_name}")
     prompt = resolved_content
     prompt = resolved_content
-    # Indiquer que le bot est en train de taper
+
+    # Appeler l'API Mistral (code existant)
     async with message.channel.typing():
     async with message.channel.typing():
         try:
         try:
-            # Appeler l'API Mistral avec l'historique de conversation, l'image si présente, et les infos de l'utilisateur
             response = call_mistral_api(
             response = call_mistral_api(
                 prompt,
                 prompt,
                 conversation_history[channel_id],
                 conversation_history[channel_id],
@@ -385,6 +425,7 @@ async def on_message(message):
         except Exception as e:
         except Exception as e:
             logger.error(f"Erreur lors de l'appel à l'API: {e}")
             logger.error(f"Erreur lors de l'appel à l'API: {e}")
             await message.channel.send("Désolé, une erreur est survenue lors du traitement de votre demande.")
             await message.channel.send("Désolé, une erreur est survenue lors du traitement de votre demande.")
+
     # Assurer que les autres gestionnaires d'événements reçoivent également le message
     # Assurer que les autres gestionnaires d'événements reçoivent également le message
     await bot.process_commands(message)
     await bot.process_commands(message)