Single-activity Jetpack Compose app that listens to notifications and forwards them to your webhook in near real time.
- FlowBell
FlowBell turns your Android phone into a notification bridge that you control. A NotificationListenerService watches the apps you pick, bundles new notifications every few seconds, and sends a JSON payload to your webhook. The Compose-based UI shows what was forwarded, what failed, and how the queue is doing, while Koin keeps the wiring tidy and Room takes care of storage.
- Replace paid integrations: Mirror banking, email, or messaging alerts into bots, dashboards, or automations without premium subscriptions.
- Own the pipeline: Self-hosted webhook endpoint, encrypted preferences, and a local queue so you are never locked out by a third-party.
- Operational visibility: Observe send success, failures, retry counts, and the most recent activity directly from the dashboard.
- Developer tooling first: Chucker, Beagle, Timber, and structured logs keep debugging fast during development and QA.
- Automation builders who need webhook-friendly notification events for tools like n8n, Activepieces, Zapier, or custom workflows.
- Merchants who receive on-device payment confirmations (for example QRIS apps) and need to forward them to downstream systems instantly.
- Android developers who want a Compose + Koin + Room codebase they can explore and extend.
- π Notification capture β Listens through
NotificationListenerService, keeps a short dedupe cache, and only forwards alerts from the apps you enabled. - π‘ Batch delivery β Groups outgoing requests every five seconds by default; falls back to per-item sends when needed.
- π§ Queue history β Stores every attempt in Room with HTTP status, latency, retry count, and the payload context so you can review it later.
- βοΈ Per-app control β Compose list with search and system-app filtering makes it easy to toggle forwarding on or off.
- π§© Webhook helper β Built-in tester (OkHttp + Chucker) checks DNS, TLS, and response codes before you save a URL.
- π On-device storage β Webhook preferences, theme settings, and history stay in Room; hooks for
DataStoreor encryption are ready if you want to harden it further. - π Dashboards & analytics β Dashboard surfaces totals and recent activity today; analytics screen is wired for deeper charts as the repositories grow.
- π Battery hints β Utility suggests batch size and cadence tweaks based on power saver, charging state, and battery level.
- π‘οΈ Debug tooling β Beagle debug menu, Timber, and Crashlytics helpers are available when you need to troubleshoot.
| Splash | Onboarding | Permission Prompt |
|---|---|---|
![]() |
![]() |
![]() |
| Dashboard | Webhook | Webhook Editor |
![]() |
![]() |
![]() |
| App List | Notification History | Settings |
![]() |
![]() |
![]() |
FlowBell stays in a single Gradle module but still keeps responsibilities separated into presentation, domain, and data packages.
- Presentation β Compose screens (
Dashboard,Webhook,Apps,History,Settings,Permission) use MVVM andStateFlow. Navigation is handled through a singleMainActivitywithnavigation-compose. - Domain β Plain Kotlin data classes (
NotificationLog,Webhook,UserPreferences,App) and repository interfaces so the UI and services can stay testable. - Data β Room (
FlowBellDatabase) stores queues and preferences, repositories wrap the DAOs, and helpers such asNotificationListenerService,HttpRequestUtils, and the battery utility live here. - App startup β A custom
Applicationkicks off Koin, Timber, Crashlytics hooks, and WorkManager scaffolding.
- A notification comes in β
NotificationListenerServicecaptures it, enriches the metadata, and discards duplicates. - The batch job wakes up β every few seconds the pending queue is drained and
HttpRequestUtilsposts to the webhook. - Results are written β success or failure (including HTTP details) is saved back into Room through the queue repository.
- Screens update β ViewModels collect repository flows and render the dashboard, history, and analytics views.
- Language & UI β Kotlin 2.1.0 with Jetpack Compose (Material 3, Navigation, SplashScreen). Lottie is ready for richer motion work.
- Architecture & DI β MVVM with Koin 3.5 so every screen/view model stays constructor-injected.
- Persistence β Room 2.6 for queue/history plus app and user preferences;
DataStoreManageris available for more granular settings later. - Networking β OkHttp 4.12, Kotlinx Serialization 1.7, and Chucker for inspecting traffic during development.
- Background work β Coroutine-driven batching today with a WorkManager worker scaffold in place for longer running jobs.
- Observability β Timber for logs, optional Crashlytics, and Beagle for in-app debugging tools.
- Build tooling β Gradle Kotlin DSL, AGP 8.8, Kotlin JVM target 21, targeting Android 26β35.
- Android Studio Ladybug or newer with Arctic Fox+ Compose tooling.
- JDK 21 (bundled with latest Android Studio).
- Android device or emulator running Android 8.0 (API 26) or higher.
- A webhook endpoint you control (Zapier, Make/Integromat, Cloudflare Workers, custom server, etc.).
- Clone the repo
git clone https://github.com/fathiraz/flowbell.git cd flowbell - Open in Android Studio β Use File βΈ Openβ¦ and select the project root. Let Gradle sync finish.
- Configure Firebase (optional) β
google-services.jsonis checked in for Crashlytics; replace with your own project if you plan to ship.
- Select the
apprun configuration and click Run (or useShift+F10). - Install on a device/emulator with Play Services for full Crashlytics support.
- On first launch you will be guided through onboarding and asked to grant Notification Listener access.
βΉοΈ The
PermissionRoutecomposable is scaffolded. If you land there while completing onboarding, use the Settings shortcut to grant access and then navigate back manually.
- Grant notification access β When prompted, Android will jump to Settings βΈ Notification access. Enable FlowBell and head back to the app.
- Configure the webhook β In the Webhook tab, paste your HTTPS URL. Hit Test to confirm DNS and TLS before you save; the result shows latency, status code, and response snippet.
- Pick the apps β The Apps tab lists everything installed. Toggle the ones you trust, search by name, or reveal system apps if you need them.
- Watch the dashboard β Totals and recent activity update as notifications move through the queue. Shortcuts to Chucker and Beagle are there if you need deeper debugging.
- Review history β The History tab streams entries as they arrive. Filter by status or app to track down failures, and use the existing scaffolding for detail views or retries.
Payloads use UUID identifiers, include device metadata, and mirror the structure used in FlowBell tests:
{
"id": "e27fe565-51b4-48f8-92ef-f4c4d33580c8",
"timestamp": "2025-09-24T01:28:58.039Z",
"app": {
"packageName": "com.jago.digitalBanking",
"name": "Jago",
"version": "unknown"
},
"notification": {
"title": "",
"text": "You've received Rp126.000 from PT BUZZER INDONESIA. Need help? Contact Tanya Jago at 1500 746.",
"subText": null,
"priority": "normal",
"isOngoing": false,
"isClearable": true,
"category": null
},
"media": {
"iconUri": "icon://2131623940",
"largeIconUri": null,
"iconBase64": null,
"largeIconBase64": null
},
"device": {
"id": "google/sdk_gphone64_arm64/emu64a:16/BE2A.250530.026.D1/13818094:user/release-keys",
"platform": "android",
"version": "16",
"model": "sdk_gphone64_arm64",
"manufacturer": "Google"
},
"security": {
"signature": null,
"nonce": "8fbd0c9b7f7e4972b5c0d4e2cf33b0ea",
"algorithm": "HMAC-SHA256"
}
}- Granting notification-listener access lets FlowBell read every notification on the device. The app still filters by the allowlist you manage in the Apps screen, but the raw access is there.
- Everything is stored locally in Room. We do not ship notifications to any third-party serviceβonly your webhook sees the data you choose to send.
- Manage webhook URLs end-to-end (validate, save, clear).
- Let people toggle forwarding per app.
- Keep a webhook history with HTTP response details.
- Surface counts for sent, failed, and pending notifications.
- Run batch processing through WorkManager so bursts donβt overwhelm the device.
- Support dark theme out of the box.
- Walk new users through onboarding and ship a splash screen.
- Bundle Chucker, Beagle, and Timber so debugging stays close at hand.
- Add pull-to-refresh on dashboard, app list, and history screens.
- Explore multi-webhook routing.
- Allow custom payload templates.
- Add a switch to show or hide debug tooling in production builds.
- Filter words in notifications.
- Filter words per app in notifications.
- GitHub Actions builds a clean release APK whenever a GitHub Release is published and attaches it to the release page.
- release-please opens choreographed PRs to bump
versionName, collect changelog entries, and tag releases automatically once merged. - Both workflows live under
.github/workflows/and run onmainwithout manual intervention.
- Fork the repository and create a feature branch (
git checkout -b feature/awesome). - Make your changes, keep functions small (<40 LOC), and add or update tests.
- Open a pull request with context, screenshots (if UI), and testing notes.
Issues, feature ideas, and bug reports are welcome via GitHub Issues.
There isnβt an open-source license yet, so please treat the code as all rights reserved until a LICENSE file appears.
Maintainer β @fathiraz
Project Link β https://github.com/fathiraz/flowbell
- Best-README-Template for the structural inspiration.
- Jetpack Compose, Koin, and Room maintainers for the foundations we build on.
- Everyone in the automation community sharing webhook ideas and tooling.
- Chucker & Beagle maintainers for world-class developer diagnostics.








