- docker-compose.yml: Variablen per Interpolation (lokal aus .env, in Portainer aus Stack-Env) - tools/test-webhook.mjs: signierte Fake-Testzustellung gegen die lokale Instanz - README: Portainer-Anleitung präzisiert (Git-Auth für privates Repo, Pull and redeploy) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
6.1 KiB
EcoBot
Discord-Bot + Webinterface für die EcoGame-Community.
Features (Roadmap):
- ✅ Bot online +
/pingSlash-Command - ✅ Commit-Feed: Gitea-Push-Webhooks → Discord-Embeds + SQLite-Archiv
- ⬜ Devlog-Archiv: tägliche Devlogs archivieren
- ⬜ Webinterface: Discord-Login, Devlog- & Commit-Seiten
Stack: Node.js 20+, discord.js v14, Fastify, React (ab Feature 4), SQLite (better-sqlite3), Docker
Setup: Discord-App anlegen (einmalig)
1. App erstellen
- Öffne das Discord Developer Portal
- New Application → Name:
EcoBot→ Create - Unter General Information die Application ID kopieren
→ das ist
DISCORD_CLIENT_ID
2. Bot-Token holen
- Linke Seitenleiste → Bot
- Reset Token → Token kopieren → das ist
DISCORD_TOKEN⚠️ Der Token wird nur einmal angezeigt — direkt in die.enveintragen! - Auf der Bot-Seite weiter unten: Message Content Intent aktivieren (brauchen wir ab Feature 3 zum Lesen der Devlog-Nachrichten)
3. Bot auf den Server einladen
- Linke Seitenleiste → OAuth2 → URL Generator
- Scopes ankreuzen:
botundapplications.commands - Bot Permissions ankreuzen:
- Send Messages
- Embed Links
- Read Message History
- Generierte URL unten kopieren, im Browser öffnen, deinen Server auswählen → Autorisieren
4. Server-ID holen (für sofortige Slash-Commands)
- In Discord: Einstellungen → Erweitert → Entwicklermodus aktivieren
- Rechtsklick auf deinen Server → Server-ID kopieren
→ das ist
DISCORD_GUILD_ID
5. .env anlegen
cp .env.example .env
Dann die Werte eintragen. Die .env ist in .gitignore und landet nie im Repo.
Setup: Commit-Feed (Gitea → Discord)
1. Neue .env-Werte
| Variable | Woher |
|---|---|
COMMIT_CHANNEL_ID |
Rechtsklick auf den Ziel-Kanal in Discord → Kanal-ID kopieren |
GITEA_WEBHOOK_SECRET |
Generieren: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" |
2. Öffentlicher Host im Nginx Proxy Manager (bot.d4rkst3r.de)
Cloudflare (DNS):
- Cloudflare-Dashboard → Zone
d4rkst3r.de→ DNS - Neuen Record anlegen: Typ CNAME, Name
bot, Ziel wie bei den bestehenden Hosts (z. B.d4rkst3r.de), Proxy-Status Proxied (orange Wolke)
Nginx Proxy Manager:
- NPM öffnen → Hosts → Proxy Hosts → Add Proxy Host
- Tab Details:
- Domain Names:
bot.d4rkst3r.de - Scheme:
http - Forward Hostname / IP:
host.docker.internal(NPM läuft im Container, der Bot published Port 3080 auf dem Windows-Host) - Forward Port:
3080 - ✅ Block Common Exploits
- Domain Names:
- Tab SSL:
- SSL Certificate: Request a new SSL Certificate (Let's Encrypt) — oder das vorhandene Wildcard-Zertifikat auswählen
- ✅ Force SSL
- Save
Test: https://bot.d4rkst3r.de/health im Browser → {"status":"ok"}
3. Webhook in Gitea eintragen
- Gitea → EcoGame-Repo → Einstellungen → Webhooks → Webhook hinzufügen → Gitea
- Ziel-URL:
https://bot.d4rkst3r.de/webhooks/gitea - HTTP-Methode:
POST, POST Content Type:application/json - Geheimnis: exakt der Wert aus
GITEA_WEBHOOK_SECRET - Trigger: Push-Events, Branch-Filter leer (= alle)
- Speichern → auf den Webhook klicken → Testzustellung senden → im Discord-Kanal erscheint ein Embed 🎉
Den alten direkten Discord-Webhook im Repo danach löschen, sonst gibt's Doppel-Posts.
Bereits gepostete Commits werden per SHA dedupliziert — ein erneuter Push derselben Commits erzeugt keine doppelten DB-Einträge.
Lokal starten (Entwicklung)
npm install
npm run dev
Erwartete Ausgabe:
[bot] Eingeloggt als EcoBot#1234
[bot] 1 Slash-Command(s) registriert (Guild)
Dann in Discord: /ping → Bot antwortet mit Latenz. 🎉
Commit-Feed lokal testen (ohne Gitea — simuliert eine signierte Testzustellung):
node tools/test-webhook.mjs
→ Embed erscheint im Commit-Kanal, Commit landet in der lokalen SQLite (data/ecobot.db).
Deployment (Docker / Portainer)
Variante A: Portainer-Stack aus Git (empfohlen)
- Portainer → Stacks → Add stack → Name:
ecobot - Build method: Repository
- Repository URL:
https://git.d4rkst3r.de/D4rkst3r/ecobot - Repository reference:
refs/heads/main - Compose path:
docker-compose.yml - Falls das Repo privat ist: Authentication aktivieren —
Username:
D4rkst3r, Password: ein Gitea-Token (Gitea → Einstellungen → Anwendungen → Token erzeugen, Scoperead:repository)
- Repository URL:
- Unter Environment variables → Advanced mode die Werte aus der lokalen
.enveintragen (DISCORD_TOKEN,DISCORD_CLIENT_ID,DISCORD_GUILD_ID,COMMIT_CHANNEL_ID,GITEA_WEBHOOK_SECRET) - Deploy the stack
Updates später: Stack öffnen → Pull and redeploy (holt den neuesten Stand von main).
Variante B: Manuell auf dem Server
git clone git@gitea:D4rkst3r/ecobot.git
cd ecobot
cp .env.example .env # Werte eintragen
docker compose up -d --build
Logs prüfen:
docker logs -f ecobot
Projektstruktur
ecobot/
├── src/
│ ├── index.js # Einstiegspunkt (Bot + Webserver)
│ ├── config.js # Env-Konfiguration mit Validierung
│ ├── db.js # SQLite (better-sqlite3), Schema + Queries
│ ├── bot/
│ │ ├── client.js # Discord-Client, Command-Registry, Interactions
│ │ ├── commit-feed.js # Push → Discord-Embed
│ │ └── commands/
│ │ └── ping.js # /ping — Lebenszeichen
│ └── web/
│ └── server.js # Fastify: /health, /webhooks/gitea (HMAC-geprüft)
├── .env.example # Vorlage für Secrets (nach .env kopieren)
├── Dockerfile
├── docker-compose.yml
└── README.md
Neue Slash-Commands: Datei in src/bot/commands/ anlegen (exportiert data + execute)
und in src/bot/client.js bei commandModules eintragen.