2026-08-28 14:18:58 +02:00
|
|
|
|
# Anrufmonitor
|
|
|
|
|
|
|
2026-08-28 15:51:56 +02:00
|
|
|
|
SIP-Client (Windows, .NET/C# Tray-App), der eingehende Anrufe passiv mitliest und automatisch
|
|
|
|
|
|
den passenden Kontakt aus Office 365, Google Contacts oder einem öffentlichen Verzeichnis anzeigt.
|
|
|
|
|
|
|
|
|
|
|
|
## Funktionsweise
|
|
|
|
|
|
|
|
|
|
|
|
- **SIP:** registriert sich bei der Telefonanlage/dem Provider und liest eingehende `INVITE`-Requests
|
|
|
|
|
|
passiv mit (Anrufer-Rufnummer). Es wird **nie** `Answer()` aufgerufen – der Client nimmt den Anruf
|
|
|
|
|
|
nicht an, sondern zeigt nur an, wer anruft. Voraussetzung: die Telefonanlage forkt eingehende Anrufe
|
|
|
|
|
|
an mehrere registrierte Geräte/Kontakte derselben Nebenstelle.
|
|
|
|
|
|
- **Kontakte:** werden periodisch im Hintergrund aus Office 365 (Microsoft Graph) und Google Contacts
|
|
|
|
|
|
(People API) in einen lokalen SQLite-Cache synchronisiert. Beim eingehenden Anruf wird **nur der
|
|
|
|
|
|
Cache** abgefragt (schnell, keine Live-API-Calls während des Anrufs). Ist die Nummer unbekannt, kann
|
|
|
|
|
|
optional ein öffentliches Verzeichnis per On-Demand-Reverse-Lookup gefragt werden (Ergebnis wird
|
|
|
|
|
|
ebenfalls gecacht).
|
|
|
|
|
|
- **UI:** Tray-Icon, Popup unten rechts mit Name/Firma/Nummer bei eingehendem Anruf.
|
|
|
|
|
|
|
|
|
|
|
|
## Projektstruktur
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
src/
|
|
|
|
|
|
Anrufmonitor.App/ WPF-Tray-App (Einstiegspunkt, appsettings.json)
|
|
|
|
|
|
Anrufmonitor.Sip/ Passiver SIP-Monitor (SIPSorcery)
|
|
|
|
|
|
Anrufmonitor.Contacts/ Kontakt-Provider, SQLite-Cache, Lookup-Service
|
|
|
|
|
|
tests/
|
|
|
|
|
|
Anrufmonitor.Tests/ xUnit-Tests
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## Bauen & Starten
|
|
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
|
dotnet build Anrufmonitor.slnx
|
|
|
|
|
|
dotnet test tests\Anrufmonitor.Tests\Anrufmonitor.Tests.csproj
|
|
|
|
|
|
dotnet run --project src\Anrufmonitor.App\Anrufmonitor.App.csproj
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-08-28 18:12:43 +02:00
|
|
|
|
## Autostart (Windows)
|
|
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
|
.\scripts\setup-autostart.ps1
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Baut eine Release-Version und legt eine Verknuepfung im Windows-Autostart-Ordner an
|
|
|
|
|
|
(`shell:startup`). Idempotent, kann nach jedem Update erneut ausgefuehrt werden.
|
|
|
|
|
|
|
2026-08-28 15:51:56 +02:00
|
|
|
|
## Konfiguration
|
|
|
|
|
|
|
|
|
|
|
|
`src\Anrufmonitor.App\appsettings.json` enthält nur die Struktur (keine Secrets, wird committet).
|
|
|
|
|
|
Für echte Werte `appsettings.Local.json.example` nach `appsettings.Local.json` kopieren
|
|
|
|
|
|
(liegt in `.gitignore`, wird beim Build automatisch mitkopiert falls vorhanden) und ausfüllen:
|
|
|
|
|
|
|
|
|
|
|
|
- **Sip:** Server, Username, Password der Telefonanlage.
|
2026-08-28 18:12:43 +02:00
|
|
|
|
- **Contacts:Office365Accounts:** Liste von Office365/Outlook-Accounts (Firmen-Tenant und/oder
|
|
|
|
|
|
outlook.com/persoenliche Konten koennen parallel laufen). Pro Account: App-Registration in
|
|
|
|
|
|
Azure/Entra (Typ *Public client*, Delegated Permission `Contacts.Read`), `Name`/`TenantId`/`ClientId`
|
|
|
|
|
|
eintragen. Fuer outlook.com: `TenantId: "common"` oder `"consumers"`, und die App-Registration muss
|
|
|
|
|
|
unter Authentifizierung -> Unterstuetzte Kontotypen auch persoenliche Microsoft-Konten erlauben.
|
|
|
|
|
|
Anmeldung per Device-Code-Flow (Code wird per Tray-Benachrichtigung und im Log angezeigt, unter
|
|
|
|
|
|
microsoft.com/devicelogin eingeben). Login und Kontakt-Cache sind pro Account getrennt.
|
2026-08-28 15:51:56 +02:00
|
|
|
|
- **Contacts:Google:** OAuth-Client (Typ *Desktop app*) in der Google Cloud Console, People API
|
|
|
|
|
|
aktivieren, `ClientId`/`ClientSecret` eintragen. Anmeldung per Browser-Login beim ersten Sync,
|
|
|
|
|
|
Token wird danach lokal zwischengespeichert.
|
|
|
|
|
|
- **Contacts:PublicDirectory:** optional, generisches URL-Template (`{number}` wird ersetzt) für
|
|
|
|
|
|
ein öffentliches Verzeichnis – muss je nach Anbieter angepasst werden
|
|
|
|
|
|
(`PublicDirectoryLookupProvider.ExtractDisplayName`).
|
2026-08-28 14:18:58 +02:00
|
|
|
|
|
|
|
|
|
|
## Sicherheit
|
|
|
|
|
|
|
|
|
|
|
|
**Public Repo** – niemals Zugangsdaten, Tokens, Client-Secrets oder SIP-Passwörter committen.
|
2026-08-28 15:51:56 +02:00
|
|
|
|
Konfiguration ausschließlich über `appsettings.Local.json` (gitignored) oder Umgebungsvariablen.
|
2026-08-28 14:18:58 +02:00
|
|
|
|
|
|
|
|
|
|
## Lizenz
|
|
|
|
|
|
|
|
|
|
|
|
TBD
|