diff --git a/.env.example b/.env.example
index d8e6b81..5a96266 100644
--- a/.env.example
+++ b/.env.example
@@ -2,3 +2,7 @@
# TCP/IP-modus: zet PHONE_IP op het IP-adres van de telefoon
# PHONE_IP=192.168.5.100
# ADB_PORT=5555
+
+# Webhook shared secret (Android notification bridge → API)
+# Moet overeenkomen met de instelling in de Android-app
+# WEBHOOK_SHARED_SECRET=verander-mij
diff --git a/README.md b/README.md
index 61e58e0..b07bd73 100644
--- a/README.md
+++ b/README.md
@@ -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
```
diff --git a/android-notification-listener/.gitignore b/android-notification-listener/.gitignore
new file mode 100644
index 0000000..e3bdbed
--- /dev/null
+++ b/android-notification-listener/.gitignore
@@ -0,0 +1,11 @@
+*.iml
+.gradle
+/local.properties
+/.idea
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
+local.properties
+/app/build
diff --git a/android-notification-listener/app/build.gradle.kts b/android-notification-listener/app/build.gradle.kts
new file mode 100644
index 0000000..db5c124
--- /dev/null
+++ b/android-notification-listener/app/build.gradle.kts
@@ -0,0 +1,39 @@
+plugins {
+ id("com.android.application")
+ id("org.jetbrains.kotlin.android")
+}
+
+android {
+ namespace = "com.eddydevink.whatsapplistener"
+ compileSdk = 34
+
+ defaultConfig {
+ applicationId = "com.eddydevink.whatsapplistener"
+ minSdk = 26
+ targetSdk = 34
+ versionCode = 1
+ versionName = "1.0.0"
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+ }
+
+ kotlinOptions {
+ jvmTarget = "17"
+ }
+}
+
+dependencies {
+ implementation("androidx.core:core-ktx:1.12.0")
+ implementation("androidx.appcompat:appcompat:1.6.1")
+ implementation("androidx.preference:preference-ktx:1.2.1")
+ implementation("com.squareup.okhttp3:okhttp:4.12.0")
+}
diff --git a/android-notification-listener/app/src/main/AndroidManifest.xml b/android-notification-listener/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..6b12b71
--- /dev/null
+++ b/android-notification-listener/app/src/main/AndroidManifest.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android-notification-listener/app/src/main/java/com/eddydevink/whatsapplistener/SettingsActivity.kt b/android-notification-listener/app/src/main/java/com/eddydevink/whatsapplistener/SettingsActivity.kt
new file mode 100644
index 0000000..878dc7f
--- /dev/null
+++ b/android-notification-listener/app/src/main/java/com/eddydevink/whatsapplistener/SettingsActivity.kt
@@ -0,0 +1,62 @@
+package com.eddydevink.whatsapplistener
+
+import android.content.Intent
+import android.os.Bundle
+import android.provider.Settings
+import android.widget.Button
+import android.widget.EditText
+import android.widget.TextView
+import android.service.notification.NotificationListenerService
+import androidx.appcompat.app.AppCompatActivity
+import androidx.preference.PreferenceManager
+
+class SettingsActivity : AppCompatActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_settings)
+
+ val prefs = PreferenceManager.getDefaultSharedPreferences(this)
+
+ val webhookUrlInput = findViewById(R.id.webhookUrl)
+ val secretInput = findViewById(R.id.sharedSecret)
+ val saveButton = findViewById