SpotifyRoulette/README.md

174 lines
6.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# Spotify Roulette
IDK für wen das ist, aber hier ist ein Guide, wie man das bei sich selbst aufsetzt, weil Spotify kein extended quota mode für Privatpersonen mehr erlaubt (sprich: man muss jeden Mitspieler manuell im Usermanagement eintragen).
## Wichtig vorab
- Für SpotifyLogin und Playback brauchst du eine Domain mit HTTPS. Nur IP ohne Domain funktioniert für Spotify OAuth nicht.
- Jeder Spieler muss sich einmal mit Spotify anmelden. Spotify Playback erfordert in der Regel Premium.
- Tokens und Spielzustand werden im Speicher gehalten. Neustart der App ⇒ erneute Logins nötig.
## 1\) Voraussetzungen
- Server mit Ubuntu 22\.04 \(oder ähnlich\), SSHZugang.
- Domain, ARecord zeigt auf deine ServerIP.
- Spotify Developer Konto:
- App anlegen, Client ID und Client Secret notieren.
- RedirectURI setzen, z\.B. `https://deine-domain.tld/callback`
- Jeden Mitspieler in der SpotifyApp als „User“ hinzufügen \(\*ohne extended quota\*\).
## 2\) Server vorbereiten
```bash
# System aktualisieren
sudo apt update && sudo apt upgrade -y
# Java (z.B. Temurin 21), Maven, Git, Nginx, Certbot
sudo apt install -y wget gnupg2 ca-certificates lsb-release apt-transport-https
sudo apt install -y openjdk-21-jre maven git nginx certbot python3-certbot-nginx
# Java prüfen
java -version
```
## 3\) Projekt beziehen und bauen
```bash
# In ein Verzeichnis deiner Wahl wechseln
cd /opt
sudo git clone <DEIN_REPO_URL> spotify-roulette
cd spotify-roulette
# Build (ohne Tests)
mvn -DskipTests package
# Das erzeugte JAR liegt meist unter: target/<name>-<version>.jar
ls -lh target
```
## 4\) SpotifyKonfiguration eintragen
- Suche, wo `SpotifyAuthService` erzeugt wird \(WorkspaceSuche nach `new SpotifyAuthService(`\).
- Trage dort `clientId`, `clientSecret` und `redirectUri` für deine Domain ein \(oder lies sie aus Umgebungsvariablen\).
- RedirectURI muss exakt zur Spotify Developer Console passen \(Schema, Host, Pfad\), z\.B. `https://deine-domain.tld/callback`.
Hinweis:
- Die App speichert pro Benutzer eine `SpotifyApi`\-Instanz im Speicher. `exchangeCode` im Callback muss aufgerufen werden, damit `getRecentTracks` und Playback funktionieren.
- `GameService` lädt pro Spieler die zuletzt gehörten Tracks beim Beitritt \(`getRecentTracks`\) und cached sie pro Spieler.
## 5\) App als Systemdienst einrichten
Kurz erklärt: Systemd startet deine JavaApp beim Booten neu und hält sie am Laufen.
```ini
# /etc/systemd/system/spotify-roulette.service
[Unit]
Description=Spotify Roulette
After=network.target
[Service]
User=www-data
WorkingDirectory=/opt/spotify-roulette
Environment=SPOTIFY_CLIENT_ID=<deine_id>
Environment=SPOTIFY_CLIENT_SECRET=<dein_secret>
Environment=APP_BASE_URL=https://deine-domain.tld
# Falls deine App Umgebungsvariablen liest, nutzt sie. Andernfalls Werte direkt im Code setzen.
ExecStart=/usr/bin/java -jar /opt/spotify-roulette/target/<jar-name>.jar
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
```
Aktivieren und starten:
```bash
sudo systemctl daemon-reload
sudo systemctl enable spotify-roulette
sudo systemctl start spotify-roulette
sudo systemctl status spotify-roulette --no-pager
```
## 6\) Reverse Proxy mit Nginx und HTTPS
Proxy leitet Port 80/443 auf deine App \(typisch Port 8080\). WebSockets brauchen UpgradeHeader.
```nginx
# /etc/nginx/sites-available/spotify-roulette.conf
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name deine-domain.tld;
location / {
proxy_pass http://127.0.0.1:8080; # ggf. Port an deine App anpassen
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 3600;
}
}
```
Aktivieren:
```bash
sudo ln -s /etc/nginx/sites-available/spotify-roulette.conf /etc/nginx/sites-enabled/spotify-roulette.conf
sudo nginx -t
sudo systemctl reload nginx
```
TLS Zertifikat:
```bash
sudo certbot --nginx -d deine-domain.tld --redirect
```
## 7\) Firewall \(falls aktiv\)
```bash
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo ufw status
```
## 8\) Start lokal \(Dev\)
- Spotify erlaubt `http://localhost` als RedirectURI. Füge z\.B. `http://localhost:8080/callback` in der Developer Console hinzu und setze denselben Wert im Code.
- Start:
```bash
mvn -DskipTests package
java -jar target/<jar-name>.jar
```
## 9\) Spielablauf \(UI\)
- Öffne `https://deine-domain.tld`.
- Spiel erstellen/beitreten.
- Jeder Spieler meldet sich mit Spotify an \(erforderliche Scopes: `user-read-recently-played`, `user-library-read`, `user-modify-playback-state`, `user-read-playback-state`, `streaming`\).
- Songliste lädt automatisch \(`getRecentTracks` + Fallback `getUsersSavedTracks`\).
- „Runde starten“ löst über WebSocket den Start aus. Es wird ein zufälliger Owner und ein Song aus dessen Tracks gewählt.
- Guesses über die KreisOptionen \(Mehrfachauswahl möglich\). Scoring:
- +3, wenn der ausgeählte den Song gehört hat
- 1 pro falschem Tipp
- +1 Bonus, wenn kein falscher Tipp \(fehlerfrei\)
- Ab 30 Punkten und eindeutiger Spitze: Spielende, Overlay mit Leaderboard, Scores werden auf 0 zurückgesetzt.
## 10\) Geräte & Playback
- Geräte laden: `GET /api/spotify/devices?username=<name>`
- Abspielen: `POST /api/spotify/play` mit JSON `{ "username": "<name>", "device_id": "<id>", "track_uri": "spotify:track:..." }`
- Der Track wird ab der Hälfte gestartet \(`position_ms = duration_ms / 2`\).
## 11\) API \& WS Übersicht
- `POST /api/create-game``{ username }` → erstellt Spiel, fügt Spieler hinzu.
- `POST /api/join-game``{ username, gameId }` → Spieler tritt bei.
- `GET /api/game/{gameId}/players` ⇒ Liste der Spieler.
- `POST /api/game/{gameId}/start-round` ⇒ Broadcast des Rundenstarts \(Fallback, primär via WebSocket `type: "start-round"`\).
- `POST /api/game/{gameId}/guess``{ username, guess }` \(Legacy SingleGuess; UI nutzt MultiGuess via WS\).
- WebSocket: Route mit Pfadparam `gameId` und Query `username` \(Client sendet `type: "start-round" | "submit-guesses" | "requestPlayers" | "next-round"`\).
- Server pusht `round-start`, `round-result`, `game-end`.
## 12\) Häufige Stolpersteine
- 404 oder OAuth Fehler: RedirectURI in Spotify Console muss exakt passen \(Schema, Host, Pfad\).
- Kein Start der Runde: Spieler ohne geladene Tracks → sicherstellen, dass Spotify Login erfolgreich war.
- WebSockets brechen ab: Nginx Upgrade/Connection Header wie oben setzen.
- HTTP statt HTTPS: Spotify akzeptiert im Internet i\.d\.R. nur HTTPS \(keine reine IP\).
- Tokens verloren nach Neustart: App speichert nur im Speicher. Spieler müssen sich erneut anmelden.
- manchmal kriegt man einen 24h ratelimit bann von alle oder bestimmte features von spotify nicht funktionieren
```