main
💸 WhoPays - Who Pays Next?
Ein einfaches, elegantes Tool um zu entscheiden, wer als nächstes zahlt - mit Discord-Benachrichtigungen und PWA-Support!
🎯 Features
- ✅ Wechsel zwischen zwei Personen - Einfacher Button-Klick
- 🎨 Individuelle Farben & Namen - Komplett anpassbar
- 📝 Grund-Angabe - Optional Grund für den Wechsel angeben
- 🔔 Discord-Benachrichtigungen - Automatische Webhooks mit farbigen Embeds
- 💾 Persistenter Speicher - Letzter Grund bleibt nach Container-Restart erhalten
- 📱 PWA-Support - Als App auf Handy & Desktop installierbar
- 🎭 Animierte Übergänge - Smooth Hintergrund- und Profilbild-Wechsel
- 🐳 Docker-Ready - Einfache Deployment mit Docker Compose
- 🔒 Reverse-Proxy kompatibel - Funktioniert mit Nginx, Caddy, Traefik, etc.
🚀 Quick Start
Voraussetzungen
- Docker & Docker Compose
- Discord Webhook URL (optional)
- Profilbilder (a.png, b.png)
- Hintergrundbilder (bgA.jpg, bgB.jpg)
Installation
# 1. Repository klonen oder Dateien herunterladen
git clone https://github.com/dein-username/whopays.git
cd whopays
# 2. Bilder hinzufügen
cp deine-bilder/* img/
# 3. config.js anpassen (siehe Konfiguration)
nano config.js
# 4. Docker Container starten
docker-compose up -d
# 5. Öffne http://localhost:3000
Das war's! 🎉
⚙️ Konfiguration
config.js - Zentrale Konfiguration
Alle Einstellungen sind in einer Datei:
// config.js
export const CONFIG = {
A: {
name: "Alice", // Name Person A
colorHex: "#2ecc71", // Farbe im Web (Grün)
colorDiscord: 0x2ecc71, // Farbe in Discord (gleich!)
icon: "a.png", // Profilbild
background: "bgA.jpg" // Hintergrundbild
},
B: {
name: "Bob", // Name Person B
colorHex: "#e74c3c", // Farbe im Web (Rot)
colorDiscord: 0xe74c3c, // Farbe in Discord (gleich!)
icon: "b.png", // Profilbild
background: "bgB.jpg" // Hintergrundbild
}
};
// Discord Webhook (optional)
export const DISCORD_WEBHOOK_URL = "https://discord.com/api/webhooks/...";
// Öffentliche URL (für Discord Thumbnails)
export const PUBLIC_BASE_URL = "https://your-domain.com";
Farben ändern
// Blau & Orange
A: { colorHex: "#3498db", colorDiscord: 0x3498db }
B: { colorHex: "#e67e22", colorDiscord: 0xe67e22 }
// Lila & Pink
A: { colorHex: "#9b59b6", colorDiscord: 0x9b59b6 }
B: { colorHex: "#e91e63", colorDiscord: 0xe91e63 }
// Türkis & Gold
A: { colorHex: "#1abc9c", colorDiscord: 0x1abc9c }
B: { colorHex: "#f39c12", colorDiscord: 0xf39c12 }
Wichtig: Hex-Farbe muss genau 6 Zeichen haben (0-9, A-F)!
📂 Projektstruktur
whopays/
├── config.js # Zentrale Konfiguration
├── server.js # Express Server
├── package.json # Node.js Dependencies
├── Dockerfile # Docker Build Instructions
├── docker-compose.yml # Docker Compose Config
├── state.json # Persistent State (auto-generiert)
│
└── public/ # Statische Dateien
├── index.html # Frontend HTML
├── script.js # Frontend JavaScript
├── style.css # CSS Animationen
├── manifest.json # PWA Manifest
├── service-worker.js # PWA Service Worker
│
└── img/ # Bilder
├── a.png # Profilbild Person A
├── b.png # Profilbild Person B
├── bgA.jpg # Hintergrund Person A
├── bgB.jpg # Hintergrund Person B
├── icon-192.png # PWA Icon (192x192)
└── icon-512.png # PWA Icon (512x512)
🐳 Docker Deployment
docker-compose.yml
version: '3.8'
services:
whopays:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- PORT=3000
- PUBLIC_BASE_URL=https://your-domain.com
- DISCORD_WEBHOOK_URL = "https://discord.com/api/webhooks/...";
volumes:
# Bilder (persistent)
- ./img:/app/public/img
# State (persistent über Neustarts)
- ./state.json:/app/state.json
restart: unless-stopped
Befehle
# Container starten
docker-compose up -d
# Logs anschauen
docker-compose logs -f
# Container neustarten
docker-compose restart
# Container stoppen
docker-compose down
# Neu bauen (nach Code-Änderungen)
docker-compose down
docker-compose build --no-cache
docker-compose up -d
📱 PWA Installation
iOS (Safari)
- Öffne die Website in Safari
- Tippe auf das Teilen-Symbol (⎙)
- Scrolle und tippe "Zum Home-Bildschirm"
- Tippe "Hinzufügen"
Android (Chrome)
- Öffne die Website in Chrome
- Tippe auf Menü (⋮)
- Tippe "App installieren"
- Tippe "Installieren"
Desktop (Chrome/Edge)
- Öffne die Website
- Klicke auf das ⊕ Icon in der Adressleiste
- Oder: Menü → "WhoPays installieren"
Wichtig: PWA funktioniert nur über HTTPS (oder localhost)!
🔒 Reverse Proxy Setup
Nginx
server {
listen 443 ssl http2;
server_name whopays.your-domain.com;
# PWA Files - NO AUTH
location ~ ^/(service-worker\.js|manifest\.json)$ {
proxy_pass http://localhost:3000;
proxy_set_header X-Forwarded-Proto $scheme;
add_header Service-Worker-Allowed "/" always;
}
# Main app
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Caddy (Einfachste Option!)
whopays.your-domain.com {
reverse_proxy localhost:3000
}
Caddy macht automatisch HTTPS mit Let's Encrypt! ✅
🔧 API Endpoints
GET /status
curl http://localhost:3000/status
Response:
{
"current": "A",
"lastReason": "Pizza bestellt"
}
POST /toggle
curl -X POST http://localhost:3000/toggle \
-H "Content-Type: application/json" \
-d '{"reason":"Kaffee trinken"}'
Response:
{
"current": "B",
"name": "Bob",
"lastReason": "Kaffee trinken"
}
GET /config
curl http://localhost:3000/config
🐛 Troubleshooting
PWA lässt sich nicht installieren
- Stelle sicher, dass du HTTPS verwendest
- Prüfe ob
manifest.jsonerreichbar ist - Icons müssen existieren:
icon-192.pngundicon-512.png
Discord sendet keine Benachrichtigungen
- Prüfe Webhook URL in
config.js - Logs prüfen:
docker-compose logs | grep Discord - Stelle sicher
PUBLIC_BASE_URList korrekt
Bilder werden nicht angezeigt
- Prüfe ob Bilder in
/img/existieren - Berechtigungen:
chmod -R 755 img/ - Container neu starten
Farbe in Discord ungültig (HTTP 400)
- Hex-Farbe muss genau 6 Zeichen haben
- ✅ Richtig:
0x2ecc71 - ❌ Falsch:
0x2ecc71c(extra Buchstabe!)
📊 Features im Detail
Persistent Storage
{
"current": "A",
"lastReason": "Restaurant bezahlt"
}
Bleibt erhalten durch Docker Volume Mount.
Smooth Animations
- Rotation-Animation (0.6s)
- Background-Transition (0.6s)
- Farb-Übergang (0.3s)
- Image Preloading
📜 Lizenz
MIT License - Frei nutzbar!
💡 Tipps
Custom Domain mit Let's Encrypt
sudo certbot --nginx -d whopays.your-domain.com
Mehrere Instanzen
Unterschiedliche Ports in docker-compose.yml für mehrere Apps!
Viel Spaß beim Entscheiden, wer zahlt! 🎉💸
Languages
JavaScript
78.2%
HTML
17.2%
CSS
3.2%
Dockerfile
1.4%