// /giveaway โ€” Verlosung starten (Admin): ๐ŸŽ‰-Button zum Teilnehmen, automatische Ziehung import { SlashCommandBuilder, PermissionFlagsBits, MessageFlags, ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder, } from 'discord.js'; import { saveGiveaway } from '../../db.js'; import { brandColor, brandFooter } from '../../runtime-settings.js'; /** "30m" / "2h" / "1d" โ†’ Millisekunden (null bei Unsinn) */ export function parseDuration(input) { const m = String(input).trim().match(/^(\d+)\s*(m|h|d)$/i); if (!m) return null; const factor = { m: 60_000, h: 3_600_000, d: 86_400_000 }[m[2].toLowerCase()]; const ms = Number(m[1]) * factor; return ms >= 60_000 && ms <= 30 * 86_400_000 ? ms : null; } export const data = new SlashCommandBuilder() .setName('giveaway') .setDescription('Verlosung in diesem Kanal starten') .setDefaultMemberPermissions(PermissionFlagsBits.Administrator) .addStringOption((o) => o.setName('preis').setDescription('Was gibt es zu gewinnen?').setRequired(true).setMaxLength(200)) .addStringOption((o) => o.setName('dauer').setDescription('z. B. 30m, 2h, 1d').setRequired(true)) .addIntegerOption((o) => o.setName('gewinner').setDescription('Anzahl Gewinner (Default 1)').setMinValue(1).setMaxValue(20)); export async function execute(interaction) { const duration = parseDuration(interaction.options.getString('dauer')); if (!duration) { await interaction.reply({ content: 'โŒ Dauer bitte als `30m`, `2h` oder `1d` (1 Minute bis 30 Tage).', flags: MessageFlags.Ephemeral, }); return; } const prize = interaction.options.getString('preis'); const winners = interaction.options.getInteger('gewinner') ?? 1; const endsAt = new Date(Date.now() + duration); const embed = new EmbedBuilder() .setColor(brandColor()) .setTitle(`๐ŸŽ‰ Giveaway: ${prize}`) .setDescription( `Klick auf den Button zum Teilnehmen!\n\n` + `๐Ÿ† **${winners}** Gewinner ยท โฐ Ziehung ` ) .setFooter({ text: brandFooter('GIVEAWAY') }) .setTimestamp(endsAt); const row = new ActionRowBuilder().addComponents( new ButtonBuilder().setCustomId('giveaway_enter').setStyle(ButtonStyle.Primary).setLabel('Teilnehmen').setEmoji('๐ŸŽ‰') ); const message = await interaction.channel.send({ embeds: [embed], components: [row] }); saveGiveaway({ message_id: message.id, channel_id: message.channelId, prize, winners, // SQLite vergleicht mit datetime('now') im UTC-Format ends_at: endsAt.toISOString().slice(0, 19).replace('T', ' '), }); await interaction.reply({ content: 'โœ… Giveaway gestartet!', flags: MessageFlags.Ephemeral }); }