Ajout des commandes de gestion du niveau, d'une logique XP, et de nouvelles fonctionnalités bot dans discord_integration.

This commit is contained in:
mrtoine 2025-12-18 14:38:31 +01:00
parent ad6600e4f6
commit 3f90cfa339
7 changed files with 166 additions and 4 deletions

View file

@ -0,0 +1,14 @@
import discord
from discord import app_commands
intents = discord.Intents.default()
intents.members = True
intents.message_content = True
class Bot(discord.Client):
def __init__(self, *, intents: discord.Intents):
super().__init__(intents=intents)
self.tree = app_commands.CommandTree(self)
async def setup_hook(self):
await self.tree.sync()

View file

@ -36,7 +36,6 @@ def process_notifications():
@tasks.loop(seconds=5.0) @tasks.loop(seconds=5.0)
async def check_announcements(client, channel_id): async def check_announcements(client, channel_id):
print("Checking announcements...")
announcements = await sync_to_async(process_notifications)() announcements = await sync_to_async(process_notifications)()
for data in announcements: for data in announcements:

View file

@ -0,0 +1,16 @@
XP = {
"MESSAGE": 5
}
RANK = {
1: "Nouveau membre",
3: "Membre",
7: "Habitué du comptoir",
12: "Expert",
18: "Chevalier du code",
25: "Baron C#",
35: "Lord Script",
50: "Héros des architectures",
75: "Vétéran",
100: "Légende"
}

View file

@ -0,0 +1,70 @@
from datetime import datetime, timezone
from asgiref.sync import sync_to_async
import discord
from datetime import datetime
from discord_integration.models import DiscordLevel
from enums import XP, RANK
from discord import app_commands
def get_user(id_discord):
user, created = DiscordLevel.objects.get_or_create(discord_id=id_discord)
return user, created
def update_user_xp(user, xp_to_add):
leveled_up = False
# 1. Mise à jour de l'XP et du temps
user.total_xp += xp_to_add
user.last_message = datetime.now(timezone.utc)
# 2. Calcul du niveau théorique
calculated_level = int(0.5 + (0.25 + user.total_xp / 50)**0.5)
# 3. Vérification du Level Up
if calculated_level > user.level:
user.level = calculated_level
leveled_up = True
new_rank = RANK[1]
for level_threshold, rank_name in RANK.items():
if user.level >= level_threshold:
new_rank = rank_name
else:
break
user.rank = new_rank
user.save()
return user, leveled_up
async def check_add_xp(message, client):
id_discord = message.author.id
username = message.author.name
user_db, created = await sync_to_async(get_user)(id_discord)
if not created and user_db.last_message:
delta = datetime.now(timezone.utc) - user_db.last_message
if delta.seconds < 6:
return
user_db, leveled_up = await sync_to_async(update_user_xp)(user_db, XP["MESSAGE"])
if leveled_up:
# On crée un petit message sympa
await message.channel.send(
f"🎊 **LEVEL UP** 🎊\nBravo {message.author.mention}, tu passes **niveau {user_db.level}** ! "
f"On applaudit tous bien fort ! Clap Clap !!"
)
else:
# Juste un petit log console pour toi
print(f"✨ XP ajouté pour {message.author.name} (Total: {user_db.total_xp})")
# AJOUT DES COMMANDES /xp et /level
@app_commands.command(name="level", description="Permet de connaitre ton xp actuel")
async def get_xp(interaction: discord.Interaction):
user_id = interaction.user.id
user_db, _ = await sync_to_async(get_user)(user_id)
await interaction.response.send_message(f"{interaction.user.mention} : Tu as {user_db.total_xp} XP et tu es niveau {user_db.level} !\nTon rang est {user_db.rank} !")

View file

