+ Upload
This commit is contained in:
118
cogs/audit_log.py
Normal file
118
cogs/audit_log.py
Normal file
@@ -0,0 +1,118 @@
|
||||
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))
|
Reference in New Issue
Block a user