jbergner 9fb4300410
All checks were successful
release-tag / release-image (push) Successful in 2m18s
Ort bei Lagerbewegungen als Pflichtfeld
2026-05-29 22:39:57 +02:00
2026-05-29 21:48:19 +02:00
2026-05-29 21:48:19 +02:00
2026-05-29 21:48:19 +02:00
2026-05-29 09:16:05 +02:00
fix
2026-05-29 09:22:10 +02:00
2026-05-29 09:16:05 +02:00
2026-05-29 09:16:05 +02:00
2026-05-29 09:16:05 +02:00
2026-05-29 09:16:05 +02:00

Starauftrag Discord Bot (Go + SQLite)

Produktionsnaher Discord-Bot für Lieferaufträge mit SQLite-Persistenz, Slash Commands, internen Team-Buttons, Audit-Log und privater Lagerverwaltung.

Kernidee

  • Endnutzer erstellen mit /auftrag einen Lieferauftrag.
  • Der öffentliche Auftragspost enthält nur auftragsbezogene Basisdaten.
  • Das Team erhält in einem privaten internen Channel denselben Auftrag plus Lagerprüfung.
  • Annahme/Ablehnung erfolgt ausschließlich im internen Channel per Button.
  • Lagerdaten werden nie an den Einreicher oder in öffentliche Posts ausgegeben.
  • Alle relevanten Änderungen werden in order_events auditiert.

Discord Buttons sind Message Components mit custom_id; beim Klick erhält der Bot eine Component Interaction und ordnet sie damit wieder dem Auftrag zu.

Setup

  1. Discord Developer Portal: Bot erstellen, Token kopieren, Bot in deinen Server einladen.
  2. Bot-Berechtigungen:
    • Send Messages
    • Use Slash Commands
    • Read Message History
    • Embed Links
    • Create Public Threads oder Create Private Threads je nach Channel-Einstellung
    • Send Messages in Threads
  3. .env.example nach .env kopieren oder Umgebungsvariablen setzen.
  4. Starten:
go mod tidy
go run .

Für schnelle Command-Updates in Entwicklung DISCORD_GUILD_ID setzen. Ohne Guild-ID werden Slash Commands global registriert, was länger dauern kann.

Wichtige Umgebungsvariablen

DISCORD_TOKEN=...
DISCORD_APP_ID=...
DISCORD_GUILD_ID=...
DISCORD_PUBLIC_ORDER_CHANNEL_ID=...
DISCORD_INTERNAL_ORDER_CHANNEL_ID=...
DISCORD_AUDIT_CHANNEL_ID=...
DISCORD_ADMIN_ROLE_IDS=roleId1,roleId2
DISCORD_TEAM_ROLE_IDS=roleId3,roleId4
DATABASE_PATH=orders.db
THREAD_DELETE_AFTER_HOURS=72

DISCORD_INTERNAL_ORDER_CHANNEL_ID sollte ein privater Team-Channel sein. Nur dort erscheinen Lagerprüfung und Annahme-/Ablehnen-Buttons.

User Commands

/auftrag

Erstellt einen Auftrag mit:

  • ware
  • qualitaet 0-1000
  • menge als Zahl
  • einheit SCU, cSCU oder Stück
  • frist im Format YYYY-MM-DD
  • lieferort
  • budget in aUEC

/auftrag_status id:<id>

Zeigt den Auftrag. Team/Admin sieht die interne Ansicht inklusive Lagerprüfung, normale Nutzer nur eigene Aufträge ohne Lagerdaten.

/auftrag_liste status:<optional> limit:<optional>

Listet nur aktive Aufträge. Standardmäßig werden offen, angenommen, in Lieferung und geliefert angezeigt. Abgeschlossene, abgelehnte und abgebrochene Aufträge erscheinen hier nicht mehr.

/auftrag_archiv status:<optional> limit:<optional>

Listet archivierte Aufträge mit den deutschen Statuswerten abgeschlossen, abgelehnt und abgebrochen. Intern werden die stabilen Werte completed, declined und cancelled gespeichert.

/auftrag_abschliessen id:<id>

Einreicher, Annehmer oder Team/Admin können abschließen.

/auftrag_abbrechen id:<id> grund:<optional>

Einreicher oder Team/Admin können abbrechen.

/auftrag_nachricht id:<id> text:<text>

Leitet eine Nachricht per DM an Einreicher und Annehmer weiter und schreibt sie zusätzlich in den internen Auftragsthread.

Team/Admin Commands

/auftrag_status_setzen

Team/Admin kann den Status manuell setzen:

  • offen
  • angenommen
  • in Lieferung
  • geliefert
  • abgeschlossen
  • abgelehnt
  • abgebrochen

Lager Commands

Nur Admins können Lagerbestände verändern. Team/Admin kann Lager prüfen und anzeigen.

