Files
Xalos/cogs/audit_log.py
2025-10-06 14:20:28 +02:00

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))