EcoBot

Discord-Bot + Webinterface für die EcoGame-Community.

Features (Roadmap):

  1. Bot online + /ping Slash-Command
  2. Commit-Feed: Gitea-Push-Webhooks → Discord-Embeds + SQLite-Archiv
  3. Devlog-Archiv: tägliche Devlogs archivieren
  4. 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

  1. Öffne das Discord Developer Portal
  2. New Application → Name: EcoBot → Create
  3. Unter General Information die Application ID kopieren → das ist DISCORD_CLIENT_ID

2. Bot-Token holen

  1. Linke Seitenleiste → Bot
  2. Reset Token → Token kopieren → das ist DISCORD_TOKEN ⚠️ Der Token wird nur einmal angezeigt — direkt in die .env eintragen!
  3. 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

  1. Linke Seitenleiste → OAuth2URL Generator
  2. Scopes ankreuzen: bot und applications.commands
  3. Bot Permissions ankreuzen:
    • Send Messages
    • Embed Links
    • Read Message History
  4. Generierte URL unten kopieren, im Browser öffnen, deinen Server auswählen → Autorisieren

4. Server-ID holen (für sofortige Slash-Commands)

  1. In Discord: Einstellungen → Erweitert → Entwicklermodus aktivieren
  2. 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):

  1. Cloudflare-Dashboard → Zone d4rkst3r.deDNS
  2. 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:

  1. NPM öffnen → HostsProxy HostsAdd Proxy Host
  2. 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
  3. Tab SSL:
    • SSL Certificate: Request a new SSL Certificate (Let's Encrypt) — oder das vorhandene Wildcard-Zertifikat auswählen
    • Force SSL
  4. Save

Test: https://bot.d4rkst3r.de/health im Browser → {"status":"ok"}

3. Webhook in Gitea eintragen

  1. Gitea → EcoGame-Repo → EinstellungenWebhooksWebhook hinzufügenGitea
  2. Ziel-URL: https://bot.d4rkst3r.de/webhooks/gitea
  3. HTTP-Methode: POST, POST Content Type: application/json
  4. Geheimnis: exakt der Wert aus GITEA_WEBHOOK_SECRET
  5. Trigger: Push-Events, Branch-Filter leer (= alle)
  6. 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)

  1. Portainer → StacksAdd stack → Name: ecobot
  2. 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, Scope read:repository)
  3. Unter Environment variablesAdvanced mode die Werte aus der lokalen .env eintragen (DISCORD_TOKEN, DISCORD_CLIENT_ID, DISCORD_GUILD_ID, COMMIT_CHANNEL_ID, GITEA_WEBHOOK_SECRET)
  4. 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.

S
Description
No description provided
Readme
7.4 MiB
Languages
JavaScript 90.4%
CSS 8.7%
PowerShell 0.7%
Dockerfile 0.2%