feat: notification bridge + webhook system

- New: android-notification-listener/ — Kotlin app vangt WhatsApp-notificaties
- New: POST /webhooks/whatsapp/incoming — ontvangt berichten van de Android-app
- New: POST /webhooks/subscribe + GET /webhooks/subscribers — fan-out
- Updated: docker-compose.yml met WEBHOOK_SHARED_SECRET
- Updated: README met volledige documentatie
This commit is contained in:
Eddy de Vink 2026-07-22 20:57:57 +02:00
commit 5b7bc23648

122
README.md
View file

@ -352,6 +352,121 @@ docker restart wa-appium-api
---
## Android Notification Bridge (event-driven)
Dit systeem maakt **real-time** notificatie van binnenkomende WhatsApp-berichten
mogelijk zonder te pollen via Appium. Het bestaat uit twee componenten:
```
WhatsApp → Android Notification → listener-app (APK) → HTTP POST → wa-appium-api → subscribers
```
### Architectuur
1. **Android app** (`android-notification-listener/`) luistert naar WhatsApp-notificaties
2. Bij elk bericht stuurt de app een HTTP POST naar de API-container
3. De API valideert het gedeelde secret en stuurt het bericht door naar subscribers
4. Subscribers registreren zich via een apart endpoint
### Android-app: bouwen en installeren
**Builden** (vereist Android SDK lokaal of op een build-server):
```bash
cd android-notification-listener
./gradlew assembleDebug
adb install app/build/outputs/apk/debug/app-debug.apk
```
Als `gradlew` niet bestaat, genereer het eerst:
```bash
gradle wrapper --gradle-version 8.5
```
**Notificatietoegang verlenen** (eenmalig via ADB):
```bash
adb shell settings put secure enabled_notification_listeners \
com.eddydevink.whatsapplistener/com.eddydevink.whatsapplistener.WhatsAppNotificationListener
```
Verifiëren:
```bash
adb shell settings get secure enabled_notification_listeners
# moet de package/service naam bevatten
```
**Configureren:** open de app op de telefoon ("WA Notification Bridge"),
vul het webhook-URL en shared secret in.
### Webhook configuratie (API-zijde)
Zet in `.env` of als environment variable:
```bash
WEBHOOK_SHARED_SECRET=verander-mij # moet gelijk zijn aan de Android-app
```
### Webhook endpoints
#### `POST /webhooks/whatsapp/incoming`
Ontvangt berichten van de Android notification-listener.
```bash
curl -X POST http://127.0.0.1:3010/webhooks/whatsapp/incoming \
-H 'Content-Type: application/json' \
-H 'X-Webhook-Secret: verander-mij' \
-d '{
"sender": "+31 6 12345678",
"text": "Hallo!",
"chatId": "Eddy de Vink",
"timestamp": 1700000000000
}'
```
| Header | Waarde |
|--------|--------|
| `X-Webhook-Secret` | Gedeeld geheim (moet matchen met `WEBHOOK_SHARED_SECRET`) |
| Veld | Type | Verplicht | Beschrijving |
|------|------|-----------|-------------|
| `sender` | string | ja | Naam of nummer van afzender |
| `text` | string | ja | Berichttekst |
| `chatId` | string | ja | Chat-naam zoals getoond in notificatie |
| `timestamp` | long | nee | Unix timestamp (ms) |
#### `POST /webhooks/subscribe`
Registreer een subscriber (interne service die notificaties wil ontvangen).
```bash
curl -X POST http://127.0.0.1:3010/webhooks/subscribe \
-H 'Content-Type: application/json' \
-d '{"url": "http://192.168.5.252:3003/webhook"}'
```
#### `GET /webhooks/subscribers`
Lijst van actieve subscribers.
```bash
curl http://127.0.0.1:3010/webhooks/subscribers
```
### Beperkingen
- **Samengevoegde notificaties:** als meerdere berichten in dezelfde chat
binnenkomen voordat de eerste is verwerkt, kan Android één samengevoegde
notificatie sturen. De listener verwerkt dan alle `messages` uit de
`MessagingStyle`, dus individuele berichten gaan niet verloren.
- **Alleen push-notificaties:** berichten die binnenkomen terwijl de app
open is (dus geen notificatie genereren) worden niet gevangen. Gebruik
dan Appium-polling als aanvulling.
- **Eén telefoon, één listener:** de app luistert naar alle chats.
---
## Onderhoud
### Rebuild en restart
@ -399,6 +514,13 @@ docker exec appium-adb adb shell dumpsys deviceidle disable
│ └── server.js # Express REST API
├── smoke-test.js # Node.js smoke-test (geen dependencies)
├── .env.example # Voorbeeld env-variabelen
├── android-notification-listener/ # Android-app: notificaties → webhook
│ ├── app/src/main/java/.../ # Kotlin broncode
│ │ ├── SettingsActivity.kt
│ │ ├── WhatsAppNotificationListener.kt
│ │ └── WebhookClient.kt
│ ├── build.gradle.kts
│ └── settings.gradle.kts
└── README.md # Dit bestand
```