// Text-Vorlagen: eine Stelle, an der alle Nachrichten stehen, die der Bot // nach außen schreibt — Begrüßungen, Bestätigungen, Direktnachrichten. // // Jede Vorlage hat einen Standardtext. Wird sie im Webinterface geändert, // landet die Fassung als Einstellung `tpl_` in der Datenbank; ein leerer // Wert bedeutet „wieder der Standard". So bleibt der Code die Quelle für den // Standard und die Datenbank enthält nur echte Abweichungen. // // Platzhalter sind `{name}`. Unbekannte Namen bleiben unverändert stehen, // damit ein Tippfehler in der Nachricht sichtbar wird statt still zu // verschwinden. import { getSetting, setSetting } from './db.js'; export const TEMPLATE_GROUPS = [ { id: 'willkommen', label: 'Ankommen & Community' }, { id: 'support', label: 'Support & Bewerbung' }, { id: 'spass', label: 'Verlosung, Geburtstag & Level' }, { id: 'sonstiges', label: 'Sonstiges' }, ]; /** Platzhalter, die es in fast jeder Vorlage gibt */ const WHO = [ { key: 'user', desc: 'Anzeigename' }, { key: 'mention', desc: 'Erwähnung (@Name)' }, ]; export const TEMPLATES = [ /* ── Ankommen & Community ─────────────────────────── */ { id: 'welcome.title', group: 'willkommen', module: 'welcome', name: 'Willkommen — Überschrift', vars: [...WHO, { key: 'server', desc: 'Servername' }, { key: 'count', desc: 'Mitglieder-Nummer' }], default: '👋 Willkommen, {user}!', }, { id: 'welcome.text', group: 'willkommen', module: 'welcome', name: 'Willkommen — Text', long: true, vars: [...WHO, { key: 'server', desc: 'Servername' }, { key: 'count', desc: 'Mitglieder-Nummer' }, { key: 'url', desc: 'Adresse der Webseite' }], default: 'Schön, dass du da bist — du bist Mitglied **#{count}**.\n\n' + '📔 Devlogs & Roadmap: {url}\n' + '🧪 Playtester werden? Schau nach dem Bewerbungs-Post!\n' + '🐛 Bug gefunden? Einfach `/bug` benutzen.', }, { id: 'playtester.joined', group: 'willkommen', module: 'playtester', name: 'Playtester — angemeldet', long: true, vars: WHO, default: '🧪 **Willkommen im Playtest-Team!** Du stehst auf der Liste — sobald es losgeht, meldet sich der Bot per DM.', }, { id: 'playtester.left', group: 'willkommen', module: 'playtester', name: 'Playtester — abgemeldet', vars: WHO, default: '🚪 Von der Playtester-Liste **abgemeldet**.', }, { id: 'tempvoice.title', group: 'willkommen', module: 'temp_voice', name: 'Sprachkanal — Überschrift', vars: WHO, default: '🔊 Dein Kanal', }, { id: 'tempvoice.text', group: 'willkommen', module: 'temp_voice', name: 'Sprachkanal — Text', long: true, vars: WHO, default: '{mention}, das hier ist dein temporärer Voice-Kanal — er verschwindet automatisch, wenn alle raus sind. Steuern kannst du ihn hier:', }, /* ── Support & Bewerbung ──────────────────────────── */ { id: 'ticket.panel_title', group: 'support', module: 'tickets', name: 'Ticket-Post — Überschrift', vars: [], default: '🎫 Support-Ticket', }, { id: 'ticket.panel_text', group: 'support', module: 'tickets', name: 'Ticket-Post — Text', long: true, vars: [], default: 'Du hast eine Frage, ein Problem oder ein privates Anliegen?\n\n' + 'Klick auf den Button — es öffnet sich ein **privater Thread**, den nur du und das Team sehen können.', }, { id: 'ticket.opened', group: 'support', module: 'tickets', name: 'Ticket — Begrüßung im Thread', long: true, vars: WHO, default: 'Willkommen in deinem Ticket! Beschreib dein Anliegen — das Team meldet sich.\n' + 'Wenn alles geklärt ist, kann das Ticket hier geschlossen werden.', }, { id: 'ticket.closed_dm', group: 'support', module: 'tickets', name: 'Ticket — Direktnachricht beim Schließen', long: true, vars: [{ key: 'ticket', desc: 'Name des Tickets' }, { key: 'closedBy', desc: 'wer geschlossen hat' }], default: '🔒 Dein Ticket **{ticket}** wurde geschlossen — hier dein Transcript. Danke für deine Anfrage!', }, { id: 'modmail.thread_intro', group: 'support', module: 'modmail', name: 'Modmail — Kopf des Staff-Threads', long: true, vars: WHO, default: 'Neue Modmail-Konversation mit **{user}** ({mention}).\n' + 'Antworten in diesem Thread gehen als DM an den User.', }, { id: 'application.submitted', group: 'support', module: 'applications', name: 'Bewerbung — Bestätigung', long: true, vars: [...WHO, { key: 'form', desc: 'Name des Formulars' }], default: '✅ Bewerbung eingereicht — danke! Du bekommst eine DM, sobald sie geprüft wurde.', }, { id: 'application.approved', group: 'support', module: 'applications', name: 'Bewerbung — angenommen', long: true, vars: [...WHO, { key: 'form', desc: 'Name des Formulars' }], default: '✅ Deine Bewerbung **„{form}"** wurde angenommen — willkommen! 🎉', }, { id: 'application.denied', group: 'support', module: 'applications', name: 'Bewerbung — abgelehnt', long: true, vars: [...WHO, { key: 'form', desc: 'Name des Formulars' }], default: '❌ Deine Bewerbung **„{form}"** wurde leider abgelehnt.', }, /* ── Verlosung, Geburtstag & Level ────────────────── */ { id: 'giveaway.winner', group: 'spass', module: 'giveaways', name: 'Verlosung — Gewinner', long: true, vars: [ { key: 'prize', desc: 'Gewinn' }, { key: 'winners', desc: 'Erwähnungen der Gewinner' }, { key: 'entries', desc: 'Anzahl Teilnahmen' }, ], default: '🎉 **{prize}** geht an: {winners} — Glückwunsch! 🏆', }, { id: 'giveaway.empty', group: 'spass', module: 'giveaways', name: 'Verlosung — keine Teilnahmen', vars: [{ key: 'prize', desc: 'Gewinn' }], default: 'Keine Teilnahmen — niemand hat gewonnen. 😢', }, { id: 'giveaway.reroll', group: 'spass', module: 'giveaways', name: 'Verlosung — neu ausgelost', long: true, vars: [{ key: 'prize', desc: 'Gewinn' }, { key: 'winners', desc: 'Erwähnung des Gewinners' }], default: '🔁 Neu ausgelost: **{prize}** geht jetzt an {winners} — Glückwunsch! 🏆', }, { id: 'birthday.title', group: 'spass', module: 'birthdays', name: 'Geburtstag — Überschrift', vars: [{ key: 'count', desc: 'Anzahl Geburtstagskinder' }], default: '🎂 Alles Gute zum Geburtstag!', }, { id: 'birthday.title_multi', group: 'spass', module: 'birthdays', name: 'Geburtstag — Überschrift (mehrere)', vars: [{ key: 'count', desc: 'Anzahl Geburtstagskinder' }], default: '🎂 Heute wird gleich mehrfach gefeiert!', }, { id: 'birthday.text', group: 'spass', module: 'birthdays', name: 'Geburtstag — Text', long: true, vars: [{ key: 'mentions', desc: 'Erwähnungen' }, { key: 'count', desc: 'Anzahl' }], default: '{mentions} hat heute Geburtstag — lasst mal ordentlich 🎉 da!', }, { id: 'birthday.text_multi', group: 'spass', module: 'birthdays', name: 'Geburtstag — Text (mehrere)', long: true, vars: [{ key: 'mentions', desc: 'Erwähnungen' }, { key: 'count', desc: 'Anzahl' }], default: '{mentions} haben heute Geburtstag — lasst mal ordentlich 🎉 da!', }, { id: 'level.up', group: 'spass', module: 'levels', name: 'Level-Aufstieg', long: true, vars: [...WHO, { key: 'level', desc: 'neues Level' }, { key: 'xp', desc: 'Gesamt-XP' }], default: '🎉 **{user}** ist jetzt **Level {level}**!', }, /* ── Sonstiges ────────────────────────────────────── */ { id: 'reminder.dm', group: 'sonstiges', module: 'reminders', name: 'Erinnerung', long: true, vars: [...WHO, { key: 'text', desc: 'der erinnerte Text' }], default: '⏰ **Erinnerung:** {text}', }, { id: 'wish.submitted', group: 'sonstiges', module: 'voting', name: 'Feature-Wunsch — Bestätigung', long: true, vars: [...WHO, { key: 'url', desc: 'Link zum Voting-Post' }], default: '✅ Wunsch eingereicht — [zur Abstimmung]({url})!', }, { id: 'bug.submitted', group: 'sonstiges', module: 'bug_reports', name: 'Fehlermeldung — Bestätigung', long: true, vars: [ ...WHO, { key: 'number', desc: 'Nummer des Issues' }, { key: 'url', desc: 'Link zum Issue' }, { key: 'title', desc: 'Titel der Meldung' }, ], default: '✅ Danke! Dein Bug ist erfasst als [#{number}]({url}) — du bekommst eine DM, sobald er behoben ist.', }, { id: 'playtester.panel_title', group: 'sonstiges', module: 'playtester', name: 'Playtester-Post — Überschrift', vars: [], default: '🧪 Playtester werden', }, { id: 'playtester.panel_text', group: 'sonstiges', module: 'playtester', name: 'Playtester-Post — Text', long: true, vars: [], default: 'Du willst **EcoGame** vor allen anderen spielen und mit deinem Feedback die Entwicklung mitgestalten?\n\n' + 'Ein Klick auf den Button setzt dich auf die Playtester-Liste — sobald die Alpha startet, ' + 'bekommst du deinen Zugang direkt per DM. Abmelden geht jederzeit mit einem zweiten Klick.', }, ]; const byId = new Map(TEMPLATES.map((t) => [t.id, t])); /** Standardtext einer Vorlage */ export function templateDefault(id) { return byId.get(id)?.default ?? ''; } /** Aktueller Rohtext — eigene Fassung, sonst der Standard */ export function getTemplate(id) { const custom = getSetting(`tpl_${id}`); return custom?.trim() ? custom : templateDefault(id); } /** Eigene Fassung setzen. Leerer Text stellt den Standard wieder her. */ export function setTemplate(id, text) { if (!byId.has(id)) return false; setSetting(`tpl_${id}`, String(text ?? '').trim()); return true; } /** Platzhalter ersetzen — Unbekanntes bleibt stehen */ export function fillPlaceholders(text, vars = {}) { return String(text).replace(/\{(\w+)\}/g, (match, key) => Object.hasOwn(vars, key) ? String(vars[key] ?? '') : match ); } /** * Vorlage rendern. * @param {string} id * @param {Record} vars */ export function renderTemplate(id, vars = {}) { return fillPlaceholders(getTemplate(id), vars); } /** Alle Vorlagen mit Zustand — fürs Webinterface */ export function templateStates() { return TEMPLATES.map((t) => { const custom = getSetting(`tpl_${t.id}`); return { id: t.id, name: t.name, group: t.group, module: t.module ?? null, long: Boolean(t.long), vars: t.vars ?? [], default: t.default, text: custom?.trim() ? custom : t.default, customized: Boolean(custom?.trim()), }; }); }