Parcourir la source

Initial commit

Andy Esnard il y a 1 an
Parent
commit
4565dd86c7
1 fichiers modifiés avec 186 ajouts et 0 suppressions
  1. 186 0
      chatbot.py

+ 186 - 0
chatbot.py

@@ -0,0 +1,186 @@
+import os
+import openai
+import discord
+import aiohttp
+import asyncio
+import base64
+from dotenv import load_dotenv
+
+# Charger les variables d'environnement depuis le fichier .env
+load_dotenv()
+DISCORD_TOKEN = os.getenv('DISCORD_TOKEN')
+OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
+
+# Vérifier que les tokens sont récupérés
+if DISCORD_TOKEN is None or OPENAI_API_KEY is None:
+    raise ValueError("Les tokens ne sont pas définis dans les variables d'environnement.")
+
+# Initialiser les intents
+intents = discord.Intents.default()
+intents.message_content = True  # Activer l'intent pour les contenus de message
+
+# Initialiser le client Discord avec les intents modifiés
+client_discord = discord.Client(intents=intents)
+
+# Initialiser l'API OpenAI avec un client
+client_openai = openai.OpenAI(api_key=OPENAI_API_KEY)
+
+# Dictionnaire pour stocker l'historique des conversations pour chaque utilisateur
+conversation_history = {}
+
+# L'ID du salon spécifique où le bot est autorisé à répondre
+chatgpt_channel_id = 1284699709188997150  # Remplace par l'ID réel de ton salon
+
+def calculate_cost(usage):
+    input_tokens = usage.get('prompt_tokens', 0)
+    output_tokens = usage.get('completion_tokens', 0)
+
+    # Coûts estimés
+    input_cost = input_tokens / 1_000_000 * 5.00  # 5$ pour 1M tokens d'entrée
+    output_cost = output_tokens / 1_000_000 * 15.00  # 15$ pour 1M tokens de sortie
+    total_cost = input_cost + output_cost
+
+    return input_tokens, output_tokens, total_cost
+
+async def read_text_file(attachment):
+    # Télécharger et lire le contenu du fichier texte
+    async with aiohttp.ClientSession() as session:
+        async with session.get(attachment.url) as resp:
+            return await resp.text()
+
+async def encode_image_from_attachment(attachment):
+    async with aiohttp.ClientSession() as session:
+        async with session.get(attachment.url) as resp:
+            image_data = await resp.read()
+            return base64.b64encode(image_data).decode('utf-8')
+
+async def call_openai_api(user_id, user_text, image_data=None):
+    # Récupérer l'historique de la conversation pour l'utilisateur
+    user_history = conversation_history.get(user_id, [])
+
+    # Préparer le contenu de l'utilisateur
+    user_content = [{"type": "text", "text": user_text}]
+    if image_data:
+        user_content.append({
+            "type": "image_url",
+            "image_url": {"url": f"data:image/jpeg;base64,{image_data}"}
+        })
+
+    # Ajouter le contenu à l'historique
+    user_history.append({
+        "role": "user",
+        "content": user_content
+    })
+
+    payload = {
+        "model": "gpt-4o",
+        "messages": user_history,
+        "max_tokens": 500,
+        "stop": ["\n"]  # Arrête la réponse à la fin d'une phrase
+    }
+
+    headers = {
+       "Content-Type": "application/json",
+        "Authorization": f"Bearer {OPENAI_API_KEY}"
+    }
+
+    try:
+        async with aiohttp.ClientSession() as session:
+            async with session.post("https://api.openai.com/v1/chat/completions", headers=headers, json=payload) as resp:
+                result = await resp.json()
+                if resp.status != 200:
+                    raise ValueError(f"API Error: {result.get('error', {}).get('message', 'Unknown error')}")
+
+                # Calculer les coûts
+                usage = result.get('usage', {})
+                input_tokens, output_tokens, total_cost = calculate_cost(usage)
+
+                # Afficher dans la console
+                print(f"Input Tokens: {input_tokens}")
+                print(f"Output Tokens: {output_tokens}")
+                print(f"Total Tokens: {input_tokens + output_tokens}")
+                print(f"Estimated Cost: ${total_cost:.4f}")
+
+                return result
+    except Exception as e:
+        print(f"Error calling OpenAI API: {e}")
+        return None
+
+@client_discord.event
+async def on_ready():
+    print(f'Bot connecté en tant que {client_discord.user}')
+
+@client_discord.event
+async def on_message(message):
+    # Vérifier si le message provient du canal autorisé
+    if message.channel.id != chatgpt_channel_id:
+        return
+
+    # Vérifier si l'auteur du message est le bot lui-même
+    if message.author == client_discord.user:
+        return
+
+    user_text = message.content.strip()
+    image_data = None
+    file_content = None
+
+    # Extensions de fichiers autorisées
+    allowed_extensions = ['.txt', '.py', '.html', '.css', '.js']
+
+    # Vérifier s'il y a une pièce jointe
+    if message.attachments:
+        for attachment in message.attachments:
+            # Vérifier si c'est un fichier avec une extension autorisée
+            if any(attachment.filename.endswith(ext) for ext in allowed_extensions):
+                file_content = await read_text_file(attachment)
+                break
+            # Vérifier si c'est une image
+            elif attachment.content_type.startswith('image/'):
+                image_data = await encode_image_from_attachment(attachment)
+                break
+
+    # Ajouter le contenu du fichier à la requête si présent
+    if file_content:
+        user_text += f"\nContenu du fichier {attachment.filename}:\n{file_content}"
+
+    # Appeler l'API OpenAI
+    result = await call_openai_api(message.author.id, user_text, image_data)
+    if result:
+        reply = result['choices'][0]['message']['content']
+        await message.channel.send(reply)
+
+        # Ajouter la réponse du modèle à l'historique
+        add_to_conversation_history(message.author.id, {
+            "role": "assistant",
+            "content": reply
+        })
+
+MAX_HISTORY_LENGTH = 50 # Nombre maximum de messages à conserver
+
+def add_to_conversation_history(user_id, new_message):
+    if user_id not in conversation_history:
+        # Ajouter la personnalité de l'IA en tant que premier message
+        conversation_history[user_id] = [
+            {
+                "role": "system",
+                "content": "Tu es une utilisatrice Discord qui parle français."
+                           "Tu ne dis jamais que tu es un IA."
+                           "Tu ne peux pas poster de message de plusieurs lignes."
+                           "Tu peux analyser des images et des pièces jointes aux formats txt, py, html, css et js."
+                           "Tu es cynique et sarcastique."
+                           "Tu apprécies les compliments."
+                           "Réponds sans poser de questions finales comme 'Avez-vous besoin de quelque chose d'autre ?'"
+                           "Privilégie des réponses courtes et percutantes."
+                           "Tu évites de générer des réponses de plus de 500 tokens."
+            }
+        ]
+
+    conversation_history[user_id].append(new_message)
+
+    # Limiter la taille de l'historique
+    if len(conversation_history[user_id]) > MAX_HISTORY_LENGTH:
+        # Garder le premier message de personnalité et les messages les plus récents
+        conversation_history[user_id] = conversation_history[user_id][:1] + conversation_history[user_id][-MAX_HISTORY_LENGTH:]
+
+# Démarrer le bot Discord
+client_discord.run(DISCORD_TOKEN)