1 GrumpyEvents
darksoon edited this page 2026-07-11 01:05:01 +02:00
This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Events — Terminplanung mit RSVP

GrumpyEvents plant Termine mit RSVP-Buttons (Zusagen/Vielleicht/Absagen), postet eine live aktualisierte Embed-Übersicht und pingt beim Event-Start alle Zusagen automatisch.


Aktivierung

In configs/config.yml:

addons:
  events: true

Es gibt keine eigene configs/modules/events.yml — das Modul hat keine Zod-Settings-Datei und keine konfigurierbaren Parameter außer dem addons.events-Toggle selbst. Alles (Titel, Zeit, Cap, Kanal) wird pro Event über den /event create-Command festgelegt und in der Datenbank gespeichert, nicht in einer YAML-Datei.


Commands

/event create

Erstellt ein neues Event und postet die Embed-Karte mit RSVP-Buttons in den gewählten Kanal.

Option Pflicht Beschreibung
title Event-Titel (max. 256 Zeichen)
in Zeitpunkt als Dauer ab jetzt, z.B. 2h, 3d, 1d12h
description Details (max. 1000 Zeichen)
max-participants Cap auf Zusagen (Yes-RSVPs). 0/leer = unbegrenzt, 11000
channel Zielkanal (Text/Ankündigung). Standard: aktueller Kanal
/event create title:"Raid Night" in:2h
/event create title:"Community Turnier" in:3d description:"Bring deine Squad mit!" max-participants:20 channel:#events

Berechtigung: Server verwalten (Discord-Default via setDefaultMemberPermissions, zusätzlich zur Laufzeit geprüft — ein Admin kann den Discord-Default pro Rolle/Kanal überschreiben, der Runtime-Check greift trotzdem).

Das in-Format akzeptiert eine reine Zahl (= Minuten) oder Kombinationen aus Xs/Xm/Xh/Xd (z.B. 1d12h).


/event list

Listet alle kommenden (noch nicht gestarteten) Events des Servers, ephemeral. Zeigt ID, Titel, Kanal und relative Zeit.

/event list

/event cancel <id>

Storniert ein Event: löscht den DB-Eintrag und die gepostete Event-Nachricht.

Option Pflicht Beschreibung
id Event-ID (Autocomplete nach Titel/ID)
/event cancel id:12

Berechtigung: Gastgeber des Events oder Server verwalten.


RSVP-Buttons

Jede Event-Nachricht hat drei Buttons:

Button Emoji Style Bedeutung
Zusagen Success (grün) yes
Vielleicht Secondary (grau) maybe
Absagen Danger (rot) no

Klick aktualisiert die RSVP live in der Datenbank (Upsert — ein User hat immer nur einen aktuellen Status) und die öffentliche Embed-Karte wird sofort neu gerendert (Namen je Kategorie, Zähler in den Feld-Überschriften).

Cap-Verhalten (max-participants): Ist das Limit an Zusagen erreicht, wird ein weiterer yes-Klick abgelehnt ( „Das Event ist voll — keine weiteren Zusagen möglich.“), maybe/no bleiben unbeschränkt. Die Prüfung läuft in einer DB-Transaktion (Zählen + Schreiben atomar), damit bei gleichzeitigen Klicks um den letzten freien Platz niemand den Cap überbucht.

Nach Event-Start (siehe unten) sind die Buttons disabled.


Event-Start: der 1-Minuten-Runner

Ein Hintergrund-Task prüft alle 60 Sekunden, ob Events fällig sind (eventTime <= now und noch nicht gestartet):

  1. Atomares Claiming: Pro fälliger Reihe ein updateMany mit where: { started: false } — so kann ein überlappender zweiter Tick dieselbe Reihe nicht doppelt claimen, der Start-Ping kann also nicht doppelt feuern.
  2. Embed aktualisieren: Die Event-Nachricht wird neu gerendert, Buttons werden disabled.
  3. Ping der Yes-RSVPs: Alle User mit Status yes werden in einer neuen Nachricht im Event-Kanal gepingt: „📅 {Titel} beginnt jetzt! @User1 @User2 …“. Gibt es keine Zusagen, wird trotzdem eine Nachricht ohne Mentions gepostet.

Mention-Limit: Discord erlaubt maximal 100 Einträge in allowed_mentions.users pro Nachricht — bei mehr Zusagen wird die Liste in mehrere Nachrichten zu je 100 Pings aufgeteilt, damit niemand stillschweigend übergangen wird.


Embed-Aufbau

📅 <Titel>

<Beschreibung, falls gesetzt>

✅ Zusagen (N/Cap)     ❔ Unsicher (N)     ❌ Absagen (N)
@User1, @User2 …       @User3 …            @User4 …

Wann
<Datum/Uhrzeit> (<relative Zeit>)

Gastgeber
@Host

Klicke unten, um zu antworten

Farbe: #5865F2 (Discord Blurple). Bei gesetztem Cap steht /<max-participants> neben der Zusagen-Anzahl.


Besonderheiten

  • Storno-Reihenfolge: Beim /event cancel wird die Berechtigung vor dem Löschen geprüft (nicht löschen-dann-zurückrollen), damit im Ablehnungsfall nie versehentlich ein zweiter DB-Eintrag mit anderer ID entsteht, an den die alten RSVP-Buttons (gebunden an die ursprüngliche ID) nicht mehr passen würden.
  • Events werden per Prisma/DB gespeichert (Event, EventRsvp) — kein In-Memory-State, überlebt Neustarts.
  • Schlägt das initiale Posten der Event-Nachricht fehl (z.B. fehlende Berechtigungen), bricht /event create mit Fehlermeldung ab, ohne den DB-Eintrag zu löschen — der Event-Eintrag existiert dann ohne messageId.