/lager_add

Fügt Bestand hinzu oder setzt ihn absolut.

/lager_add ware:Gold qualitaet:900 menge:64 einheit:SCU ort:Orison modus:addieren
/lager_add ware:Gold qualitaet:900 menge:100 einheit:SCU ort:Orison modus:setzen

ort ist ein Pflichtfeld und bezeichnet den internen Lagerort. Er wird nur in Team-/Admin-Ausgaben, der internen Lagerprüfung und im Auditlog angezeigt. Öffentliche Auftragsposts und Endnutzer-DMs enthalten keine Lagerorte.

Das Auditlog zeigt Bestandsänderungen mit altem und neuem Wert, z. B.:

Lager geändert durch b1tk1ll3r: P4-AR Q725 Stück @ Baijini Point: 0 → 2

/lager_remove

Reduziert Bestand. Der Bot verhindert negative Bestände.

/lager_remove ware:Gold qualitaet:900 menge:10 einheit:SCU ort:Orison

Auch hier ist ort ein Pflichtfeld und bezieht sich auf genau diese Lagerposition. Dadurch werden Bestände an verschiedenen Orten sauber getrennt geführt.

/lager_liste

Zeigt interne Lagerbestände ephemeral an.

/lager_liste suche:Gold limit:20

/lager_check

Prüft intern, ob eine Menge verfügbar ist.

/lager_check ware:Gold qualitaet:900 menge:64 einheit:SCU
/lager_check ware:P4-AR qualitaet:725 menge:2 einheit:cSCU

Statusmodell

offen -> angenommen -> in Lieferung -> geliefert -> abgeschlossen
       \-> abgebrochen
offen -> abgelehnt

Intern speichert der Bot weiterhin stabile technische Statuswerte wie `open`, `accepted`, `completed` usw. In Discord werden sie deutsch angezeigt.

Datenbanktabellen

  • orders: Aufträge und Discord-Message-Referenzen
  • inventory: interne Lagerpositionen
  • order_events: Audit-Log für Aufträge und Lageränderungen

SQLite wird mit WAL-Modus und busy_timeout betrieben, damit kleine produktive Deployments robuster laufen.

Produktionshinweise

  • Setze DISCORD_INTERNAL_ORDER_CHANNEL_ID auf einen strikt privaten Channel.
  • Gib Lager-Commands nur einer kleinen Admin-Rolle.
  • Sichere orders.db regelmäßig.
  • Führe den Bot als systemd-Service oder Container aus.
  • Aktiviere Monitoring für Logs und Neustarts.
  • Teste DMs: Manche Nutzer blockieren DMs von Servermitgliedern; der Bot loggt solche Fehler, kann sie aber nicht erzwingen.

Lagerbestand bei 0

Wenn ein Lagerbestand durch /lager_remove oder /lager_add mit modus:setzen auf 0 fällt, wird der Lagerdatensatz automatisch gelöscht. Das Auditlog zeigt weiterhin die Änderung als alter Wert → neuer Wert, z. B. 2 → 0.

Zusätzlich verhindert die Lagerlogik negative Bestände. Wenn mehr entfernt wird als vorhanden ist, antwortet der Bot mit einem Fehler und ändert den Bestand nicht.

/lager_liste und die interne Lagerprüfung berücksichtigen nur Bestände größer als 0, sodass alte Nullbestände nicht mehr angezeigt werden.

Automatische Thread-Bereinigung

Interne Auftragsthreads werden nach einer konfigurierbaren Zeit automatisch gelöscht, sobald der Auftrag archiviert ist. Archiviert bedeutet:

  • abgeschlossen
  • abgelehnt
  • abgebrochen

Die Zeit steuerst du über:

THREAD_DELETE_AFTER_HOURS=72

72 bedeutet: Der Thread wird frühestens 72 Stunden nach der letzten Statusänderung gelöscht. 0 deaktiviert die automatische Thread-Bereinigung.

Für das Löschen benötigt der Bot im internen Channel zusätzlich Manage Threads. Wenn diese Berechtigung fehlt, bleibt der Thread bestehen und der Fehler erscheint im Bot-Log.

Deutsche Statusbegriffe

Discord zeigt Statuswerte jetzt deutsch an:

Anzeige interner Wert
offen open
angenommen accepted
in Lieferung in_delivery
geliefert delivered
abgeschlossen completed
abgelehnt declined
abgebrochen cancelled

Die internen Werte bleiben absichtlich englisch, damit bestehende Datenbanken und Integrationen stabil bleiben.

Einheiten

Bei Aufträgen und Lagerbeständen sind jetzt diese Einheiten auswählbar:

  • SCU
  • cSCU
  • Stück
Description
No description provided
Readme 233 KiB
Languages
Go 99.7%
Dockerfile 0.3%