@ -1,6 +1,8 @@
import discord import discord
import django import django
import os, sys import os, sys
import dotenv
from discord.ext import commands from discord.ext import commands
# On import django pour communiquer avec # On import django pour communiquer avec
@ -13,9 +15,12 @@ django.setup()
# Import des fonctions # Import des fonctions
from role_logic import check_role_reaction from role_logic import check_role_reaction
from announces_logic import check_announcements from announces_logic import check_announcements
from random_phrase import get_random_phrase
from level_logic import check_add_xp, get_xp
import BotClass
# CONFIGURATION # CONFIGURATION
TOKEN = 'MTQ1MDkyNzQ5NzQ3Nzc1MDg1NA.GmkYxN.YHWXYUIav51yriV_9EotmtUO-cQqdVFLkkb6Do' TOKEN = dotenv.get_key(BASE_DIR + '/.env', 'D_TOKEN')
MESSAGE_ID = 1450928822156263505 # L'ID du message des règles (clic droit > Copier l'identifiant) MESSAGE_ID = 1450928822156263505 # L'ID du message des règles (clic droit > Copier l'identifiant)
ROLE_ID = 1450920002868875435 # L'ID du rôle "Membres" ROLE_ID = 1450920002868875435 # L'ID du rôle "Membres"
ANNOUNCEMENT_CHANNEL_ID = 1450912559774306346 ANNOUNCEMENT_CHANNEL_ID = 1450912559774306346
@ -26,15 +31,34 @@ intents = discord.Intents.default()
intents.members = True # Important pour pouvoir donner des rôles intents.members = True # Important pour pouvoir donner des rôles
intents.message_content = True intents.message_content = True
client = discord.Client(intents=intents) client = BotClass.Bot(intents=intents)
client.tree.add_command(get_random_phrase)
client.tree.add_command(get_xp)
@client.event @client.event
async def on_ready(): async def on_ready():
print(f'✅ Bot connecté : {client.user}') print(f'✅ Bot connecté : {client.user}')
try:
synced = await client.tree.sync()
print(f"🌍 {len(synced)} commandes slash synchronisées !")
except Exception as e:
print(f"❌ Erreur de synchronisation : {e}")
if not check_announcements.is_running(): if not check_announcements.is_running():
check_announcements.start(client, ANNOUNCEMENT_CHANNEL_ID) check_announcements.start(client, ANNOUNCEMENT_CHANNEL_ID)
@client.event
async def on_message(message):
if message.author == client.user:
return
if message.guild is None:
author = message.author
await message.channel.send("Bonjour !\nJe suis un bot destiné à tester les nouvelles fonctionnalités de Discord. Pour le moment, je suis qu'en lecture seule.")
else:
await check_add_xp(message, client)
@client.event @client.event
async def on_raw_reaction_add(payload): async def on_raw_reaction_add(payload):
# On envoie tout le nécessaire à notre fonction dans role_logic.py # On envoie tout le nécessaire à notre fonction dans role_logic.py

View file

@ -0,0 +1,32 @@
import discord
import random
from discord import app_commands
phrase = [
"Yo !",
"Quoi de neuf ?",
"Je suis occupé à compter mes octets.",
"Vive la Belgique ! 🇧🇪",
"Cest pas un bug, cest une fonctionnalité non documentée ! 🐛",
"Est-ce quon peut dire que mon code est une œuvre dart ? Non ? Dommage.",
"Je ne plante pas, je fais une pause créative.",
"Quelquun a vu mon point-virgule ? Il a disparu depuis le dernier commit.",
"Je mangerais bien une mitraillette sauce andalouse, mais mon système digestif est en 404. 🍟",
"42. Voilà. Maintenant, pose-moi une vraie question.",
"On mange quoi ? Ah non, c'est vrai, je suis un robot... Tristesse infinie. 🤖",
"C'est écrit en Python, donc c'est forcément élégant, non ?",
"Un petit café ? Pour moi, une petite dose d'électricité suffira.",
"Je parie que tu n'as pas encore fait ton `git push` aujourd'hui. Je te surveille ! 👀",
"En Belgique, on n'a peut-être pas toujours du soleil, mais on a les meilleures frites ! 🇧🇪🍟",
"Il y a 10 types de personnes : celles qui comprennent le binaire, et les autres.",
"Mon processeur chauffe... soit je réfléchis trop, soit ton code est trop complexe !",
"Tout va bien, tant que personne ne touche au dossier `migrations` de Django...",
"Sais-tu pourquoi les développeurs détestent la nature ? Parce qu'il y a trop de bugs. 🌳",
"On n'est pas là pour trier des lentilles, une fois ! On code ou quoi ? 🇧🇪"
]
@app_commands.command(name="random_phrase", description="Envoi une phrase aléatoire !")
async def get_random_phrase(interaction: discord.Interaction):
choice = random.choice(phrase)
await interaction.response.send_message(choice)

View file

@ -11,3 +11,10 @@ class DiscordNotification(models.Model):
def __str__(self): def __str__(self):
return f"Annonces pour {self.content_object} ({'' if self.is_announced else ''})" return f"Annonces pour {self.content_object} ({'' if self.is_announced else ''})"
class DiscordLevel(models.Model):
discord_id = models.BigIntegerField()
total_xp = models.PositiveIntegerField(default=0)
level = models.PositiveIntegerField(default=1)
rank = models.TextField(default="Nouveau membre")
last_message = models.DateTimeField(auto_now_add=True)