README komplett überarbeitet: aktueller Funktionsumfang, Setup, Endpoints, Struktur
- Feature-Tabellen (Discord + Webinterface + Setup-Seite) - Ersteinrichtung gestrafft: Discord-App inkl. aller nötigen Permissions, Env-Tabelle mit Pflicht/Optional, Gitea-Webhook mit allen drei Trigger-Events - Deployment (Portainer inkl. Re-pull-Hinweis), lokale Entwicklung - HTTP-Endpoint-Referenz und aktualisierte Projektstruktur Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,257 +1,190 @@
|
|||||||
# EcoBot
|
# EcoBot — D4RKST3R // DEVLOG
|
||||||
|
|
||||||
Discord-Bot + Webinterface für die EcoGame-Community.
|
Discord-Bot + Webinterface: Devlog-Tagebuch, Commit-Feed, Changelog und
|
||||||
|
Community-Tools für die EcoGame-Entwicklung — alles gebrandet, alles über
|
||||||
|
die Setup-Seite steuerbar.
|
||||||
|
|
||||||
**Features (Roadmap):**
|
**Stack:** Node.js 20+ (ESM), discord.js v14, Fastify 5, React 19 + Vite,
|
||||||
1. ✅ Bot online + `/ping` Slash-Command
|
SQLite (better-sqlite3, FTS5), Docker Multi-Stage — deploybar als Portainer-Stack.
|
||||||
2. ✅ Commit-Feed: Gitea-Push-Webhooks → Discord-Embeds + SQLite-Archiv
|
|
||||||
3. ✅ Devlog-Archiv: Devlog-Kanal live archivieren + `/devlog-backfill` für die Historie
|
|
||||||
4. ✅ Webinterface: Devlog-Archiv (öffentlich) + Commit-Feed (Discord-Login, nur Admin)
|
|
||||||
|
|
||||||
**Stack:** Node.js 20+, discord.js v14, Fastify, React + Vite, SQLite (better-sqlite3), Docker
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Setup: Discord-App anlegen (einmalig)
|
## Features
|
||||||
|
|
||||||
### 1. App erstellen
|
### Discord
|
||||||
1. Öffne das [Discord Developer Portal](https://discord.com/developers/applications)
|
| Feature | Beschreibung |
|
||||||
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 → **OAuth2** → **URL 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** |
|
| 📔 **Devlog-Posts** | `tools/devlog.py` (EcoGame-Repo) schickt Prosa + Bilder an den Bot-Endpoint → gebrandetes Embed (Datum-Titel, Author-Zeile, Commit-Zähler im Footer, Bilder-Grid, Link-Buttons) |
|
||||||
| `GITEA_WEBHOOK_SECRET` | Generieren: `node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"` |
|
| 💬 **Auto-Threads** | Diskussions-Thread unter jedem Devlog-Post („💬 Devlog 23.07.") |
|
||||||
|
| 🔔 **Rollen-Ping** | Ping-Rolle beim Devlog-Post; Member abonnieren sie selbst über den 🔔-Button |
|
||||||
|
| 📦 **Commit-Feed** | Gitea-Push-Webhooks → Embeds in den (privaten) Commit-Kanal |
|
||||||
|
| 🚀 **Release-Ankündigungen** | Neues Gitea-Release → oranges Ankündigungs-Embed |
|
||||||
|
| 📊 **Wochen-Rückblick** | Sonntags 20:00 automatisch: Commits pro Tag als Balken, Devlogs, Top-Projekte |
|
||||||
|
| 🐛 **`/bug`** | Member melden Bugs → Gitea-Issue (inkl. Screenshot-Upload); Issue geschlossen → DM an den Reporter |
|
||||||
|
| 🚨 **Watchdog** | Prüft eigene Dienste alle 2 min, DM-Alarm bei Ausfall + Entwarnung |
|
||||||
|
| 🏓 `/ping`, 🗄 `/devlog-backfill` | Lebenszeichen · Kanal-Historie nacharchivieren (Admin) |
|
||||||
|
|
||||||
### 2. Öffentlicher Host im Nginx Proxy Manager (`bot.d4rkst3r.de`)
|
### Webinterface (`bot.d4rkst3r.de`)
|
||||||
|
| Seite | Zugriff | Inhalt |
|
||||||
|
|---|---|---|
|
||||||
|
| `/devlogs` | öffentlich | Devlog-Archiv: Timeline, Bildergalerien, Projekt-Chips, **Volltextsuche** |
|
||||||
|
| `/changelog` | öffentlich | Alle Releases mit Notes, Tag- und Pre-Release-Chips |
|
||||||
|
| `/feed.xml` | öffentlich | RSS-Feed der Devlogs |
|
||||||
|
| `/commits` | nur Admin | Archivierte Commits aller Repos (SHA → Gitea-Link) |
|
||||||
|
| `/settings` | nur Admin | **Setup-Seite** — siehe unten |
|
||||||
|
|
||||||
**Cloudflare (DNS):**
|
Login via Discord-OAuth2 (identify-Scope, signierte Session-Cookies, keine Token-Speicherung).
|
||||||
1. Cloudflare-Dashboard → Zone `d4rkst3r.de` → **DNS**
|
Design: D4RKST3R-Brand (Neon-Gelb/Orange auf Schwarz, Bebas Neue + Barlow Condensed +
|
||||||
2. Neuen Record anlegen: Typ **CNAME**, Name `bot`, Ziel wie bei den bestehenden
|
Share Tech Mono, selbst gehostet).
|
||||||
Hosts (z. B. `d4rkst3r.de`), Proxy-Status **Proxied** (orange Wolke)
|
|
||||||
|
|
||||||
**Nginx Proxy Manager:**
|
### Setup-Seite (`/settings`)
|
||||||
1. NPM öffnen → **Hosts** → **Proxy Hosts** → **Add Proxy Host**
|
Alles zur Laufzeit änderbar — gespeichert in SQLite, Env-Variablen sind nur Fallback,
|
||||||
2. Tab **Details:**
|
kein Redeploy nötig:
|
||||||
- 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"}`
|
- **Kanäle** (Devlog / Commit / Release) als Dropdown + „Test senden"-Button je Kanal
|
||||||
|
- **Devlog:** Ping-Rolle, Auto-Threads an/aus, Wochen-Rückblick an/aus (+ Sofort-Test)
|
||||||
### 3. Webhook in Gitea eintragen
|
- **Commit-Feed:** an/aus, Branch-Filter, ignorierte Repos
|
||||||
1. Gitea → EcoGame-Repo → **Einstellungen** → **Webhooks** → **Webhook hinzufügen** → **Gitea**
|
(gefiltert wird nur das Posten — archiviert wird immer; ignorierte Repos komplett übersprungen)
|
||||||
2. Ziel-URL: `https://bot.d4rkst3r.de/webhooks/gitea`
|
- **Bug-Reports:** Ziel-Repo für `/bug`
|
||||||
3. HTTP-Methode: `POST`, POST Content Type: `application/json`
|
- **Watchdog:** überwachte URLs
|
||||||
4. **Geheimnis:** exakt der Wert aus `GITEA_WEBHOOK_SECRET`
|
- **Status-Panel:** Bot-Account, Uptime, Devlog-/Commit-Zahlen, DB-Größe
|
||||||
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.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Setup: Devlog (Bot postet + archiviert)
|
## Ersteinrichtung
|
||||||
|
|
||||||
Der Bot ist das Tagebuch: `tools/devlog.py` (EcoGame-Repo) schickt sein Devlog an
|
### 1. Discord-App ([Developer Portal](https://discord.com/developers/applications))
|
||||||
den **Bot-Endpoint** (Discord-Webhook-kompatibel), der Bot postet ein gebrandetes
|
1. **New Application** → Name vergeben
|
||||||
Embed (Gelb, „D4RKST3R // DEVLOG"-Footer, bis zu 4 Bilder als Grid) in den
|
2. **General Information** → Application ID = `DISCORD_CLIENT_ID`
|
||||||
Devlog-Kanal und archiviert Text + Bilder in SQLite.
|
3. **Bot** → Reset Token = `DISCORD_TOKEN` (wird nur einmal angezeigt!)
|
||||||
|
und **Message Content Intent** aktivieren (Devlog-Listener)
|
||||||
|
4. **OAuth2** → Client Secret = `DISCORD_CLIENT_SECRET`;
|
||||||
|
unter **Redirects** eintragen:
|
||||||
|
- `https://bot.d4rkst3r.de/auth/callback`
|
||||||
|
- `http://localhost:3080/auth/callback` (lokale Entwicklung)
|
||||||
|
5. **OAuth2 → URL Generator:** Scopes `bot` + `applications.commands`;
|
||||||
|
Permissions: Send Messages, Embed Links, Attach Files, Read Message History,
|
||||||
|
**Create Public Threads**, **Manage Roles** (für den 🔔-Abo-Button)
|
||||||
|
→ URL öffnen, Bot einladen
|
||||||
|
6. In Discord: Entwicklermodus an → Server-ID = `DISCORD_GUILD_ID`,
|
||||||
|
eigene User-ID = `ADMIN_DISCORD_ID`
|
||||||
|
|
||||||
1. `.env` / Portainer-Stack:
|
⚠️ **Kanal-Overrides:** In Kanälen, in denen `@everyone` nicht schreiben darf,
|
||||||
- `DEVLOG_CHANNEL_ID` = Kanal-ID des Devlog-Kanals
|
braucht der Bot eigene Overrides (Kanal ansehen, Nachrichten senden, Links einbetten,
|
||||||
- `DEVLOG_POST_SECRET` = generieren:
|
Dateien anhängen, Threads erstellen). Die Bot-Rolle muss **über** der Ping-Rolle stehen.
|
||||||
`node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"`
|
|
||||||
2. Im EcoGame-Repo in `tools/.devlog_webhook` statt der Discord-URL eintragen:
|
### 2. Environment-Variablen
|
||||||
|
Vorlage: [.env.example](.env.example) — lokal als `.env` (gitignored),
|
||||||
|
in Portainer als Stack-Environment-Variables.
|
||||||
|
|
||||||
|
| Variable | Pflicht | Zweck |
|
||||||
|
|---|---|---|
|
||||||
|
| `DISCORD_TOKEN` | ✅ | Bot-Token |
|
||||||
|
| `DISCORD_CLIENT_ID` | ✅ | Application ID |
|
||||||
|
| `DISCORD_CLIENT_SECRET` | ✅ | OAuth2-Login |
|
||||||
|
| `SESSION_SECRET` | ✅ | Session-Cookies signieren¹ |
|
||||||
|
| `ADMIN_DISCORD_ID` | ✅ | Deine User-ID (Admin-Zugriff + Watchdog-DMs) |
|
||||||
|
| `GITEA_WEBHOOK_SECRET` | ✅ | HMAC-Prüfung der Gitea-Webhooks¹ |
|
||||||
|
| `DEVLOG_POST_SECRET` | ✅ | Secret im Devlog-Endpoint-Pfad¹ |
|
||||||
|
| `DISCORD_GUILD_ID` | optional | Guild-Commands sofort statt global (bis 1h) |
|
||||||
|
| `GITEA_API_TOKEN` | optional | Für `/bug` → Issues (Scope `write:issue`); ohne Token ist `/bug` aus |
|
||||||
|
| `GITEA_URL` | optional | Default `https://git.d4rkst3r.de` |
|
||||||
|
| `PUBLIC_URL` | optional | Default `https://bot.d4rkst3r.de` |
|
||||||
|
| `COMMIT_CHANNEL_ID` / `DEVLOG_CHANNEL_ID` | optional | Fallbacks — Kanäle kommen normal von der Setup-Seite |
|
||||||
|
| `TZ` | optional | Default `Europe/Berlin` (Wochen-Rückblick, Datumsformate) |
|
||||||
|
|
||||||
|
¹ Generieren: `node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"`
|
||||||
|
|
||||||
|
### 3. Routing (einmalig eingerichtet)
|
||||||
|
Cloudflare: CNAME `bot` → Zone, Proxied. Nginx Proxy Manager: `bot.d4rkst3r.de`
|
||||||
|
→ `host.docker.internal:3080`, Block Common Exploits, Force SSL.
|
||||||
|
Test: `https://bot.d4rkst3r.de/health` → `{"status":"ok"}`
|
||||||
|
|
||||||
|
### 4. Gitea-Webhook (systemweit oder pro Repo)
|
||||||
|
- Typ **Gitea**, URL `https://bot.d4rkst3r.de/webhooks/gitea`,
|
||||||
|
Content Type `application/json`, Geheimnis = `GITEA_WEBHOOK_SECRET`
|
||||||
|
- Trigger-Events: **Push**, **Release**, **Issues**
|
||||||
|
(Push = Commit-Feed · Release = Ankündigungen/Changelog · Issues = Bug-Rückkanal-DMs)
|
||||||
|
|
||||||
|
### 5. devlog.py (EcoGame-Repo)
|
||||||
|
In `tools/.devlog_webhook` steht die Bot-Endpoint-URL:
|
||||||
```
|
```
|
||||||
https://bot.d4rkst3r.de/webhooks/devlog/<DEVLOG_POST_SECRET>
|
https://bot.d4rkst3r.de/webhooks/devlog/<DEVLOG_POST_SECRET>
|
||||||
```
|
```
|
||||||
`devlog.py` selbst bleibt unverändert — der Endpoint versteht das
|
Workflow: Prosa nach `tools/devlog_today.txt` (+ Bilder in `devlog_images/`, max 4)
|
||||||
Discord-Webhook-Format (JSON + Multipart mit Bildern).
|
→ `python tools/devlog.py` (oder Task täglich 21:00) → Bot postet + archiviert,
|
||||||
3. Den alten Discord-Webhook im Devlog-Kanal löschen (wird nicht mehr gebraucht)
|
Prosa-Datei und Bilder werden danach gelöscht (gepostet = erledigt).
|
||||||
|
Ohne Prosa postet das Skript **nichts** (Schutz des öffentlichen Kanals).
|
||||||
**Zusätzlich** liest der Bot den Kanal live mit und archiviert auch fremde
|
Der Endpoint versteht das Discord-Webhook-Format (JSON + Multipart) —
|
||||||
Webhook-/Bot-Posts (dafür: **Message Content Intent** im Developer Portal aktiv).
|
`devlog.py` kennt den Bot also gar nicht.
|
||||||
**`/devlog-backfill`** (Admin) archiviert die Kanal-Historie nach.
|
|
||||||
Dedupe läuft über die Discord-Message-ID — alles beliebig wiederholbar.
|
|
||||||
Bilder werden lokal gespeichert (`data/devlog_images/`), weil Discord-CDN-Links ablaufen.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Setup-Seite im Webinterface (Admin)
|
## Deployment (Portainer)
|
||||||
|
|
||||||
Unter **/settings** (Nav: „Setup", nur als Admin sichtbar) lassen sich zur Laufzeit
|
1. **Stacks → Add stack** → Name `ecobot` → Build method **Repository**
|
||||||
ändern — gespeichert in SQLite, **Env-Variablen sind nur noch der Fallback**,
|
- URL `https://git.d4rkst3r.de/D4rkst3r/ecobot`, Reference `refs/heads/main`,
|
||||||
Änderungen greifen sofort ohne Redeploy:
|
Compose path `docker-compose.yml`
|
||||||
|
- Privates Repo: Authentication mit Gitea-Token (Scope `read:repository`)
|
||||||
|
2. Environment-Variablen eintragen (Tabelle oben)
|
||||||
|
3. **Deploy the stack**
|
||||||
|
|
||||||
- **Devlog-Kanal** und **Commit-Kanal** als Dropdown (alle Textkanäle, die der
|
**Updates:** Stack öffnen → **Pull and redeploy**
|
||||||
Bot sieht) — mit **Test senden**-Button pro Kanal
|
(„Re-pull image" **aus** lassen — das Image wird lokal gebaut, nicht aus einer Registry gezogen).
|
||||||
- **Commit-Feed an/aus** (aus = Commits werden weiter archiviert, nur nicht gepostet)
|
|
||||||
- **Branch-Filter** (kommagetrennt, leer = alle) — gefilterte Branches werden
|
|
||||||
archiviert, aber nicht gepostet
|
|
||||||
- **Ignorierte Repos** (kommagetrennt, z. B. `D4rkst3r/ecobot`) — komplett übersprungen
|
|
||||||
- **Status-Panel:** Bot-Account, Uptime, Anzahl Devlogs/Commits, DB-Größe
|
|
||||||
|
|
||||||
`COMMIT_CHANNEL_ID` und `DEVLOG_CHANNEL_ID` sind damit optional geworden.
|
Daten liegen im Volume `ecobot_data` (`/app/data`): SQLite (`ecobot.db`, WAL)
|
||||||
|
+ Devlog-Bilder (`devlog_images/` — lokal gespeichert, weil Discord-CDN-Links ablaufen).
|
||||||
|
|
||||||
|
Manuell statt Portainer:
|
||||||
|
```
|
||||||
|
git clone git@gitea:D4rkst3r/ecobot.git && cd ecobot
|
||||||
|
cp .env.example .env # Werte eintragen
|
||||||
|
docker compose up -d --build
|
||||||
|
docker logs -f ecobot
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Bug-Reports, Threads & Watchdog
|
## Lokale Entwicklung
|
||||||
|
|
||||||
**`/bug` (alle Member):** Titel + Beschreibung + optional Screenshot → der Bot
|
```
|
||||||
erstellt ein Gitea-Issue im konfigurierten Repo (Setup-Seite), lädt den
|
npm install
|
||||||
Screenshot als Issue-Attachment hoch und merkt sich den Reporter.
|
npm run dev # Bot + API auf :3080 (Werte aus .env)
|
||||||
Wird das Issue in Gitea **geschlossen**, bekommt der Reporter automatisch
|
```
|
||||||
eine DM („Dein Bug ist behoben ✅").
|
|
||||||
|
|
||||||
Setup:
|
Frontend mit Hot-Reload:
|
||||||
1. Gitea → Einstellungen → Anwendungen → **Token erzeugen** (Scope `write:issue`)
|
|
||||||
→ als `GITEA_API_TOKEN` in die Env
|
|
||||||
2. Im Gitea-Webhook zusätzlich das Trigger-Event **„Issues"** aktivieren
|
|
||||||
(für die Rückkanal-DMs)
|
|
||||||
|
|
||||||
**Auto-Threads:** Unter jedem Devlog-Post öffnet der Bot einen Diskussions-Thread
|
|
||||||
(„💬 Devlog 23.07.", Auto-Archiv nach 3 Tagen). Abschaltbar auf der Setup-Seite.
|
|
||||||
Der Bot braucht im Devlog-Kanal die Berechtigung **„Öffentliche Threads erstellen"**.
|
|
||||||
|
|
||||||
**Watchdog:** Auf der Setup-Seite URLs eintragen (kommagetrennt, z. B.
|
|
||||||
`https://git.d4rkst3r.de, https://bot.d4rkst3r.de/health`) — der Bot prüft sie
|
|
||||||
alle 2 Minuten und schickt dir bei Ausfall (2 Fehlschläge in Folge) eine
|
|
||||||
**Discord-DM**, inkl. Entwarnung mit Downtime-Dauer.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Setup: Webinterface
|
|
||||||
|
|
||||||
**Zugriffsmodell:** Devlog-Archiv ist öffentlich (wie der Discord-Kanal),
|
|
||||||
die Commit-Seite erfordert Discord-Login und ist auf deine Discord-ID beschränkt.
|
|
||||||
|
|
||||||
### 1. OAuth2 im Developer Portal konfigurieren
|
|
||||||
1. [Developer Portal](https://discord.com/developers/applications) → deine App → **OAuth2**
|
|
||||||
2. **Client Secret** kopieren (ggf. „Reset Secret") → `DISCORD_CLIENT_SECRET`
|
|
||||||
3. Unter **Redirects** BEIDE URLs eintragen:
|
|
||||||
- `https://bot.d4rkst3r.de/auth/callback` (Produktion)
|
|
||||||
- `http://localhost:3080/auth/callback` (lokale Entwicklung)
|
|
||||||
|
|
||||||
### 2. Neue .env-Werte
|
|
||||||
| Variable | Woher |
|
|
||||||
|---|---|
|
|
||||||
| `DISCORD_CLIENT_SECRET` | Developer Portal → OAuth2 (Schritt 1) |
|
|
||||||
| `SESSION_SECRET` | Generieren: `node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"` |
|
|
||||||
| `ADMIN_DISCORD_ID` | Discord: Rechtsklick auf deinen Namen → **Benutzer-ID kopieren** |
|
|
||||||
| `PUBLIC_URL` | Produktion: `https://bot.d4rkst3r.de` · lokal: `http://localhost:3080` |
|
|
||||||
|
|
||||||
### 3. Frontend lokal entwickeln
|
|
||||||
```
|
```
|
||||||
cd frontend
|
cd frontend
|
||||||
npm install
|
npm install
|
||||||
npm run dev # Vite-Dev-Server auf :5173, proxied /api + /auth zum Bot auf :3080
|
npm run dev # Vite auf :5173, proxied /api + /auth → :3080
|
||||||
```
|
```
|
||||||
Für den „Produktions-Look" lokal: `npm run build` im frontend/-Ordner —
|
Alternativ `npm run build` im frontend/ — der Bot liefert `frontend/dist`
|
||||||
der Bot liefert `frontend/dist` dann selbst unter `http://localhost:3080` aus.
|
dann selbst unter :3080 aus (so läuft es auch im Container, Multi-Stage-Build).
|
||||||
Im Docker-Image wird das Frontend automatisch mitgebaut (Multi-Stage).
|
|
||||||
|
|
||||||
---
|
Commit-Feed ohne Gitea testen (signierte Fake-Testzustellung):
|
||||||
|
|
||||||
## 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
|
node tools/test-webhook.mjs
|
||||||
```
|
```
|
||||||
→ Embed erscheint im Commit-Kanal, Commit landet in der lokalen SQLite (`data/ecobot.db`).
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Deployment (Docker / Portainer)
|
## HTTP-Endpoints
|
||||||
|
|
||||||
### Variante A: Portainer-Stack aus Git (empfohlen)
|
| Route | Auth | Zweck |
|
||||||
1. Portainer → **Stacks** → **Add stack** → Name: `ecobot`
|
|---|---|---|
|
||||||
2. Build method: **Repository**
|
| `GET /health` | — | Healthcheck |
|
||||||
- Repository URL: `https://git.d4rkst3r.de/D4rkst3r/ecobot`
|
| `POST /webhooks/gitea` | HMAC-Signatur | Push / Release / Issues von Gitea |
|
||||||
- Repository reference: `refs/heads/main`
|
| `POST /webhooks/devlog/:secret` | Secret im Pfad | Devlog von devlog.py (JSON/Multipart) |
|
||||||
- Compose path: `docker-compose.yml`
|
| `GET /api/devlogs?page=&q=` | — | Archiv + FTS5-Volltextsuche |
|
||||||
- Falls das Repo privat ist: **Authentication** aktivieren —
|
| `GET /api/releases?page=` | — | Changelog |
|
||||||
Username: `D4rkst3r`, Password: ein Gitea-Token
|
| `GET /feed.xml` | — | RSS |
|
||||||
(Gitea → Einstellungen → Anwendungen → Token erzeugen, Scope `read:repository`)
|
| `GET /devlog-assets/*` | — | Lokal gespeicherte Devlog-Bilder |
|
||||||
3. Unter **Environment variables** → **Advanced mode** die Werte aus der lokalen `.env`
|
| `GET/PUT /api/settings`, `POST /api/settings/test/:target` | Admin | Setup-Seite |
|
||||||
eintragen (`DISCORD_TOKEN`, `DISCORD_CLIENT_ID`, `DISCORD_GUILD_ID`,
|
| `GET /api/commits?page=` · `DELETE /api/devlogs/:id` | Admin | Commit-Archiv · Devlog löschen |
|
||||||
`COMMIT_CHANNEL_ID`, `GITEA_WEBHOOK_SECRET`)
|
| `GET /auth/login` · `/auth/callback` · `/auth/logout` | — | Discord-OAuth2 |
|
||||||
4. **Deploy the stack**
|
|
||||||
|
|
||||||
Updates später: Stack öffnen → **Pull and redeploy** (holt den neuesten Stand von `main`).
|
Devlogs, die in Discord gelöscht werden, verschwinden automatisch auch aus dem
|
||||||
|
Archiv (MessageDelete-Sync) — zusätzlich gibt es den ✕-Button für Admins auf der Webseite.
|
||||||
### 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
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -260,30 +193,36 @@ docker logs -f ecobot
|
|||||||
```
|
```
|
||||||
ecobot/
|
ecobot/
|
||||||
├── src/
|
├── src/
|
||||||
│ ├── index.js # Einstiegspunkt (Bot + Webserver)
|
│ ├── index.js # Start: Bot, Webserver, Wochen-Rückblick, Watchdog
|
||||||
│ ├── config.js # Env-Konfiguration mit Validierung
|
│ ├── config.js # Env-Konfiguration mit Validierung
|
||||||
│ ├── db.js # SQLite (better-sqlite3), Schema + Queries
|
│ ├── db.js # SQLite: Schema, Migrationen, FTS5, alle Queries
|
||||||
|
│ ├── runtime-settings.js # Effektive Settings (DB vor Env)
|
||||||
|
│ ├── gitea-api.js # Gitea-REST (Issues + Assets für /bug)
|
||||||
│ ├── bot/
|
│ ├── bot/
|
||||||
│ │ ├── client.js # Discord-Client, Command-Registry, Interactions, Devlog-Listener
|
│ │ ├── client.js # Discord-Client, Commands, Listener (Devlog, Delete, Buttons)
|
||||||
│ │ ├── commit-feed.js # Push → Discord-Embed
|
│ │ ├── commit-feed.js # Push → Embed
|
||||||
│ │ ├── devlog-archive.js # Webhook-Nachricht → SQLite
|
│ │ ├── release-feed.js # Release → Ankündigungs-Embed
|
||||||
│ │ └── commands/
|
│ │ ├── devlog-archive.js # Nachricht → SQLite (+ Bild-Download)
|
||||||
│ │ ├── ping.js # /ping — Lebenszeichen
|
│ │ ├── weekly-recap.js # Sonntags-Zusammenfassung + Scheduler
|
||||||
│ │ └── devlog-backfill.js # /devlog-backfill — Historie archivieren (Admin)
|
│ │ ├── watchdog.js # URL-Checks + DM-Alarm
|
||||||
|
│ │ └── commands/ # ping, devlog-backfill, bug
|
||||||
│ └── web/
|
│ └── web/
|
||||||
│ ├── server.js # Fastify: Webhook, Static-Serving, SPA-Fallback
|
│ ├── server.js # Fastify: Webhooks, Static, SPA-Fallback
|
||||||
│ ├── auth.js # Discord-OAuth2-Flow + Session-Cookies
|
│ ├── auth.js # Discord-OAuth2 + Session-Cookies
|
||||||
│ └── api.js # REST-API: /api/me, /api/devlogs, /api/commits
|
│ ├── api.js # REST-API + Settings + RSS
|
||||||
├── frontend/ # React + Vite (Devlogs öffentlich, Commits admin-only)
|
│ └── devlog-endpoint.js# Devlog-Post: Embed, Bilder, Ping, Thread, Archiv
|
||||||
|
├── frontend/ # React + Vite (D4RKST3R-Design)
|
||||||
│ └── src/
|
│ └── src/
|
||||||
│ ├── App.jsx # Layout, Router, Login-Status
|
│ ├── App.jsx # Layout, Router, Nav, Login-Status
|
||||||
│ ├── markdown.jsx # Mini-Markdown-Renderer für Devlog-Prosa
|
│ ├── markdown.jsx # Mini-Markdown (fett/kursiv/Code/Links/Listen/---/##)
|
||||||
│ └── pages/ # Devlogs.jsx, Commits.jsx
|
│ └── pages/ # Devlogs, Changelog, Commits, Settings
|
||||||
├── .env.example # Vorlage für Secrets (nach .env kopieren)
|
├── tools/test-webhook.mjs # Lokaler Commit-Feed-Test
|
||||||
├── Dockerfile # Multi-Stage: Frontend-Build + Runtime
|
├── .env.example # Vorlage für alle Env-Variablen
|
||||||
├── docker-compose.yml
|
├── Dockerfile # Multi-Stage: Frontend-Build + node:22-slim Runtime
|
||||||
└── README.md
|
└── docker-compose.yml # Portainer-ready, Volume ecobot_data, TZ
|
||||||
```
|
```
|
||||||
|
|
||||||
Neue Slash-Commands: Datei in `src/bot/commands/` anlegen (exportiert `data` + `execute`)
|
**Neue Slash-Commands:** Datei in `src/bot/commands/` (exportiert `data` + `execute`)
|
||||||
und in `src/bot/client.js` bei `commandModules` eintragen.
|
und in `client.js` bei `commandModules` eintragen.
|
||||||
|
**Neue Settings:** Key in `db.js`-Settings nutzen, Zugriff über `runtime-settings.js`,
|
||||||
|
UI in `frontend/src/pages/Settings.jsx`, GET/PUT in `src/web/api.js`.
|
||||||
|
|||||||
Reference in New Issue
Block a user