Zum Hauptinhalt springen

Discord Ticket Bot einrichten

Discord Ticket Bot

Ein moderner Discord Ticket Bot zum Selbsthosten, gebaut auf Discord.js v14. SQLite ist von Haus aus dabei, eine externe Datenbank brauchst du also nicht. MySQL/MariaDB und PostgreSQL gehen optional trotzdem. Keine Telemetrie, voller Funktionsumfang ab der ersten Minute.

Lizenz: AGPL-3.0 · Node.js 24+ · Discord.js v14

Du willst erst den Überblick? Die Seite Discord Ticket Bot zum Selbsthosten auf msk-scripts.de geht die Funktionen, die Transkript-Stufen und den Verifizierungsablauf durch.

Noch unentschlossen? Der Vergleich der Discord Ticket Bots stellt diesen Bot neben Discord Tickets, Sayrix Ticket-Bot und das gehostete Ticket Tool, inklusive der Fälle, in denen ein anderes Projekt besser passt.

Wenn du direkt loslegen willst, geht es auf der Seite Discord Ticket Bot installieren weiter.


✨ Funktionen

FunktionBeschreibung
🎫 Ticket-TypenBis zu 25 konfigurierbare Typen mit eigenem Emoji, eigener Farbe, Kategorie und eigenen Fragen
📋 FragebögenModal-Formulare mit bis zu 5 Fragen, die beim Öffnen eines Tickets erscheinen
🙋 Claim-SystemDas Team kann Tickets übernehmen und wieder abgeben. Der Button schaltet um, Embed und Kanalthema aktualisieren sich von selbst
🔴 PrioritätenNiedrig, Mittel, Hoch, Dringend. Pro Ticket-Typ vorgegeben oder per /priority gesetzt, sichtbar im Kanalthema und im Embed
📝 Team-NotizenInterne Notizen über /note add und /note list
🔀 Ticket verschiebenPer /move oder Button in einen anderen Typ bzw. eine andere Kategorie verschieben, nur für das Team
🛡️ Rollen je Ticket-TypJeder Ticket-Typ kann eigene Team-Rollen festlegen
🖼️ Panel-Logo und BannerOptionales Logo als Thumbnail und/oder ein Bannerbild im Panel-Embed
🎛️ Panel-InteraktionWahlweise ein Button oder direkt ein Auswahlmenü im Panel
⭐ BewertungssystemBewertung von 1 bis 5 Sternen nach dem Schließen, automatisch in einen festgelegten Kanal gepostet
⏰ Team-ErinnerungAutomatischer Ping im Ticket, wenn sich nach X Stunden niemand aus dem Team gemeldet hat
⏰ Auto-CloseInaktive Tickets schließen sich automatisch, mit einstellbarer Vorwarnzeit
♻️ Tickets wieder öffnenEin geschlossenes Ticket über den ♻️-Button oder /reopen erneut öffnen. Zugriff und Kategorie werden wiederhergestellt
🔗 Transkript-LinksTranskripte liegen online und sind über einen öffentlichen Link erreichbar
📄 HTML-TranskriptIn sich geschlossenes HTML-Transkript, modern oder klassisch. Avatare und eigene Emojis stecken als Base64 mit drin, Erwähnungen sowie Erstellt-, Übernommen- und Geschlossen-von erscheinen als Namen. Kein CDN nötig
🌐 Eigene DomainPremium-Kunden liefern Transkripte unter ihrer eigenen Domain aus
📊 StatistikenServerweite Statistiken und detaillierte Nutzerstatistiken über /stats
🚫 Blacklist/blacklist add/remove/list sperrt Nutzer für das Öffnen von Tickets
💬 TextbausteineVorformulierte Antworten mit einem Befehl, konfiguriert in snippets.jsonc
🔒 Ticket sperrenTicket sperren und entsperren, damit der Nutzer keine Nachrichten mehr schreiben kann
📢 RundnachrichtEine Nachricht auf einmal in alle offenen Ticket-Kanäle schicken
🔔 BenachrichtigungenOptionale DM an den Nutzer, sobald jemand aus dem Team antwortet
🎮 Dynamischer Bot-StatusZeigt die Anzahl der offenen Tickets automatisch im Bot-Status an
🌍 Mehrsprachig7 Sprachen enthalten (Englisch, Deutsch, Französisch, Spanisch, Portugiesisch, Polnisch, Ungarisch), leicht erweiterbar
🗄️ Flexible DatenbankSQLite ohne jede Einrichtung. Optional MySQL/MariaDB oder PostgreSQL über DATABASE_URL, inklusive Migrationsskript
🔄 Update-PrüfungPrüft beim Start auf neue GitHub-Releases und meldet sich mit einer Update-Anleitung
🖥️ Web-DashboardOptionales, selbst gehostetes Dashboard im Browser (standardmäßig aus): Tickets, Statistiken, ein Editor für Konfiguration und Dateien, Bot-Steuerung und Rechte je Rolle oder Nutzer. Siehe Web-Dashboard.

