Umfragen: /umfrage als native Discord-Abstimmung
Deploy / check (push) Has been cancelled
Deploy / deploy (push) Has been cancelled

Bewusst Discords eigenes Poll-Objekt statt einer Nachbildung mit Knoepfen —
Oberflaeche, Auszaehlen und Ergebnisanzeige macht Discord dann selbst, auch
auf dem Handy. Wir bauen nur die Frage zusammen.

Bis zu vier Antworten (Discord erlaubt zehn, vier halten den Befehl
uebersichtlich), Laufzeit von einer Stunde bis einer Woche, Mehrfachauswahl
optional. Rechte: ManageMessages.

Zwei gleiche Antworten werden abgefangen. Discord stoert das nicht, aber
abstimmen kann darauf niemand sinnvoll.

Nicht zu verwechseln mit /wunsch: das sammelt Feature-Wuensche dauerhaft und
zeigt sie auf der Roadmap. /umfrage ist die schnelle Frage zwischendurch und
laeuft von selbst ab. Steht so auch als Kommentar im Befehl.

Geprueft gegen die installierte discord.js-Fassung (14.27) statt gegen die
Dokumentation: Feldnamen aus den Typdefinitionen gelesen, und die fertige
Nutzlast durch discord.js' eigene Serialisierung gejagt. Kommt als
poll_media / allow_multiselect / layout_type 1 raus, genau wie Discords API
es erwartet.

Dazu: 18 Befehle laden ohne Namenskollision, Befehl steht auf der
oeffentlichen Liste in beiden Sprachen, Zahl auf der Produktseite von 17
auf 18.

Nutzungsbedingungen als Entwurf unter docs/ — Text fuer den Seiten-Editor,
keine Rechtsberatung.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-01 06:34:04 +02:00
co-authored by Claude Fable 5
parent 52a735f83a
commit c8b1f604f0
9 changed files with 186 additions and 3 deletions
+2 -1
View File
@@ -40,12 +40,13 @@ import * as tag from './commands/tag.js';
import * as remind from './commands/remind.js';
import * as geburtstag from './commands/geburtstag.js';
import * as raid from './commands/raid.js';
import * as umfrage from './commands/umfrage.js';
// Alle Commands hier eintragen — jedes Modul exportiert { data, execute }
const commandModules = [
ping, devlogBackfill, bug, playtesterSetup, galerieBackfill,
wunsch, giveaway, ticketSetup, warn, warns, timeout, purge, rank, tag, remind, geburtstag,
raid,
raid, umfrage,
];
export async function startBot() {
+87
View File
@@ -0,0 +1,87 @@
// /umfrage — native Discord-Umfrage starten.
//
// Bewusst Discords eigenes Poll-Objekt statt einer Nachbildung mit Knöpfen:
// die Oberfläche, das Auszählen und die Ergebnisanzeige macht Discord dann
// selbst, auch auf dem Handy. Wir bauen nur die Frage zusammen.
//
// Nicht zu verwechseln mit /wunsch — das sammelt Feature-Wünsche dauerhaft
// und zeigt sie auf der Roadmap. Diese hier ist für die schnelle Frage
// zwischendurch und läuft nach der eingestellten Zeit von selbst ab.
import { SlashCommandBuilder, PermissionFlagsBits, MessageFlags, PollLayoutType } from 'discord.js';
import { moduleEnabled } from '../../modules.js';
// Discord erlaubt bis zu 10 Antworten; vier reichen für den Alltag und halten
// den Befehl übersichtlich. Die ersten beiden sind Pflicht.
const ANTWORT_FELDER = ['a', 'b', 'c', 'd'];
const DAUER = [
{ name: '1 Stunde', value: 1 },
{ name: '4 Stunden', value: 4 },
{ name: '1 Tag', value: 24 },
{ name: '3 Tage', value: 72 },
{ name: '1 Woche', value: 168 },
];
export const data = new SlashCommandBuilder()
.setName('umfrage')
.setDescription('Startet eine Umfrage in diesem Kanal')
.setDefaultMemberPermissions(PermissionFlagsBits.ManageMessages)
.addStringOption((o) => o.setName('frage').setDescription('Worum geht es?').setRequired(true).setMaxLength(300))
.addStringOption((o) => o.setName('a').setDescription('Erste Antwort').setRequired(true).setMaxLength(55))
.addStringOption((o) => o.setName('b').setDescription('Zweite Antwort').setRequired(true).setMaxLength(55))
.addStringOption((o) => o.setName('c').setDescription('Dritte Antwort').setMaxLength(55))
.addStringOption((o) => o.setName('d').setDescription('Vierte Antwort').setMaxLength(55))
.addIntegerOption((o) => o.setName('dauer').setDescription('Wie lange offen? (Standard: 1 Tag)').addChoices(...DAUER))
.addBooleanOption((o) => o.setName('mehrfach').setDescription('Mehrere Antworten erlaubt? (Standard: nein)'));
export async function execute(interaction) {
if (!moduleEnabled('polls')) {
await interaction.reply({
content: '❌ Umfragen sind ausgeschaltet — im Panel unter **Community** einschaltbar.',
flags: MessageFlags.Ephemeral,
});
return;
}
const frage = interaction.options.getString('frage').trim();
const antworten = ANTWORT_FELDER
.map((feld) => interaction.options.getString(feld)?.trim())
.filter(Boolean)
.map((text) => ({ text }));
// Zwei gleiche Antworten sind kein Fehler für Discord, aber Unsinn für die
// Auswertung — hier abfangen statt eine kaputte Umfrage zu posten.
const einmalig = new Set(antworten.map((a) => a.text.toLowerCase()));
if (einmalig.size !== antworten.length) {
await interaction.reply({
content: '❌ Zwei Antworten sind gleich — dann kann niemand sinnvoll abstimmen.',
flags: MessageFlags.Ephemeral,
});
return;
}
try {
await interaction.channel.send({
poll: {
question: { text: frage },
answers: antworten,
duration: interaction.options.getInteger('dauer') ?? 24,
allowMultiselect: interaction.options.getBoolean('mehrfach') ?? false,
layoutType: PollLayoutType.Default,
},
});
} catch (error) {
console.error('[umfrage]', error);
await interaction.reply({
content: '❌ Umfrage konnte nicht gepostet werden — darf der Bot hier schreiben?',
flags: MessageFlags.Ephemeral,
});
return;
}
// Die Umfrage selbst ist die sichtbare Antwort; die Bestätigung bleibt still
await interaction.reply({
content: `✅ Umfrage läuft — ${antworten.length} Antworten.`,
flags: MessageFlags.Ephemeral,
});
}