137 lines
5.2 KiB
Python
137 lines
5.2 KiB
Python
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import logging
|
||
|
|
|
||
|
|
import discord
|
||
|
|
from discord import app_commands
|
||
|
|
from discord.ext import commands
|
||
|
|
|
||
|
|
from features import shared
|
||
|
|
|
||
|
|
logger = logging.getLogger("vision")
|
||
|
|
|
||
|
|
|
||
|
|
class Welcome(commands.Cog):
|
||
|
|
def __init__(self, bot: commands.Bot):
|
||
|
|
self.bot = bot
|
||
|
|
self._invites: dict[int, dict[str, int]] = {}
|
||
|
|
|
||
|
|
@commands.Cog.listener()
|
||
|
|
async def on_ready(self):
|
||
|
|
await self._cache_invites()
|
||
|
|
|
||
|
|
@commands.Cog.listener()
|
||
|
|
async def on_guild_join(self, guild: discord.Guild):
|
||
|
|
await self._cache_invites_for(guild)
|
||
|
|
|
||
|
|
@commands.Cog.listener()
|
||
|
|
async def on_member_join(self, member: discord.Member):
|
||
|
|
cfg = shared.section(member.guild.id, "welcome")
|
||
|
|
if not cfg.get("enabled"):
|
||
|
|
return
|
||
|
|
|
||
|
|
channel_id = cfg.get("channel_id")
|
||
|
|
if not channel_id:
|
||
|
|
return
|
||
|
|
channel = member.guild.get_channel(channel_id)
|
||
|
|
if not channel:
|
||
|
|
return
|
||
|
|
|
||
|
|
inviter = await self._find_inviter(member)
|
||
|
|
|
||
|
|
text = cfg.get("message", "**{user}** a rejoint **{guild}** ! ({member_count} membres)")
|
||
|
|
text = text.replace("{user}", member.mention).replace("{guild}", member.guild.name)
|
||
|
|
text = text.replace("{member_count}", str(member.guild.member_count))
|
||
|
|
text = text.replace("{username}", member.name)
|
||
|
|
|
||
|
|
embed = discord.Embed(description=text, color=discord.Color.blurple())
|
||
|
|
embed.set_thumbnail(url=member.display_avatar.url)
|
||
|
|
|
||
|
|
if inviter:
|
||
|
|
inviter_data = cfg.get("invites", {}).get(str(inviter.id), 0)
|
||
|
|
embed.add_field(name="Invité par", value=f"{inviter.mention} ({inviter_data + 1} invites)")
|
||
|
|
|
||
|
|
await channel.send(embed=embed)
|
||
|
|
|
||
|
|
if cfg.get("dm_message"):
|
||
|
|
try:
|
||
|
|
dm_text = cfg["dm_message"].replace("{guild}", member.guild.name)
|
||
|
|
await member.send(dm_text)
|
||
|
|
except discord.HTTPException:
|
||
|
|
pass
|
||
|
|
|
||
|
|
await self._update_invite_count(member.guild, inviter)
|
||
|
|
|
||
|
|
async def _find_inviter(self, member: discord.Member) -> discord.Member | None:
|
||
|
|
try:
|
||
|
|
invites = await member.guild.invites()
|
||
|
|
except discord.HTTPException:
|
||
|
|
return None
|
||
|
|
|
||
|
|
cached = self._invites.get(member.guild.id, {})
|
||
|
|
for inv in invites:
|
||
|
|
if cached.get(inv.code, 0) < inv.uses:
|
||
|
|
self._invites.setdefault(member.guild.id, {})[inv.code] = inv.uses
|
||
|
|
return inv.inviter
|
||
|
|
|
||
|
|
self._cache_invites_for(member.guild)
|
||
|
|
return None
|
||
|
|
|
||
|
|
async def _update_invite_count(self, guild: discord.Guild, inviter: discord.Member | None):
|
||
|
|
if not inviter:
|
||
|
|
return
|
||
|
|
cfg = shared.get(guild.id, "welcome")
|
||
|
|
invites = cfg.get("invites", {})
|
||
|
|
key = str(inviter.id)
|
||
|
|
invites[key] = invites.get(key, 0) + 1
|
||
|
|
shared.set(guild.id, "welcome", {**cfg, "invites": invites})
|
||
|
|
|
||
|
|
async def _cache_invites(self):
|
||
|
|
for guild in self.bot.guilds:
|
||
|
|
await self._cache_invites_for(guild)
|
||
|
|
|
||
|
|
async def _cache_invites_for(self, guild: discord.Guild):
|
||
|
|
try:
|
||
|
|
invites = await guild.invites()
|
||
|
|
self._invites[guild.id] = {inv.code: inv.uses for inv in invites}
|
||
|
|
except discord.HTTPException:
|
||
|
|
self._invites[guild.id] = {}
|
||
|
|
|
||
|
|
@app_commands.command(name="welcome_setup", description="Configurer le message d'arrivée")
|
||
|
|
@app_commands.describe(channel="Canal d'arrivée", message="Message (utilise {user}, {guild}, {member_count})")
|
||
|
|
@app_commands.checks.has_permissions(manage_guild=True)
|
||
|
|
async def welcome_setup(self, interaction: discord.Interaction, channel: discord.TextChannel, message: str = ""):
|
||
|
|
cfg = shared.get(interaction.guild_id, "welcome")
|
||
|
|
cfg["enabled"] = True
|
||
|
|
cfg["channel_id"] = channel.id
|
||
|
|
if message:
|
||
|
|
cfg["message"] = message
|
||
|
|
shared.set(interaction.guild_id, "welcome", cfg)
|
||
|
|
await interaction.response.send_message(f"Message d'arrivée configuré dans {channel.mention}", ephemeral=True)
|
||
|
|
|
||
|
|
@app_commands.command(name="welcome_disable", description="Désactiver le message d'arrivée")
|
||
|
|
@app_commands.checks.has_permissions(manage_guild=True)
|
||
|
|
async def welcome_disable(self, interaction: discord.Interaction):
|
||
|
|
cfg = shared.get(interaction.guild_id, "welcome")
|
||
|
|
cfg["enabled"] = False
|
||
|
|
shared.set(interaction.guild_id, "welcome", cfg)
|
||
|
|
await interaction.response.send_message("Message d'arrivée désactivé.", ephemeral=True)
|
||
|
|
|
||
|
|
@app_commands.command(name="invites", description="Voir le nombre d'invitations d'un membre")
|
||
|
|
@app_commands.describe(member="Membre à vérifier")
|
||
|
|
async def invites(self, interaction: discord.Interaction, member: discord.Member):
|
||
|
|
cfg = shared.get(interaction.guild_id, "welcome")
|
||
|
|
invites = cfg.get("invites", {})
|
||
|
|
count = invites.get(str(member.id), 0)
|
||
|
|
embed = discord.Embed(
|
||
|
|
title=f"Invitations de {member}",
|
||
|
|
description=f"**{count}** invitations",
|
||
|
|
color=discord.Color.blurple(),
|
||
|
|
)
|
||
|
|
embed.set_thumbnail(url=member.display_avatar.url)
|
||
|
|
await interaction.response.send_message(embed=embed)
|
||
|
|
|
||
|
|
|
||
|
|
async def setup(bot: commands.Bot):
|
||
|
|
await bot.add_cog(Welcome(bot))
|