🔗 MSK Transcript Service

Statt Transkripte als Dateianhang per DM zu verschicken, kann der Bot sie zu www.msk-scripts.de hochladen und daraus einen öffentlichen Link erzeugen. Der lässt sich in jedem Browser öffnen, ganz ohne Download.

Es gibt vier Stufen: Basic (kostenlos), Premium (3,99 € im Monat), Premium+ (6,99 € im Monat) und Business (9,99 € im Monat). Die bezahlten Stufen bringen größere Transkripte samt Dateianhängen, längere Speicherdauer, eine eigene Domain, das Recht den MSK-Hinweis zu entfernen und die Bot-Verwaltung im Hosting. Abgeschlossen wird über Stripe, mit 14 Tagen kostenlos und ohne Kreditkarte.

Für den Start holst du dir deinen API-Key unter www.msk-scripts.de/ticketbot/verify (mit Discord anmelden, Server auswählen) und trägst ihn in die .env ein:

MSK_API_KEY='dein_api_key'
MSK_API_URL="https://www.msk-scripts.de"

📖 Alles im Detail (Stufenvergleich, API-Key, eigene Domain, Stripe): Service Setup


🖥️ Gehostete Bot-Verwaltung (Premium und Premium+)

Wer Premium oder Premium+ nutzt, kann seine Bot-Instanz komplett von MSK Scripts hosten lassen und sie vollständig über das Dashboard unter msk-scripts.de/ticketbot/dashboard verwalten: starten, stoppen, neu starten, aktualisieren, dazu eine Live-Log-Konsole und ein Klick zum eigenen Web-Dashboard des Bots. SSH-Zugang oder Serverkenntnisse brauchst du dafür nicht.

Dashboard, gehostete Bot-Verwaltung

Melde dich über Discord bei MSK Scripts, um das Hosting zu vereinbaren. Sobald es eingerichtet ist, taucht die Verwaltung nach dem Login automatisch in deinem Dashboard auf.

📖 Details: Service Setup, gehostete Bot-Verwaltung


🖥️ Selbst gehostetes Web-Dashboard

Du betreibst den Bot selbst? Das optionale Web-Dashboard verwaltet Tickets, Statistiken, die Konfiguration und den Bot-Prozess im Browser, mit einem Rechtemodell für dein Team. Es ist standardmäßig abgeschaltet und ab Werk sicher konfiguriert.

Einrichtung, Absicherung und das vollständige Rechtemodell stehen auf der eigenen Seite Web-Dashboard.


📁 Projektstruktur

