# TeamPulse — Design-Dokument **Datum:** 2026-05-16 **Status:** Zur Implementierung freigegeben --- ## Ziel Ein Python-Script, das den Chat eines laufenden Microsoft Teams-Meetings überwacht, alle Personen erfasst, die in einem definierten Zeitfenster eine Nachricht gepostet haben, und ein Memo mit Name und E-Mail-Adresse der Teilnehmer erzeugt. Ausgangslage: Nutzer ohne Admin-Rechte, kein Zugriff auf Microsoft Graph API / Azure AD App-Registrierung. --- ## Architektur ``` main.py ├── auth.py — Playwright-Session verwalten (Login, Persistenz) ├── monitor.py — Teams-Chat pollen, Trigger erkennen, Nachrichten sammeln ├── resolver.py — Sender-Name → E-Mail via Profilkarte (mit lokalem Cache) └── memo.py — Markdown-Memo erzeugen und speichern ``` --- ## Komponenten ### `auth.py` - Startet Playwright mit persistentem User-Data-Verzeichnis (`~/.teampulse/session`) - Beim ersten Start: sichtbares Browser-Fenster für manuellen SSO/MFA-Login - Bei bekannter Session: headless, unsichtbar im Hintergrund - Erkennt Session-Ablauf (Login-Redirect) und öffnet Browser-Fenster zur Re-Authentifizierung - Liest beim Start den Display-Namen des eingeloggten Nutzers aus → wird als „Moderator" gespeichert ### `monitor.py` - Öffnet Teams Web im Hintergrund-Browser - Nutzer navigiert einmalig manuell zur Meeting-Chat-URL - Pollt den Chat-DOM alle ~2 Sekunden auf neue Nachrichten - Erkennt Trigger-Befehle (nur wenn gepostet vom eingeloggten Nutzer): - `!start "Name des Vortragenden"` → startet Zeitfenster, speichert Vortragendenname - `!stop` → beendet Zeitfenster - Fallback: Enter-Taste in der Konsole als alternativer Trigger - Sammelt während des Zeitfensters: `{ sender: str, timestamp: str }` - Reconnect-Logik bei Seitenreload oder Verbindungsverlust (gesammelte Daten bleiben erhalten) ### `resolver.py` - Iteriert nach `!stop` über alle eindeutigen Sender - Prüft `~/.teampulse/cache.json` — bekannte Namen werden nicht erneut aufgelöst - Für unbekannte Sender: klickt Profilkarte im Teams-Web → extrahiert E-Mail - Fehlerbehandlung: - Profilkarte nicht ladbar → `` - Externer Gast → als Gast markieren: `` oder `` - Cache wird bei jedem neuen Eintrag sofort geschrieben ### `memo.py` - Filtert Vortragenden und Moderator aus der Teilnehmerliste - Sortiert verbleibende Einträge nach E-Mail-Adresse - Erzeugt Markdown-Ausgabe (siehe Format unten) - Speichert Datei als `audit_YYYYMMDD_HHMM.md` im aktuellen Verzeichnis - Gibt Inhalt zusätzlich in der Konsole aus --- ## Trigger-Verhalten | Aktion | Chat-Befehl | Konsole | |---|---|---| | Zeitfenster starten | `!start "Anna Bauer"` | Enter drücken | | Zeitfenster beenden | `!stop` | Enter drücken | - Nur Befehle vom eingeloggten Nutzer werden als Trigger akzeptiert - `!start` ohne Anführungszeichen oder ohne Namen → Warnung, Zeitfenster startet mit Platzhalter „Unbekannter Vortragender" - Mehrfaches `!start` ohne `!stop` → zweites `!start` überschreibt das erste (kein Fehler) --- ## Ausgabeformat ```markdown # Meeting Chat Audit Zeitfenster: 10:03:42 – 10:47:15 ## Teilnehmer am Vortrag von Anna Bauer (4) _Moderator: Oliver Hofmann — Vortragender und Moderator ausgeschlossen_ - Klaus Huber - Max Mustermann - Sandra Vogel - Thomas Wolf _Sortiert nach E-Mail-Adresse. Erstellt: 2026-05-16 10:51_ ``` - Keine Nachrichten im Zeitfenster → Hinweis „Keine Chat-Aktivität in diesem Zeitfenster" - Nicht auflösbare E-Mails → Eintrag trotzdem aufgeführt, E-Mail als `` --- ## Technologie-Stack | Komponente | Wahl | |---|---| | Sprache | Python 3.12 (`.venv`) | | Browser-Automation | Playwright (sync API) | | Cache | JSON-Datei (`~/.teampulse/cache.json`) | | Ausgabe | Markdown | | Plattform | Mac, Windows, Linux | --- ## Randfälle | Situation | Verhalten | |---|---| | Session abgelaufen | Sichtbarer Browser für Re-Auth, danach wieder headless | | Profilkarte nicht ladbar | ``, kein Absturz | | Externer Gast | Als Gast markiert | | `!start` ohne Namen | Warnung + Platzhalter | | `!start` von anderem Nutzer | Ignoriert | | Seitenreload während Monitoring | Automatischer Reconnect, keine Datenverlust | | Keine Nachrichten im Fenster | Memo mit entsprechendem Hinweis | --- ## Nicht im Scope - Graph API / Azure AD Integration - GUI / Web-Dashboard - Mehrere gleichzeitige Zeitfenster - Historische Chat-Auswertung (vergangene Meetings)