118 lines
5.3 KiB
Python
118 lines
5.3 KiB
Python
import discord
|
|
from discord.ext import commands
|
|
from discord import app_commands
|
|
import sqlite3
|
|
import datetime
|
|
|
|
class AuditLog(commands.Cog):
|
|
def __init__(self, bot: commands.Bot):
|
|
self.bot = bot
|
|
self.db_connection = sqlite3.connect("xalos_data.db")
|
|
self.db_cursor = self.db_connection.cursor()
|
|
# Tabelle für server-spezifische Einstellungen
|
|
self.db_cursor.execute("""
|
|
CREATE TABLE IF NOT EXISTS server_configs (
|
|
guild_id INTEGER PRIMARY KEY,
|
|
log_channel_id INTEGER
|
|
)
|
|
""")
|
|
|
|
async def get_log_channel(self, guild_id: int) -> discord.TextChannel | None:
|
|
"""Holt den Log-Kanal für einen Server aus der DB."""
|
|
self.db_cursor.execute("SELECT log_channel_id FROM server_configs WHERE guild_id = ?", (guild_id,))
|
|
result = self.db_cursor.fetchone()
|
|
if result and result[0]:
|
|
return self.bot.get_channel(result[0])
|
|
return None
|
|
|
|
@app_commands.command(name="setlogchannel", description="Setzt den Kanal für die Audit-Logs.")
|
|
@app_commands.describe(channel="Der Kanal, in den die Logs gesendet werden sollen.")
|
|
@app_commands.checks.has_permissions(manage_guild=True)
|
|
async def set_log_channel(self, interaction: discord.Interaction, channel: discord.TextChannel):
|
|
"""Speichert den Log-Kanal in der Datenbank."""
|
|
self.db_cursor.execute(
|
|
"INSERT OR REPLACE INTO server_configs (guild_id, log_channel_id) VALUES (?, ?)",
|
|
(interaction.guild.id, channel.id)
|
|
)
|
|
self.db_connection.commit()
|
|
await interaction.response.send_message(f"✅ Der Log-Kanal wurde auf {channel.mention} gesetzt.", ephemeral=True)
|
|
|
|
@commands.Cog.listener()
|
|
async def on_message_delete(self, message: discord.Message):
|
|
if message.author.bot or not message.guild:
|
|
return
|
|
|
|
log_channel = await self.get_log_channel(message.guild.id)
|
|
if log_channel:
|
|
embed = discord.Embed(
|
|
title="🗑️ Nachricht gelöscht",
|
|
description=f"**Autor:** {message.author.mention}\n"
|
|
f"**Kanal:** {message.channel.mention}",
|
|
color=discord.Color.orange(),
|
|
timestamp=datetime.datetime.now(datetime.timezone.utc)
|
|
)
|
|
# Füge den Inhalt hinzu, wenn er nicht zu lang ist
|
|
if message.content:
|
|
embed.add_field(name="Inhalt", value=message.content[:1024], inline=False)
|
|
|
|
await log_channel.send(embed=embed)
|
|
|
|
@commands.Cog.listener()
|
|
async def on_message_edit(self, before: discord.Message, after: discord.Message):
|
|
if before.author.bot or not before.guild or before.content == after.content:
|
|
return
|
|
|
|
log_channel = await self.get_log_channel(before.guild.id)
|
|
if log_channel:
|
|
embed = discord.Embed(
|
|
title="✏️ Nachricht bearbeitet",
|
|
description=f"**Autor:** {before.author.mention}\n"
|
|
f"**Kanal:** {before.channel.mention}\n"
|
|
f"[Zur Nachricht springen]({after.jump_url})",
|
|
color=discord.Color.blue(),
|
|
timestamp=datetime.datetime.now(datetime.timezone.utc)
|
|
)
|
|
# Füge den alten und neuen Inhalt hinzu, wenn er nicht zu lang ist
|
|
embed.add_field(name="Vorher", value=before.content[:1024], inline=False)
|
|
embed.add_field(name="Nachher", value=after.content[:1024], inline=False)
|
|
|
|
await log_channel.send(embed=embed)
|
|
|
|
@commands.Cog.listener()
|
|
async def on_member_ban(self, guild: discord.Guild, user: discord.User | discord.Member):
|
|
log_channel = await self.get_log_channel(guild.id)
|
|
if log_channel:
|
|
embed = discord.Embed(
|
|
title="🔨 Mitglied gebannt",
|
|
description=f"**Mitglied:** {user.mention} (`{user.id}`)",
|
|
color=discord.Color.dark_red(),
|
|
timestamp=datetime.datetime.now(datetime.timezone.utc)
|
|
)
|
|
await log_channel.send(embed=embed)
|
|
|
|
@commands.Cog.listener()
|
|
async def on_member_remove(self, member: discord.Member):
|
|
# Dieser Event wird auch bei einem Kick oder Bann ausgelöst. Wir warten kurz,
|
|
# um zu sehen, ob es ein Bann war, um doppelte Logs zu vermeiden.
|
|
await asyncio.sleep(2)
|
|
try:
|
|
# Wenn der Nutzer gebannt wurde, existiert ein Ban-Eintrag
|
|
await member.guild.fetch_ban(member)
|
|
return # Es war ein Bann, on_member_ban kümmert sich darum
|
|
except discord.NotFound:
|
|
# Es war kein Bann (also ein Kick oder freiwilliger Leave)
|
|
log_channel = await self.get_log_channel(member.guild.id)
|
|
if log_channel:
|
|
embed = discord.Embed(
|
|
title="🚪 Mitglied hat den Server verlassen",
|
|
description=f"**Mitglied:** {member.mention} (`{member.id}`)",
|
|
color=discord.Color.greyple(),
|
|
timestamp=datetime.datetime.now(datetime.timezone.utc)
|
|
)
|
|
await log_channel.send(embed=embed)
|
|
|
|
|
|
async def setup(bot: commands.Bot):
|
|
# Wir brauchen asyncio für das Warten im on_member_remove Event
|
|
import asyncio
|
|
await bot.add_cog(AuditLog(bot)) |