discord_ticketbot/
├── index.js # Einstiegspunkt
├── package.json
├── .env.example # Vorlage für die Umgebungsvariablen
├── ticketbot.service # systemd-Unit für Linux-Server
├── assets/ # Statische Dateien (Logo, Banner)
│ ├── logo.png # Logo-Thumbnail im Panel (eigenes hier ablegen)
│ └── banner.png # Bannerbild im Panel (eigenes hier ablegen)
├── config/
│ ├── config.example.jsonc # Konfigurationsvorlage (kommentiert)
│ └── snippets.example.jsonc # Vorlage für Textbausteine
├── docs/
│ ├── setup-en.md # Anleitung zum MSK Transcript Service (englisch)
│ └── setup-de.md # Anleitung zum MSK Transcript Service (deutsch)
├── locales/ # 7 Sprachen + main.json (englische Vorlage)
│ ├── en.json # Englisch
│ ├── de.json # Deutsch
│ └── … # fr, es, pt, pl, hu
├── scripts/
│ └── migrate-db.js # npm run db:migrate, SQLite nach MySQL/PostgreSQL
├── data/
│ └── tickets.db # SQLite-Datenbank (wird angelegt, Standard-Backend)
└── src/
├── client.js # Erweiterter Discord-Client
├── config.js # Laden und Prüfen der Konfiguration
├── database/ # Datenbankschicht für SQLite, MySQL und PostgreSQL
│ ├── index.js # Öffentliche async-API und alle Queries
│ ├── url.js # DATABASE_URL auswerten, Treiber wählen
│ ├── schema.js # Schema und Migrationen je Dialekt
│ └── drivers/ # sqlite.js / mysql.js / postgres.js
├── handlers/
│ ├── commandHandler.js # Lädt und registriert die Slash-Befehle
│ ├── eventHandler.js # Lädt die Discord-Events
│ └── componentHandler.js # Lädt Buttons, Modals und Menüs
├── commands/ # Slash-Befehle
│ ├── setup.js # /setup – Panel senden
│ ├── close.js # /close – Ticket schließen
│ ├── reopen.js # /reopen – Ticket wieder öffnen
│ ├── add.js # /add – Nutzer hinzufügen
│ ├── remove.js # /remove – Nutzer entfernen
│ ├── claim.js # /claim – Ticket übernehmen
│ ├── unclaim.js # /unclaim – Ticket abgeben
│ ├── move.js # /move – Ticket verschieben
│ ├── rename.js # /rename – Kanal umbenennen
│ ├── transcript.js # /transcript – HTML-Transkript erzeugen
│ ├── priority.js # /priority – Priorität setzen
│ ├── note.js # /note – Team-Notizen
│ ├── blacklist.js # /blacklist – Nutzer sperren
│ ├── stats.js # /stats – Statistiken
│ ├── snippet.js # /snippet – Textbausteine senden
│ ├── broadcast.js # /broadcast – An alle offenen Tickets
│ ├── lock.js # /lock – Ticket sperren/entsperren
│ └── autoclose.js # /autoclose – Inaktivität pausieren/fortsetzen
├── events/
│ ├── ready.js # Start, Status, Auto-Close und Team-Erinnerung
│ ├── messageCreate.js # Aktivität verfolgen und DM-Benachrichtigungen
│ └── interactionCreate.js # Alle Interaktionen verteilen
├── components/
│ ├── buttons/
│ │ ├── openTicket.js # tb_open
│ │ ├── closeTicket.js # tb_close
│ │ ├── claimTicket.js # tb_claim
│ │ ├── unclaimTicket.js # tb_unclaim
│ │ ├── moveTicket.js # tb_move
│ │ ├── deleteTicket.js # tb_delete
│ │ ├── deleteConfirm.js # tb_deleteConfirm
│ │ ├── deleteCancel.js # tb_deleteCancel
│ │ ├── reopenTicket.js # tb_reopen
│ │ ├── rateTicket.js # tb_rate:N:id
│ │ └── notifyToggle.js # tb_notifyToggle
│ ├── modals/
│ │ ├── closeReason.js # tb_modalClose
│ │ ├── ticketQuestions.js # tb_modalQuestions:type
│ │ └── rateComment.js # tb_modalRate:N:id
│ └── menus/
│ ├── panelSelect.js # tb_panelSelect
│ ├── ticketType.js # tb_selectType
│ └── moveSelect.js # tb_moveSelect
└── utils/
├── logger.js # Farbiger Konsolen-Logger
├── embeds.js # Alle Embed-Konstruktoren
├── transcript.js # Eigenständiges HTML, Avatare als Base64
├── mskApi.js # API-Client für den MSK Transcript Service
├── ticketActions.js # Kernlogik: openTicket, performClose, performReopen, performMove
├── versionCheck.js # Update-Prüfung beim Start gegen GitHub-Releases
└── snippets.js # Lader und Platzhalter-Engine für Textbausteine

⚙️ Slash-Befehle

