103 lines
3.9 KiB
Python
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)) |