mirror of
https://github.com/skylanix/MamieHenriette.git
synced 2026-02-15 12:30:39 +01:00
Ajout d'une table member_invites dans la base de données pour suivre les invitations des membres, et mise à jour des commandes de modération pour supprimer les messages après un délai
This commit is contained in:
@@ -67,3 +67,12 @@ CREATE TABLE IF NOT EXISTS `anticheat_cache` (
|
|||||||
notes VARCHAR(1024),
|
notes VARCHAR(1024),
|
||||||
updated_at DATETIME NOT NULL
|
updated_at DATETIME NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `member_invites` (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
`user_id` VARCHAR(64) NOT NULL,
|
||||||
|
`guild_id` VARCHAR(64) NOT NULL,
|
||||||
|
`invite_code` VARCHAR(256),
|
||||||
|
`inviter_name` VARCHAR(256),
|
||||||
|
`join_date` DATETIME NOT NULL
|
||||||
|
);
|
||||||
|
|||||||
@@ -84,7 +84,8 @@ async def send_access_denied(channel):
|
|||||||
description="Vous n'avez pas les permissions nécessaires pour utiliser cette commande.",
|
description="Vous n'avez pas les permissions nécessaires pour utiliser cette commande.",
|
||||||
color=discord.Color.red()
|
color=discord.Color.red()
|
||||||
)
|
)
|
||||||
await channel.send(embed=embed)
|
msg = await channel.send(embed=embed)
|
||||||
|
asyncio.create_task(delete_after_delay(msg))
|
||||||
|
|
||||||
async def send_user_not_found(channel):
|
async def send_user_not_found(channel):
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
@@ -92,7 +93,8 @@ async def send_user_not_found(channel):
|
|||||||
description="Utilisateur introuvable. Vérifiez la mention ou l'ID Discord.",
|
description="Utilisateur introuvable. Vérifiez la mention ou l'ID Discord.",
|
||||||
color=discord.Color.red()
|
color=discord.Color.red()
|
||||||
)
|
)
|
||||||
await channel.send(embed=embed)
|
msg = await channel.send(embed=embed)
|
||||||
|
asyncio.create_task(delete_after_delay(msg))
|
||||||
|
|
||||||
async def parse_target_user_and_reason(message, bot, parts: list):
|
async def parse_target_user_and_reason(message, bot, parts: list):
|
||||||
if message.mentions:
|
if message.mentions:
|
||||||
@@ -116,7 +118,8 @@ async def send_warning_usage(channel):
|
|||||||
)
|
)
|
||||||
embed.add_field(name="Exemples", value="• `!averto @User Spam dans le chat`\n• `!warn 123456789012345678 Comportement inapproprié`\n• `!av @User`", inline=False)
|
embed.add_field(name="Exemples", value="• `!averto @User Spam dans le chat`\n• `!warn 123456789012345678 Comportement inapproprié`\n• `!av @User`", inline=False)
|
||||||
embed.add_field(name="Aliases", value="`!averto`, `!av`, `!avertissement`, `!warn`", inline=False)
|
embed.add_field(name="Aliases", value="`!averto`, `!av`, `!avertissement`, `!warn`", inline=False)
|
||||||
await channel.send(embed=embed)
|
msg = await channel.send(embed=embed)
|
||||||
|
asyncio.create_task(delete_after_delay(msg))
|
||||||
|
|
||||||
def create_warning_event(target_user, reason: str, staff_member):
|
def create_warning_event(target_user, reason: str, staff_member):
|
||||||
event = ModerationEvent(
|
event = ModerationEvent(
|
||||||
@@ -191,7 +194,8 @@ async def send_remove_warning_usage(channel):
|
|||||||
)
|
)
|
||||||
embed.add_field(name="Exemples", value="• `!delaverto 5`\n• `!removewarn 12`", inline=False)
|
embed.add_field(name="Exemples", value="• `!delaverto 5`\n• `!removewarn 12`", inline=False)
|
||||||
embed.add_field(name="Aliases", value="`!delaverto`, `!removewarn`, `!delwarn`", inline=False)
|
embed.add_field(name="Aliases", value="`!delaverto`, `!removewarn`, `!delwarn`", inline=False)
|
||||||
await channel.send(embed=embed)
|
msg = await channel.send(embed=embed)
|
||||||
|
asyncio.create_task(delete_after_delay(msg))
|
||||||
|
|
||||||
async def send_invalid_event_id(channel):
|
async def send_invalid_event_id(channel):
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
@@ -199,7 +203,8 @@ async def send_invalid_event_id(channel):
|
|||||||
description="L'ID doit être un nombre entier.",
|
description="L'ID doit être un nombre entier.",
|
||||||
color=discord.Color.red()
|
color=discord.Color.red()
|
||||||
)
|
)
|
||||||
await channel.send(embed=embed)
|
msg = await channel.send(embed=embed)
|
||||||
|
asyncio.create_task(delete_after_delay(msg))
|
||||||
|
|
||||||
async def send_event_not_found(channel, event_id: int):
|
async def send_event_not_found(channel, event_id: int):
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
@@ -207,7 +212,8 @@ async def send_event_not_found(channel, event_id: int):
|
|||||||
description=f"Aucun événement de modération trouvé avec l'ID `{event_id}`.",
|
description=f"Aucun événement de modération trouvé avec l'ID `{event_id}`.",
|
||||||
color=discord.Color.red()
|
color=discord.Color.red()
|
||||||
)
|
)
|
||||||
await channel.send(embed=embed)
|
msg = await channel.send(embed=embed)
|
||||||
|
asyncio.create_task(delete_after_delay(msg))
|
||||||
|
|
||||||
def delete_moderation_event(event: ModerationEvent):
|
def delete_moderation_event(event: ModerationEvent):
|
||||||
db.session.delete(event)
|
db.session.delete(event)
|
||||||
@@ -223,7 +229,8 @@ async def send_event_deleted_confirmation(channel, event: ModerationEvent, moder
|
|||||||
embed.add_field(name="🛡️ Modérateur", value=f"{moderator.name}\n`{moderator.id}`", inline=True)
|
embed.add_field(name="🛡️ Modérateur", value=f"{moderator.name}\n`{moderator.id}`", inline=True)
|
||||||
embed.set_footer(text="Mamie Henriette")
|
embed.set_footer(text="Mamie Henriette")
|
||||||
|
|
||||||
await channel.send(embed=embed)
|
msg = await channel.send(embed=embed)
|
||||||
|
asyncio.create_task(delete_after_delay(msg))
|
||||||
await safe_delete_message(original_message)
|
await safe_delete_message(original_message)
|
||||||
|
|
||||||
async def handle_remove_warning_command(message: Message, bot):
|
async def handle_remove_warning_command(message: Message, bot):
|
||||||
@@ -263,7 +270,8 @@ async def send_no_events_found(channel):
|
|||||||
description="Aucun événement de modération trouvé.",
|
description="Aucun événement de modération trouvé.",
|
||||||
color=discord.Color.blue()
|
color=discord.Color.blue()
|
||||||
)
|
)
|
||||||
await channel.send(embed=embed)
|
msg = await channel.send(embed=embed)
|
||||||
|
asyncio.create_task(delete_after_delay(msg))
|
||||||
|
|
||||||
def create_events_list_embed(events: list, page_num: int, per_page: int):
|
def create_events_list_embed(events: list, page_num: int, per_page: int):
|
||||||
start = page_num * per_page
|
start = page_num * per_page
|
||||||
@@ -368,7 +376,8 @@ async def _send_ban_usage(channel):
|
|||||||
color=discord.Color.blue()
|
color=discord.Color.blue()
|
||||||
)
|
)
|
||||||
embed.add_field(name="Exemples", value="• `!ban @User Spam répété`\n• `!ban 123456789012345678 Comportement toxique`", inline=False)
|
embed.add_field(name="Exemples", value="• `!ban @User Spam répété`\n• `!ban 123456789012345678 Comportement toxique`", inline=False)
|
||||||
await channel.send(embed=embed)
|
msg = await channel.send(embed=embed)
|
||||||
|
asyncio.create_task(delete_after_delay(msg))
|
||||||
|
|
||||||
async def _parse_ban_target_and_reason(message: Message, bot, parts: list):
|
async def _parse_ban_target_and_reason(message: Message, bot, parts: list):
|
||||||
if message.mentions:
|
if message.mentions:
|
||||||
@@ -386,7 +395,8 @@ async def _send_user_not_found_for_ban(channel):
|
|||||||
description="Utilisateur introuvable. Vérifiez la mention ou l'ID Discord.",
|
description="Utilisateur introuvable. Vérifiez la mention ou l'ID Discord.",
|
||||||
color=discord.Color.red()
|
color=discord.Color.red()
|
||||||
)
|
)
|
||||||
await channel.send(embed=embed)
|
msg = await channel.send(embed=embed)
|
||||||
|
asyncio.create_task(delete_after_delay(msg))
|
||||||
|
|
||||||
def _create_ban_event(target_user, reason: str, staff_member):
|
def _create_ban_event(target_user, reason: str, staff_member):
|
||||||
event = ModerationEvent(
|
event = ModerationEvent(
|
||||||
@@ -416,7 +426,8 @@ async def _process_ban_success(message: Message, target_user, reason: str, bot):
|
|||||||
description="Je n'ai pas les permissions nécessaires pour bannir cet utilisateur.",
|
description="Je n'ai pas les permissions nécessaires pour bannir cet utilisateur.",
|
||||||
color=discord.Color.red()
|
color=discord.Color.red()
|
||||||
)
|
)
|
||||||
await message.channel.send(embed=embed)
|
msg = await message.channel.send(embed=embed)
|
||||||
|
asyncio.create_task(delete_after_delay(msg))
|
||||||
return
|
return
|
||||||
|
|
||||||
event = _create_ban_event(target_user, reason, message.author)
|
event = _create_ban_event(target_user, reason, message.author)
|
||||||
@@ -459,7 +470,8 @@ async def _send_unban_usage(channel):
|
|||||||
color=discord.Color.blue()
|
color=discord.Color.blue()
|
||||||
)
|
)
|
||||||
embed.add_field(name="Exemples", value="• `!unban 123456789012345678`\n• `!unban #5 Appel accepté`", inline=False)
|
embed.add_field(name="Exemples", value="• `!unban 123456789012345678`\n• `!unban #5 Appel accepté`", inline=False)
|
||||||
await channel.send(embed=embed)
|
msg = await channel.send(embed=embed)
|
||||||
|
asyncio.create_task(delete_after_delay(msg))
|
||||||
|
|
||||||
async def _parse_unban_target_and_reason(message: Message, bot, parts: list):
|
async def _parse_unban_target_and_reason(message: Message, bot, parts: list):
|
||||||
reason = parts[2] if len(parts) > 2 else "Sans raison"
|
reason = parts[2] if len(parts) > 2 else "Sans raison"
|
||||||
@@ -492,7 +504,8 @@ async def _send_unban_invalid_id(channel):
|
|||||||
description="ID Discord invalide ou utilisateur introuvable.",
|
description="ID Discord invalide ou utilisateur introuvable.",
|
||||||
color=discord.Color.red()
|
color=discord.Color.red()
|
||||||
)
|
)
|
||||||
await channel.send(embed=embed)
|
msg = await channel.send(embed=embed)
|
||||||
|
asyncio.create_task(delete_after_delay(msg))
|
||||||
|
|
||||||
async def _process_unban_success(message: Message, bot, target_user, discord_id: str, reason: str):
|
async def _process_unban_success(message: Message, bot, target_user, discord_id: str, reason: str):
|
||||||
try:
|
try:
|
||||||
@@ -503,7 +516,8 @@ async def _process_unban_success(message: Message, bot, target_user, discord_id:
|
|||||||
description="Cet utilisateur n'est pas banni.",
|
description="Cet utilisateur n'est pas banni.",
|
||||||
color=discord.Color.red()
|
color=discord.Color.red()
|
||||||
)
|
)
|
||||||
await message.channel.send(embed=embed)
|
msg = await message.channel.send(embed=embed)
|
||||||
|
asyncio.create_task(delete_after_delay(msg))
|
||||||
return
|
return
|
||||||
except discord.Forbidden:
|
except discord.Forbidden:
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
@@ -511,7 +525,8 @@ async def _process_unban_success(message: Message, bot, target_user, discord_id:
|
|||||||
description="Je n'ai pas les permissions nécessaires pour débannir cet utilisateur.",
|
description="Je n'ai pas les permissions nécessaires pour débannir cet utilisateur.",
|
||||||
color=discord.Color.red()
|
color=discord.Color.red()
|
||||||
)
|
)
|
||||||
await message.channel.send(embed=embed)
|
msg = await message.channel.send(embed=embed)
|
||||||
|
asyncio.create_task(delete_after_delay(msg))
|
||||||
return
|
return
|
||||||
|
|
||||||
username = target_user.name if target_user else f"ID: {discord_id}"
|
username = target_user.name if target_user else f"ID: {discord_id}"
|
||||||
@@ -599,7 +614,8 @@ async def handle_ban_list_command(message: Message, bot):
|
|||||||
description="Vous n'avez pas les permissions nécessaires pour utiliser cette commande.",
|
description="Vous n'avez pas les permissions nécessaires pour utiliser cette commande.",
|
||||||
color=discord.Color.red()
|
color=discord.Color.red()
|
||||||
)
|
)
|
||||||
await message.channel.send(embed=embed)
|
msg = await message.channel.send(embed=embed)
|
||||||
|
asyncio.create_task(delete_after_delay(msg))
|
||||||
return
|
return
|
||||||
|
|
||||||
# Récupérer la liste des bannis
|
# Récupérer la liste des bannis
|
||||||
@@ -806,7 +822,8 @@ async def _send_kick_usage(channel):
|
|||||||
color=discord.Color.blue()
|
color=discord.Color.blue()
|
||||||
)
|
)
|
||||||
embed.add_field(name="Exemples", value="• `!kick @User Spam dans le chat`\n• `!kick 123456789012345678 Comportement inapproprié`", inline=False)
|
embed.add_field(name="Exemples", value="• `!kick @User Spam dans le chat`\n• `!kick 123456789012345678 Comportement inapproprié`", inline=False)
|
||||||
await channel.send(embed=embed)
|
msg = await channel.send(embed=embed)
|
||||||
|
asyncio.create_task(delete_after_delay(msg))
|
||||||
|
|
||||||
async def _parse_kick_target_and_reason(message: Message, bot, parts: list):
|
async def _parse_kick_target_and_reason(message: Message, bot, parts: list):
|
||||||
if message.mentions:
|
if message.mentions:
|
||||||
@@ -824,7 +841,8 @@ async def _send_user_not_found_for_kick(channel):
|
|||||||
description="Utilisateur introuvable. Vérifiez la mention ou l'ID Discord.",
|
description="Utilisateur introuvable. Vérifiez la mention ou l'ID Discord.",
|
||||||
color=discord.Color.red()
|
color=discord.Color.red()
|
||||||
)
|
)
|
||||||
await channel.send(embed=embed)
|
msg = await channel.send(embed)
|
||||||
|
asyncio.create_task(delete_after_delay(msg))
|
||||||
|
|
||||||
async def _process_kick_success(message: Message, target_member, reason: str, bot):
|
async def _process_kick_success(message: Message, target_member, reason: str, bot):
|
||||||
member_obj = message.guild.get_member(target_member.id)
|
member_obj = message.guild.get_member(target_member.id)
|
||||||
@@ -834,7 +852,8 @@ async def _process_kick_success(message: Message, target_member, reason: str, bo
|
|||||||
description="L'utilisateur n'est pas membre du serveur.",
|
description="L'utilisateur n'est pas membre du serveur.",
|
||||||
color=discord.Color.red()
|
color=discord.Color.red()
|
||||||
)
|
)
|
||||||
await message.channel.send(embed=embed)
|
msg = await message.channel.send(embed=embed)
|
||||||
|
asyncio.create_task(delete_after_delay(msg))
|
||||||
return
|
return
|
||||||
joined_days = None
|
joined_days = None
|
||||||
if member_obj.joined_at:
|
if member_obj.joined_at:
|
||||||
@@ -848,7 +867,8 @@ async def _process_kick_success(message: Message, target_member, reason: str, bo
|
|||||||
description="Je n'ai pas les permissions nécessaires pour expulser cet utilisateur.",
|
description="Je n'ai pas les permissions nécessaires pour expulser cet utilisateur.",
|
||||||
color=discord.Color.red()
|
color=discord.Color.red()
|
||||||
)
|
)
|
||||||
await message.channel.send(embed=embed)
|
msg = await message.channel.send(embed=embed)
|
||||||
|
asyncio.create_task(delete_after_delay(msg))
|
||||||
return
|
return
|
||||||
create = ModerationEvent(
|
create = ModerationEvent(
|
||||||
type='kick',
|
type='kick',
|
||||||
@@ -921,7 +941,8 @@ async def send_inspect_usage(channel):
|
|||||||
color=discord.Color.blue()
|
color=discord.Color.blue()
|
||||||
)
|
)
|
||||||
embed.add_field(name="Exemples", value="• `!inspect @User`\n• `!inspect 123456789012345678`", inline=False)
|
embed.add_field(name="Exemples", value="• `!inspect @User`\n• `!inspect 123456789012345678`", inline=False)
|
||||||
await channel.send(embed=embed)
|
msg = await channel.send(embed=embed)
|
||||||
|
asyncio.create_task(delete_after_delay(msg))
|
||||||
|
|
||||||
async def parse_target_user(message: Message, bot, parts: list):
|
async def parse_target_user(message: Message, bot, parts: list):
|
||||||
if message.mentions:
|
if message.mentions:
|
||||||
@@ -999,17 +1020,25 @@ def create_inspect_embed(user, member, join_date, days_on_server, account_age, w
|
|||||||
|
|
||||||
async def get_invite_info_for_user(bot, guild, user_id: int):
|
async def get_invite_info_for_user(bot, guild, user_id: int):
|
||||||
try:
|
try:
|
||||||
from discordbot.welcome import invite_cache
|
from database import db
|
||||||
|
from sqlalchemy import text
|
||||||
|
|
||||||
audit_logs = [entry async for entry in guild.audit_logs(limit=100, action=discord.AuditLogAction.member_join)]
|
result = db.session.execute(
|
||||||
|
text("SELECT invite_code, inviter_name FROM member_invites WHERE user_id = :user_id AND guild_id = :guild_id ORDER BY join_date DESC LIMIT 1"),
|
||||||
|
{'user_id': str(user_id), 'guild_id': str(guild.id)}
|
||||||
|
).fetchone()
|
||||||
|
|
||||||
for entry in audit_logs:
|
if result and result[0]:
|
||||||
if entry.target and entry.target.id == user_id:
|
invite_code = result[0]
|
||||||
if hasattr(entry, 'extra') and entry.extra:
|
inviter_name = result[1]
|
||||||
return f"Code: `{entry.extra}`"
|
display_text = f"`{invite_code}`"
|
||||||
|
if inviter_name:
|
||||||
|
display_text += f" (créée par {inviter_name})"
|
||||||
|
return display_text
|
||||||
|
|
||||||
return None
|
return None
|
||||||
except:
|
except Exception as e:
|
||||||
|
logging.error(f'Erreur lors de la récupération de l\'invitation : {e}')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def handle_inspect_command(message: Message, bot):
|
async def handle_inspect_command(message: Message, bot):
|
||||||
|
|||||||
@@ -28,19 +28,23 @@ async def updateInviteCache(guild):
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def getUsedInvite(guild) -> str:
|
async def getUsedInvite(guild):
|
||||||
try:
|
try:
|
||||||
new_invites = await guild.invites()
|
new_invites = await guild.invites()
|
||||||
for invite in new_invites:
|
for invite in new_invites:
|
||||||
old_uses = invite_cache.get(guild.id, {}).get(invite.code, 0)
|
old_uses = invite_cache.get(guild.id, {}).get(invite.code, 0)
|
||||||
if invite.uses > old_uses:
|
if invite.uses > old_uses:
|
||||||
await updateInviteCache(guild)
|
await updateInviteCache(guild)
|
||||||
inviter = f' (créée par {invite.inviter.name})' if invite.inviter else ''
|
invite_code = invite.code
|
||||||
return f'`{invite.code}`{inviter}'
|
inviter_name = invite.inviter.name if invite.inviter else None
|
||||||
|
display_text = f'`{invite_code}`'
|
||||||
|
if inviter_name:
|
||||||
|
display_text += f' (créée par {inviter_name})'
|
||||||
|
return (invite_code, inviter_name, display_text)
|
||||||
await updateInviteCache(guild)
|
await updateInviteCache(guild)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
return 'Inconnue'
|
return (None, None, 'Inconnue')
|
||||||
|
|
||||||
async def sendWelcomeMessage(bot: discord.Client, member: Member):
|
async def sendWelcomeMessage(bot: discord.Client, member: Member):
|
||||||
config = ConfigurationHelper()
|
config = ConfigurationHelper()
|
||||||
@@ -64,7 +68,24 @@ async def sendWelcomeMessage(bot: discord.Client, member: Member):
|
|||||||
|
|
||||||
welcome_message = replaceMessageVariables(welcome_message, member)
|
welcome_message = replaceMessageVariables(welcome_message, member)
|
||||||
|
|
||||||
invite_used = await getUsedInvite(member.guild)
|
invite_code, inviter_name, invite_display = await getUsedInvite(member.guild)
|
||||||
|
|
||||||
|
try:
|
||||||
|
from database import db
|
||||||
|
from sqlalchemy import text
|
||||||
|
db.session.execute(
|
||||||
|
text("INSERT INTO member_invites (user_id, guild_id, invite_code, inviter_name, join_date) VALUES (:user_id, :guild_id, :invite_code, :inviter_name, :join_date)"),
|
||||||
|
{
|
||||||
|
'user_id': str(member.id),
|
||||||
|
'guild_id': str(member.guild.id),
|
||||||
|
'invite_code': invite_code,
|
||||||
|
'inviter_name': inviter_name,
|
||||||
|
'join_date': datetime.now(timezone.utc)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
db.session.commit()
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f'Échec de la sauvegarde de l\'invitation : {e}')
|
||||||
|
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
title='🎉 Nouveau membre !',
|
title='🎉 Nouveau membre !',
|
||||||
@@ -75,7 +96,7 @@ async def sendWelcomeMessage(bot: discord.Client, member: Member):
|
|||||||
embed.set_thumbnail(url=member.display_avatar.url)
|
embed.set_thumbnail(url=member.display_avatar.url)
|
||||||
embed.add_field(name='Membre', value=member.mention, inline=True)
|
embed.add_field(name='Membre', value=member.mention, inline=True)
|
||||||
embed.add_field(name='Nombre de membres', value=str(member.guild.member_count), inline=True)
|
embed.add_field(name='Nombre de membres', value=str(member.guild.member_count), inline=True)
|
||||||
embed.add_field(name='Invitation utilisée', value=invite_used, inline=False)
|
embed.add_field(name='Invitation utilisée', value=invite_display, inline=False)
|
||||||
embed.set_footer(text=f'ID: {member.id}')
|
embed.set_footer(text=f'ID: {member.id}')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
Reference in New Issue
Block a user