Dies ist ein Discord-Ticket-Bot mit integrierter KI-Unterstützung (OpenAI / GPT-4o-mini). Der Bot ermöglicht Nutzer*innen, über einen Button ein Ticket zu eröffnen, woraufhin eine „Sekretärin Sigrid“ (KI) direkt im Channel erste Fragen stellt und entscheidet, ob der/die Nutzer*in kooperativ ist. Anschließend kann das Support-/Admin-Team das Ticket übernehmen, bearbeiten, schließen oder löschen.
Zusätzlich enthält das Projekt eine Flask-Webanwendung (zugänglich über Discord-OAuth2-Login), die Übersichten und Transkripte der Tickets anzeigt.
- Funktionsübersicht
- Voraussetzungen
- Discord Developer Portal: Bot erstellen & einrichten
- Projektstruktur
- Installation & Konfiguration
- Start des Discord-Bots (lokal)
- Start des Flask-Webservers (lokal)
- Produktivbetrieb
- Discord-Bot-Kommandos & Workflow
- Web-Panel: Funktionen
- Lizenz / Hinweise
- Ticket-Erstellung via Button in Discord-Kanälen.
- KI-Unterstützung (GPT-4o-mini oder kompatibel): Stellt anfangs Fragen (z. B. nach einer Bann-ID) und prüft Kooperationsbereitschaft.
- Manuelles Claiming: Supporter/Admins können Tickets beanspruchen, schreiben und den User direkt betreuen.
- Abschluss: Ticket schließen (Archiv in „Closed“-Kategorie, Transkript wird gespeichert) oder Ticket löschen (Kanal weg, Transkript bleibt in der Datenbank).
- Web-Panel (Flask) mit Discord-OAuth2-Anmeldung, um Ticketlisten und Transkripte einzusehen.
- Python 3.9 oder höher (empfohlen).
- Discord-Bot (Client-ID, Bot-Token) – Anlegen und konfigurieren siehe unten.
- GPT-4o-mini-API-Key (oder ein kompatibles OpenAI-/GPT-Zugangstoken).
- SQLite (in Python enthalten).
- Für OCR-Funktionen:
pytesseract
(Python-Bindings),- systemweit installiertes Tesseract mit deutschem Sprachpaket („tesseract-ocr-deu“).
- Python-Bibliotheken wie
py-cord
,openai
,flask
,requests
,python-dotenv
,aiohttp
,gunicorn
,pytesseract
,Pillow
.
- Gehe zum Discord Developer Portal.
- Klicke auf New Application.
- Gib einen Namen für deine Anwendung ein, z. B. „TicketBot“.
- Klicke auf Create.
- Wähle deine neue Anwendung aus.
- Gehe links auf Bot.
- Klicke auf Add Bot → Yes, do it!.
- Nun hast du einen Bot-Account innerhalb der Anwendung.
- Kopiere unter TOKEN deinen Bot-Token (dieser muss in deiner
.env
unterBOT_TOKEN=
eingetragen werden!). - (Optional) Passe das Bot-Icon und den Benutzernamen an.
- In der Bot-Seite (im Developer Portal) scrolle zu Privileged Gateway Intents.
- Aktiviere ggf. Message Content Intent, wenn du möchtest, dass dein Bot Nachrichteninhalte lesen kann (hier im Code ist
message_content = True
gesetzt). - Aktiviere ggf. weitere Intents (z. B. Presence, Server Members) falls benötigt.
- Klicke auf Save Changes.
- Gehe links auf OAuth2 > URL Generator.
- Wähle unter Scopes:
bot
&applications.commands
(für Slash-Befehle). - Unter Bot Permissions wähle die nötigen Rechte (z. B.
Send Messages
,Manage Channels
,Manage Roles
– je nachdem, welche Aktionen dein Bot ausführen muss). - Der generierte Link (unten) kann jetzt kopiert und im Browser aufgerufen werden.
- Wähle den Server, auf dem der Bot hinzugefügt werden soll, und bestätige.
- Standardmäßig registriert Discord Slash-Befehle automatisch, wenn du sie in deinem Code (z. B. in
ticket_cog.py
) definiert hast. - Stelle sicher, dass du die erforderlichen Intents aktiviert hast.
- Die Synchronisierung der Slash-Befehle kann teils mehrere Minuten dauern.
.
├── main.py # Startpunkt für den Discord-Bot
├── cogs/
│ ├── ticket_cog.py # Hauptlogik (Ticketverwaltung + KI)
│ └── transcript_cog.py # /ticket_transcript-Befehl
├── utils/
│ ├── config.py # Lädt .env-Variablen, enthält IDs und Konstanten
│ └── database.py # SQLite-Datenbankzugriff
├── webapp/
│ ├── app.py # Flask-Anwendung (Web-Panel)
│ ├── templates/
│ │ ├── index.html # Übersicht aller Tickets
│ │ └── transcript_detail.html # Zeigt ein einzelnes Transkript
│ └── static/ # (optionale statische Dateien)
├── tickets.sqlite # SQLite-Datenbank (wird automatisch angelegt)
├── .env # Deine Umgebungsvariablen
└── requirements.txt # Liste benötigter Pakete (Beispiel)
-
Projekt klonen/entpacken
Lade das Projekt in einen geeigneten Ordner. -
Virtuelle Umgebung (optional, empfohlen)
python -m venv venv source venv/bin/activate # (Linux/Mac) # Windows: venv\Scripts\activate
-
Abhängigkeiten installieren
Die wichtigsten Python-Pakete sind inrequirements.txt
aufgeführt. Ein Beispiel:py-cord openai flask requests python-dotenv aiohttp gunicorn pytesseract Pillow
Installiere sie mit:
pip install -r requirements.txt
-
Konfiguration in
.env
Erstelle eine Datei namens.env
(im Hauptverzeichnis). Beispiel:BOT_TOKEN=DEIN_DISCORD_BOT_TOKEN GUILD_ID=123456789123456789 SUPPORT_ROLE_ID=111111111111111111 ADMIN_ROLE_ID=222222222222222222 VIEWER_ROLE_ID=333333333333333333 VIEWER2_ROLE_ID=444444444444444444 CREATED_TICKETS_CATEGORY_ID=555555555555555555 CLAIMED_TICKETS_CATEGORY_ID=666666666666666666 CLOSED_TICKETS_CATEGORY_ID=777777777777777777 TICKET_LOG_CHANNEL_ID=888888888888888888 MAX_TICKETS_PER_SUPPORTER=3 TICKET_CLEANUP_DAYS=7 # GPT-4o-mini- oder kompatibler API Key: OPENAI_API_KEY=sk-... OPENAI_MODEL=gpt-4o-mini # Flask WebApp (Discord OAuth2) FLASK_SECRET_KEY=EinLangerGeheimerString DISCORD_CLIENT_ID=1234567890 DISCORD_CLIENT_SECRET=ABCDEFGHIJKLMNOPQRST DISCORD_REDIRECT_URI=https://deine-app.de/callback
Je nachdem, wie oder wo du GPT-4o-mini verwendest (z. B. lokal gehostet, per Proxy oder über einen Drittanbieter), benötigst du einen gültigen API-Key oder ein Zugangstoken.
- Account / Projekt erstellen beim Anbieter, der GPT-4o-mini bereitstellt, oder deine eigene Instanz konfigurieren.
- API-Schlüssel generieren oder abrufen (z. B. „Secret Key“).
- Diesen Schlüssel in der
.env
unterOPENAI_API_KEY
eintragen (oder einer anderen Variable, falls du den Code entsprechend anpasst). - In
OPENAI_MODEL
könntest du „gpt-4o-mini“ eintragen, wenn dein Anbieter diesen Modellnamen unterstützt.
Beachte die jeweiligen Nutzungsbedingungen und möglichen Kosten (z. B. pro Anfrage).
Falls du in der ticket_cog.py
die OCR-Funktion (z. B. pytesseract.image_to_string(img, lang="deu")
) verwendest, musst du folgendes sicherstellen:
- Systemweit installiertes Tesseract-OCR (nicht nur das Python-Paket
pytesseract
). - Das deutsche Sprachpaket („deu“).
Beispiele:
Ubuntu/Debian:
sudo apt-get update
sudo apt-get install tesseract-ocr tesseract-ocr-deu
Windows:
- Lade das offizielle Tesseract-Windows-Installationsprogramm (z. B. UB Mannheim Build) herunter.
- Während der Installation kannst du zusätzliche Sprachpakete (wie Deutsch) auswählen oder später manuell in den
tessdata/
-Ordner legen (z. B.deu.traineddata
).
Erst dann ist pytesseract
(inkl. deutschem OCR) vollständig nutzbar.
- Terminal öffnen, ins Projektverzeichnis wechseln.
- (Optional) Virtuelle Umgebung aktivieren.
- Bot starten:
python main.py
- Auf der Konsole sollten Meldungen erscheinen wie
Dann ist der Bot auf deinem Server online (sofern Token & IDs korrekt sind).
[LOG] Erfolgreich cogs.ticket_cog geladen. [LOG] Erfolgreich cogs.transcript_cog geladen. [LOG] Starte Bot... [LOG] Eingeloggt als DeinBotName (ID: 123456789)
- Prüfe
.env
:FLASK_SECRET_KEY
,DISCORD_CLIENT_ID
,DISCORD_CLIENT_SECRET
,DISCORD_REDIRECT_URI
. - Starte die Flask-App:
python webapp/app.py
- Standardmäßig läuft sie auf
http://127.0.0.1:60123
. - Öffne die URL im Browser. Du wirst über Discord-OAuth2 geleitet (sofern
DISCORD_REDIRECT_URI
korrekt eingetragen ist).
Im produktiven Umfeld empfiehlt es sich, den Discord-Bot (main.py
) als Systemd-Service laufen zu lassen und die Flask-App mit Gunicorn (ebenfalls in einem Systemd-Service) zu betreiben. So kannst du beide Prozesse dauerhaft und stabil im Hintergrund laufen lassen und über einen Reverse Proxy (Nginx/Apache) absichern.
- Gunicorn installieren (falls nicht bereits geschehen):
pip install gunicorn
- Gunicorn starten (Beispiel):
gunicorn -w 2 -b 0.0.0.0:60123 webapp.app:app
-w 2
= 2 Worker-Prozesse.-b 0.0.0.0:60123
= Port 60123 auf allen Interfaces.webapp.app:app
= Importiere das Flask-App-Objektapp
auswebapp/app.py
.
Lege eine Service-Datei an, z. B. /etc/systemd/system/discord_ticketbot.service
:
[Unit]
Description=Discord Ticketbot
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/pfad/zu/deinem/projekt
ExecStart=/pfad/zu/deinem/projekt/venv/bin/python main.py
Restart=always
[Install]
WantedBy=multi-user.target
Anschließend:
sudo systemctl daemon-reload
sudo systemctl enable discord_ticketbot
sudo systemctl start discord_ticketbot
sudo systemctl status discord_ticketbot
Lege eine zweite Service-Datei an, z. B. /etc/systemd/system/ticketweb_gunicorn.service
:
[Unit]
Description=Gunicorn for Ticket WebApp
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/pfad/zu/deinem/projekt
ExecStart=/pfad/zu/deinem/projekt/venv/bin/gunicorn --workers 2 --bind 0.0.0.0:60123 webapp.app:app
Restart=always
[Install]
WantedBy=multi-user.target
Dann:
sudo systemctl daemon-reload
sudo systemctl enable ticketweb_gunicorn
sudo systemctl start ticketweb_gunicorn
sudo systemctl status ticketweb_gunicorn
In der Regel leitest du in der produktiven Umgebung den Traffic per HTTPS von NGINX/Apache zu Gunicorn weiter. Ein Beispiel (NGINX, HTTP → Proxy → Gunicorn auf Port 60123):
server {
listen 80;
server_name deine-app.de;
location / {
proxy_pass http://127.0.0.1:60123;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
}
}
Anschließend kannst du Let's Encrypt oder ein anderes SSL-Zertifikat aktivieren.
-
Slash-Befehl:
/setup_ticket_button
- Nur für Admin-Rolle (
ADMIN_ROLE_ID
). - Erstellt eine Nachricht mit „Ticket erstellen“-Button im aktuellen Kanal.
- Nur für Admin-Rolle (
-
Ticket-Kanal
- Klick → Neuer Textkanal in Kategorie
CREATED_TICKETS_CATEGORY_ID
. - KI (Sekretärin Sigrid) begrüßt, fragt nach ID und klärt den Banngrund.
- Klick → Neuer Textkanal in Kategorie
-
Ticket beanspruchen
- Button: „Ticket beanspruchen“ → Wechselt in
CLAIMED_TICKETS_CATEGORY_ID
.
- Button: „Ticket beanspruchen“ → Wechselt in
-
Ticket schließen
- Button: „Ticket schließen“ → Kanal wird archiviert in
CLOSED_TICKETS_CATEGORY_ID
, Transkript gespeichert, KI wird beendet.
- Button: „Ticket schließen“ → Kanal wird archiviert in
-
Ticket löschen
- Button: „Ticket löschen“ → Kanal wird gelöscht, Transkript bleibt in der Datenbank.
-
/ticket_transcript
- Erstellt / aktualisiert ein Transkript manuell (nur Supporter/Admin).
- Übersichtsseite (
/
): Zeigt alle Tickets (ID, Ersteller, Status, neuestes Transkript). - Transkriptansicht: Zeigt den Chatverlauf eines Tickets.
- Login über Discord-OAuth2; nur Rollen aus
ALLOWED_ROLES
(siehe.env
) haben Zugriff.
- Dieses Projekt nutzt Abhängigkeiten mit eigenen Lizenzen (Discord, GPT-4o-mini/OpenAI, Flask etc.). Prüfe deren Bestimmungen.
- Achte auf die Nutzungsrichtlinien von Discord und deinem GPT-4o-mini-/OpenAI-Anbieter (z. B. Abrechnungsmodelle, verbotene Inhalte etc.).
- Du kannst den Code frei anpassen und erweitern.