diff --git a/docs/04-roadmap.md b/docs/04-roadmap.md index 113ea14..4df9dde 100644 --- a/docs/04-roadmap.md +++ b/docs/04-roadmap.md @@ -22,6 +22,8 @@ und Chat sowie Zuschauerzahlen vollständig in der DB stehen. - [ ] Community-Modul: Begrüßungslogik, Cooldowns, `!notiz` - [ ] Overlay-Seite `/overlay/community` (Chatter-Hinweis für Abdu) - [ ] `apps/broadcaster`: Discord + Bluesky, Story-Bild-Generator + (Discord-Seite ist fertig: Server, Kanal und Webhook liegen bereit, + siehe [`projects/discord-community.md`](projects/discord-community.md)) - [ ] Draft-Modus, Kill-Switch, Doppelpost-Schutz **Fertig, wenn:** Erstchatter werden erkannt und begrüßt, Stream-Start wird diff --git a/docs/handoff.md b/docs/handoff.md index 9b6c255..c5aeafd 100644 --- a/docs/handoff.md +++ b/docs/handoff.md @@ -1,8 +1,8 @@ # Übergabe -Stand **2026-09-09**, Version 0.5.4. Wer hier weitermacht, liest zuerst diese -Seite, dann [`07-mvp-plan.md`](07-mvp-plan.md). Für Abdu selbst gibt es das -[Handbuch](handbuch/handbuch.pdf). +Stand **2026-09-15**, letztes gebautes Paket 0.5.4. Wer hier weitermacht, +liest zuerst diese Seite, dann [`07-mvp-plan.md`](07-mvp-plan.md). Für Abdu +selbst gibt es das [Handbuch](handbuch/handbuch.pdf). ## Wo das Projekt steht @@ -20,9 +20,35 @@ Auslöser bis zum fertigen Short steht im Code vollständig. Geprüft ist sie | S5 Onboarding + Sichtung | offen | | | S6 Erstchatter-Begrüßung | offen | | -93 Tests, alle grün. Was noch fehlt, steht vollständig in +162 Tests, alle grün. Was noch fehlt, steht vollständig in [`offene-punkte.md`](offene-punkte.md). +## Der Discord-Server steht + +Dazugekommen seit der letzten Übergabe, und kein Teil des MVP: der +Community-Server ist eingerichtet, und zwar als Code statt von Hand. Der +Bauplan liegt in [`packages/discord/src/plan.ts`](../packages/discord/src/plan.ts), +aufgetragen wird er mit `abdulive discord:setup`. Wiederholbar: gefunden wird +über Namen und frühere Namen, danach wird angeglichen. Der zweite Lauf ändert +nichts, gelöscht wird nie. + +Das ist Vorarbeit für drei Werkzeuge. Die Webhooks für +[Go-Live](projects/go-live-broadcaster.md), [Recap](projects/stream-recap.md) +und [Clips](projects/clip-shorts.md) liegen fertig im verschlüsselten Speicher +unter `goLiveWebhook`, `recapWebhook` und `clipsWebhook`. Wer diese Werkzeuge +baut, muss sich um Discord nicht mehr kümmern, sondern nur noch posten. + +Sieben Kanäle, vier Rollen, zwei AutoMod-Regeln. Der Entwurf und seine +Begründung stehen in [`projects/discord-community.md`](projects/discord-community.md); +die Kurzfassung ist, dass bei 5 bis 30 Zuschauern fünf sichtbare Kanäle besser +sind als zwanzig leere. + +Ein Teil davon läuft dauerhaft: der Knopf unter dem Willkommenstext, mit dem +man sich die Rolle `Live-Ping` selbst gibt. Er hängt als Gateway-Verbindung im +Ingest-Daemon mit drin und meldet sich als `discordConnected` auf der +Statusseite. **Läuft der Daemon nicht, tut der Knopf nichts** - der Klick +läuft dann in Discords Zeitüberschreitung. + ## Was jemand wissen muss, bevor er etwas anfasst **Keine Abhängigkeiten, kein Build.** Node 24 bringt SQLite, WebSocket, @@ -44,6 +70,10 @@ Datenbank wird gesichert und weitergereicht, die Geheimnisse nicht. zur Installation, und der Updater braucht keinen Token. Es heißt aber auch: nichts Vertrauliches mehr hineinschreiben, auch nicht in die Doku. +**Es gibt zwei Remotes**, beide mit demselben Inhalt: `origin` +(`ZeasyAlex/abdulive`) und `discord` (`ZeasyAlex/abdulive_-discord`). Wer +pusht, pusht auf beide, sonst laufen sie auseinander. + Die Begründungen stehen in [`decisions/`](decisions/), acht ADRs. Wer eine davon umwerfen will, liest sie vorher. ADR-0004 (Docker) ist durch ADR-0007 ersetzt; die Analyse darin bleibt lesenswert, weil zwei der vier @@ -147,6 +177,41 @@ nicht umbricht. Deutsche Komposita sind regelmäßig breiter als das Bild. Wer die Schrift wechselt, muss `CHAR_WIDTH_RATIO` in `subtitles.ts` neu einmessen. Sonst bricht die Zeile wieder an der falschen Stelle. +## Discord: was gemessen ist + +Vier Dinge, die nicht in der Dokumentation standen, in der man zuerst sucht. +Alle am echten Server nachgeprüft. + +**Kanalnamen lassen sich nur zweimal in zehn Minuten ändern.** Danach verlangt +Discord eine Pause, gemessen wurden 529 Sekunden. Ein Einrichtungslauf, der +brav auf ein 429 wartet, steht dann neun Minuten. Der Client wartet deshalb +höchstens eine Minute, meldet den Kanal als übersprungen und macht weiter. + +**Eine Rolle kann nur Rollen unterhalb der eigenen verschieben** - auch mit +Administrator. Discord hängt die Rolle eines frisch eingeladenen Bots ganz +unten ein, also gibt es dort keinen Platz. Der erste Lauf quittierte das mit +`Missing Permissions`, was nach einem fehlenden Recht aussieht und keines ist. +`rolePositions()` rechnet den Platz jetzt aus und sagt, was zu tun ist. + +**Discords Onboarding braucht einen größeren Server.** + +``` +HTTP 400 Cannot enable onboarding, requirements are not met (350000) + +sichtbar für @everyone: 5 davon beschreibbar: 3 +Discord verlangt: 7 davon beschreibbar: 5 +``` + +Zwei Kanäle anzulegen, damit eine Schwelle passt, hätte den Server leerer +gemacht statt besser. Daher der Knopf. + +**Kanalnamen werden normalisiert, aber nicht so weit wie erwartet.** +Textkanäle werden kleingeschrieben und Leerzeichen zu Bindestrichen; Emoji, +Umlaute und das Trennzeichen `│` (U+2502) bleiben unverändert stehen. +`normalizeName()` bildet das ab. Ohne diesen Abgleich geht bei jedem Lauf +dieselbe Umbenennung erneut raus - und läuft nach zwei Läufen in das Limit von +oben. + ## Die drei Dinge, die Abdu tun muss 1. **Broadcaster-Konto verbinden.** Die beiden Twitch-Apps @@ -167,6 +232,15 @@ Dazu eine Kleinigkeit mit Wirkung: das Bot-Konto sollte Moderator sein (`/mod `). Ohne das gilt ein Limit von 20 Chat-Nachrichten je 30 Sekunden statt 100, und im Follower-only-Modus kommt der Bot gar nicht durch. +Und zwei für Discord, beide nicht über die API machbar: + +1. **Sich selbst die Rolle `Abdu` geben.** Das Skript legt Rollen an, aber es + hängt sie niemandem um. +2. **Einladungslink** ohne Ablaufdatum erzeugen und ins Twitch-Panel, in die + Kanalinfo und in einen Chat-Befehl eintragen. Ein Server, den im Stream + niemand erwähnt, bleibt leer. Das ist der eine Handgriff, an dem hängt, ob + der Server überhaupt jemanden bekommt. + ## Wo ich weitermachen würde **S2 an einem laufenden OBS abnehmen.** Das ist die einzige ungeprüfte Stelle @@ -174,6 +248,11 @@ in der ganzen Kette, und alles Weitere hängt daran. Seit es `abdulive sources` gibt, ist auch die Frage beantwortbar, welche OBS-Quelle fremden Text ins Bild malt. Das war vorher nicht zu erraten. +**Discord braucht jetzt nichts mehr.** Der Server steht, die Webhooks liegen +bereit. Wer als Nächstes `apps/broadcaster` oder `apps/recap` baut, findet +alles vor und muss nur noch posten. Das wäre auch ein guter Nebenweg, wenn der +Stream-PC gerade nicht verfügbar ist, denn anders als S2 hängt daran nichts. + **Danach S5.** Nicht wegen des Codes, sondern weil das Werkzeug ohne Sichtungsseite für Abdu nicht bedienbar ist. Die Kette funktioniert, aber sie hat keine Oberfläche, auf der man Clips durchgeht und aussortiert. @@ -198,6 +277,18 @@ konkrete Verbesserungen stehen in [`offene-punkte.md`](offene-punkte.md). Solange nur Abdu installiert, reicht ein Klick. Sobald jemand Drittes es bekommt, nicht mehr. +**Der Discord-Knopf hängt am Daemon.** Läuft der Ingest nicht, passiert beim +Klick nichts, und die klickende Person sieht nur „Interaktion fehlgeschlagen". +Das ist vertretbar, solange der Daemon ohnehin durchläuft, aber es ist eine +stille Abhängigkeit zwischen zwei Dingen, die sonst nichts miteinander zu tun +haben. + +**Der Discord-Bot ist nie unter Last gelaufen.** Getestet sind die Bausteine +und ein Klickweg gegen einen nachgebauten Server; am echten Server ist die +Verbindung nachgewiesen und der Rollenwechsel einmal in beide Richtungen +durchgespielt. Was bei gleichzeitigen Klicks oder nach Tagen Laufzeit +passiert, ist offen. + **Es gibt keine Einstellung für den OBS-Wiedergabepuffer-Ordner.** Im Container kam der Pfad über `OBS_REPLAY_DIR`, nativ fehlt der Weg. Für die Clip-Kette ist das egal, weil OBS den Pfad über WebSocket meldet. Aber diff --git a/docs/offene-punkte.md b/docs/offene-punkte.md index a493b87..e91a904 100644 --- a/docs/offene-punkte.md +++ b/docs/offene-punkte.md @@ -82,6 +82,22 @@ Der Durchlauf am echten Clip war brauchbar, aber nicht gut. Was auffiel: heraus ging das nicht. `clipper.ffmpeg.encoder` steht weiter auf `libx264`. Auf Abdus Rechner messen, ob `h264_qsv` etwas bringt. +## Discord + +- [ ] **Den Bot unter Last sehen.** Gleichzeitige Klicks auf den Rollen-Knopf + sind nie vorgekommen, ebenso wenig eine Laufzeit über Tage. Die + Gateway-Verbindung kann fortsetzen und wiederverbinden, aber beides ist + nur gegen einen nachgebauten Server geprüft. +- [ ] **Onboarding einschalten, sobald der Server groß genug ist.** Discord + verlangt sieben Vorgabekanäle mit fünf beschreibbaren, wir haben fünf und + drei. Die Frage liegt fertig auf dem Server, nur ausgeschaltet. Dann + könnte der Knopf entfallen und mit ihm die Gateway-Verbindung. +- [ ] **Twitch-Konto unter Integrationen verbinden**, damit Subs automatisch + eine Rolle bekommen. +- [ ] **Stammgast automatisch vergeben.** Bisher von Hand. Die Daten dafür + liegen längst in der Datenbank, es fehlt die Brücke zwischen + Twitch-Konto und Discord-Konto. + ## Nach dem MVP - [ ] **Spitzen-Erkennung scharf schalten.** Sie läuft mit und schreibt jeden