BefehlBerechtigungBeschreibung
/setupAdministratorDas Ticket-Panel senden
/close [Grund]KonfigurierbarDas aktuelle Ticket schließen
/reopenKonfigurierbarEin geschlossenes Ticket wieder öffnen, Zugriff und Kategorie zurück
/claimTeamTicket übernehmen, Kanalthema und Embed aktualisieren sich
/unclaimTeamÜbernommenes Ticket wieder abgeben
/moveTeamTicket in einen anderen Typ oder eine andere Kategorie verschieben
/add <Nutzer>TeamEinen Nutzer zum Ticket hinzufügen
/remove <Nutzer>TeamEinen Nutzer aus dem Ticket entfernen
/rename <Name>TeamDen Ticket-Kanal umbenennen
/transcriptTeamEin HTML-Transkript erzeugen
/priority <Stufe>TeamPriorität setzen, aktualisiert Kanalthema und Embed
/note add <Text>TeamEine Team-Notiz anlegen
/note listTeamAlle Notizen zu diesem Ticket anzeigen
/statsTeamServerweite Ticket-Statistiken
/stats @NutzerTeamDetaillierte Statistiken zu einem Nutzer
/blacklist addServer verwaltenEinen Nutzer sperren
/blacklist removeServer verwaltenEine Sperre aufheben
/blacklist listServer verwaltenDie Blacklist anzeigen
/snippet send <Name>TeamEinen Textbaustein ins Ticket schicken
/snippet listTeamAlle verfügbaren Textbausteine anzeigen
/lock lock [Grund]TeamTicket sperren, der Nutzer kann nicht mehr schreiben
/lock unlockTeamTicket entsperren
/autoclose pauseTeamInaktivitätswarnung, Auto-Close und Team-Erinnerung pausieren
/autoclose resumeTeamDie normalen Inaktivitätsregeln wieder aufnehmen
/broadcast <Text>TeamEine Nachricht an alle offenen Ticket-Kanäle senden

🔘 Ticket-Buttons

In jedem Ticket-Kanal steht oben eine Button-Reihe:

ButtonSichtbar wennBeschreibung
🔒 SchließenImmer (konfigurierbar)Deaktiviert alle Buttons, erzeugt das Transkript, schließt und benennt den Kanal um
🙋 ÜbernehmenclaimButton: true, noch nicht übernommenDas Team übernimmt, Kanalthema und Embed aktualisieren sich
🙌 AbgebenclaimButton: true, bereits übernommenDas Team gibt wieder ab, Kanalthema und Embed aktualisieren sich
🔀 VerschiebenMehr als 1 Ticket-Typ konfiguriertÖffnet die Typauswahl, nur für das Team
🗑️ LöschenNach dem SchließenLöscht den Kanal nach einer Rückfrage
♻️ Wieder öffnenNach dem Schließen (reopenOption.enabled)Öffnet das Ticket erneut und schiebt es zurück in seine Kategorie
🔕 BenachrichtigenuserNotifications.enabled: trueDer Nutzer aktiviert DMs, sobald das Team antwortet

🗄️ Datenbankschema

Die Datenbank wird automatisch angelegt. Standardmäßig ist das eine lokale SQLite-Datei (data/tickets.db). Setzt du DATABASE_URL, nutzt der Bot stattdessen MySQL/MariaDB oder PostgreSQL, siehe Datenbank. Schema und Migrationen sind für jedes Backend gleich, fehlende Spalten kommen beim Start automatisch dazu.

TabelleInhalt
ticketsAlle Tickets: Status, Typ, Priorität, Claim, Sperre, Benachrichtigung, Erinnerung, Transkript
blacklistGesperrte Nutzer mit Grund und Zeitstempel
staff_notesInterne Team-Notizen je Ticket
ratingsBewertungen (1 bis 5 ⭐) mit optionalem Kommentar
panel_messagesFundort der /setup-Panel-Nachricht, für die Auffrischung beim Start

Spalten aus den letzten Updates:

SpalteStandardZweck
locked0Ob das Ticket gerade gesperrt ist
notify_on_reply0Ob der Ersteller DM-Benachrichtigungen aktiviert hat
last_notify_sentNULLZeitstempel der letzten Benachrichtigung (30 Minuten Sperrzeit)

🌍 Eine neue Sprache ergänzen

Sieben Sprachen liegen bei: Englisch, Deutsch, Französisch, Spanisch, Portugiesisch, Polnisch und Ungarisch (locales/en.json, de.json, fr.json, es.json, pt.json, pl.json, hu.json). Um eine davon zu nutzen, trägst du ihren Code in config/config.jsonc ein ("lang": "de").

Für eine weitere Sprache:

  1. locales/en.json kopieren, zum Beispiel als locales/it.json
  2. Alle Strings übersetzen, den transcript-Block eingeschlossen
  3. "lang": "it" in config/config.jsonc setzen, optional auch "transcriptLang": "it"

📝 Lizenz

AGPL-3.0. Der Quellcode muss offen bleiben und bei Weitergabe oder beim Hosten unter derselben Lizenz veröffentlicht werden.

Forks und Änderungen, die die Anbindung an den MSK Transcript Service entfernen oder umgehen, sind nicht gestattet.