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

103 lines
3.9 KiB
Python

import discord
from discord.ext import commands
from discord import app_commands
import datetime
import asyncio
import random
import re
def parse_duration(duration_str: str) -> int:
"""
Wandelt einen Dauer-String (z.B. "1d", "12h", "30m", "5s") in Sekunden um.
Gibt 0 zurück, wenn das Format ungültig ist.
"""
match = re.match(r"(\d+)([dhms])", duration_str.lower())
if not match:
return 0
value, unit = int(match.group(1)), match.group(2)
if unit == 'd':
return value * 86400
elif unit == 'h':
return value * 3600
elif unit == 'm':
return value * 60
elif unit == 's':
return value
return 0
class Giveaways(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot
@app_commands.command(name="giveaway", description="Startet eine Verlosung.")
@app_commands.describe(
duration="Dauer (z.B. 10m, 1h, 2d).",
winners="Anzahl der Gewinner.",
prize="Der Preis, der verlost wird."
)
@app_commands.checks.has_permissions(manage_guild=True)
async def giveaway(self, interaction: discord.Interaction, duration: str, winners: int, prize: str):
"""Startet eine Verlosung."""
seconds = parse_duration(duration)
if seconds <= 0:
await interaction.response.send_message("Ungültiges Zeitformat! Bitte benutze `d`, `h`, `m` oder `s` (z.B. `10m` oder `2h`).", ephemeral=True)
return
if winners < 1:
await interaction.response.send_message("Die Anzahl der Gewinner muss mindestens 1 sein.", ephemeral=True)
return
end_time = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(seconds=seconds)
embed = discord.Embed(
title=f"🎉 Verlosung: {prize}",
description=f"Reagiere mit 🎉, um teilzunehmen!\n"
f"Endet: <t:{int(end_time.timestamp())}:R>\n"
f"Veranstalter: {interaction.user.mention}",
color=discord.Color.gold()
)
embed.set_footer(text=f"{winners} Gewinner")
# Sende die Nachricht und reagiere, um die Teilnahme zu starten
await interaction.response.send_message("Verlosung wird gestartet...", ephemeral=True)
giveaway_message = await interaction.channel.send(embed=embed)
await giveaway_message.add_reaction("🎉")
# Warte bis zum Ende der Verlosung
await asyncio.sleep(seconds)
# Hole die Nachricht erneut, um die aktuellen Reaktionen zu bekommen
try:
updated_message = await interaction.channel.fetch_message(giveaway_message.id)
except discord.NotFound:
# Nachricht wurde gelöscht, Verlosung abbrechen
return
# Finde alle Teilnehmer (ohne Bots)
reaction = discord.utils.get(updated_message.reactions, emoji="🎉")
participants = [user async for user in reaction.users() if not user.bot]
# Wähle den/die Gewinner
if not participants:
winner_text = "Niemand hat teilgenommen. 😢"
new_embed = embed.copy()
new_embed.description = f"Verlosung beendet.\n{winner_text}"
new_embed.color = discord.Color.dark_red()
await updated_message.edit(embed=new_embed)
return
chosen_winners = random.sample(participants, k=min(winners, len(participants)))
winner_mentions = ", ".join(w.mention for w in chosen_winners)
# Bearbeite die ursprüngliche Nachricht und verkünde die Gewinner
new_embed = embed.copy()
new_embed.description = f"Verlosung beendet!\n**Gewinner:** {winner_mentions}"
new_embed.color = discord.Color.green()
await updated_message.edit(embed=new_embed)
await interaction.channel.send(f"Herzlichen Glückwunsch {winner_mentions}! Ihr habt **{prize}** gewonnen!")
async def setup(bot: commands.Bot):
await bot.add_cog(Giveaways(bot))