Community-Endgame: Alpha-Keys, Bewerbungen, Events, Stats, Triggers, /remind, Social, Temp-Voice + MEE6-Bot-Karte

- Alpha-Keys: Pool im Community-Tab, Ein-Klick-Verteilung per DM an alle Playtester
  (Key bleibt frei, wenn die DM geblockt wird)
- Bewerbungs-Formulare: Builder im neuen Bewerbungen-Tab (bis 5 Fragen),
  Button → Discord-Modal → Review-Embed mit /, Rolle + DM bei Entscheidung
- Events: GuildScheduledEventCreate → Announce-Embed; öffentliche /events-Seite
  aus den Discord-Events (5-min-Cache)
- Server-Stats: activity_daily (Nachrichten/Joins/Leaves) → Balken-Chart auf /level
- Triggers (Auto-Antworten, 30s-Cooldown), /remind (DM-Scheduler),
  Twitch-Live (Helix, App-Creds write-only) + YouTube-RSS-Announcements,
  Temp-Voice (Join to Create, Cleanup bei Leerstand + Start)
- Brand-Tab: MEE6-Style Bot-Identity-Karte (Avatar-Vorschau mit Status-Dot,
  Bot-Name via setUsername, Presence online/idle/dnd, Aktivität)
- Neue Intents: GuildVoiceStates, GuildScheduledEvents; alles smoke-getestet

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-30 01:02:47 +02:00
co-authored by Claude Fable 5
parent f7b261c648
commit e72e6c8991
16 changed files with 1368 additions and 47 deletions
+26
View File
@@ -0,0 +1,26 @@
// /remind — Erinnerung per DM (z. B. /remind dauer:2h text:Server neustarten)
import { SlashCommandBuilder, MessageFlags } from 'discord.js';
import { parseDuration } from './giveaway.js';
import { createReminder } from '../../db.js';
export const data = new SlashCommandBuilder()
.setName('remind')
.setDescription('Erinnert dich per DM')
.addStringOption((o) => o.setName('dauer').setDescription('z. B. 30m, 2h, 1d').setRequired(true))
.addStringOption((o) => o.setName('text').setDescription('Woran erinnern?').setRequired(true).setMaxLength(500));
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`.', flags: MessageFlags.Ephemeral });
return;
}
const text = interaction.options.getString('text');
const remindAt = new Date(Date.now() + duration).toISOString().slice(0, 19).replace('T', ' ');
createReminder(interaction.user.id, text, remindAt);
await interaction.reply({
content: `⏰ Alles klar — ich melde mich <t:${Math.floor((Date.now() + duration) / 1000)}:R> per DM.`,
flags: MessageFlags.Ephemeral,
});
}