Apps & tools
Gotify+
A modern Android client for Gotify push.
Per-app channels, real-time WebSocket streaming, offline history and multiple servers, built with Compose and Material 3.

Why I built it
Gotify carries all of my homelab alerts. I wanted a cleaner Android client with offline history and search.
Architecture
How it fits together
Services
Homelab alerts and scripts
Gotify server
Self-hosted push
Gotify+
Live stream
WebSocket
Offline cache
Room DB
Per-app channels
Screenshots
See it in use
Documentation
From the README
A modern Android client for Gotify — a self-hosted push notification server. Built entirely with Jetpack Compose and Material 3, Gotify+ replaces the official Android app with a cleaner interface, per-app notification channels, real-time WebSocket streaming, and offline message caching.
Features
- Real-time notifications via persistent WebSocket connection to
/stream - Per-app notification channels with Low / Normal / High priority tiers
- Offline caching — messages stored in Room DB, readable without network
- Cached message search with result highlighting
- App inbox — per-application message view
- Markdown rendering in message bodies
- Action buttons — tap extras from message payloads open URLs directly
- Dark and light theme with Material You dynamic color on Android 12+
- Vibration control — toggle independently from notification sound
- Filter chips — filter the message feed by application instantly
- Pull-to-refresh on both messages and applications screens
- Battery optimization guidance — opens Android's battery settings so the user can review background restrictions
- Boot receiver — listener service auto-restarts after device reboot
- Adaptive navigation — bottom navigation on phones and a navigation rail on larger windows
- Server control sheet — switch servers, inspect connection/version/health, and remove saved servers
- Application management — create, edit, clear, and delete applications with confirmation for destructive actions
- Message actions — copy or share message content, and safely open Gotify URL/intent actions
- Credential hygiene — application tokens are not displayed in the UI; sign out clears all local server credentials and caches
Tech Stack
| Layer | Library |
|---|---|
| UI | Jetpack Compose + Material 3 |
| Architecture | MVVM + Clean Architecture |
| Dependency Injection | Hilt |
| Networking | Retrofit 3 + OkHttp 5 |
| Real-time | OkHttp WebSocket |
| Local DB | Room |
| Preferences | DataStore |
| Image loading | Coil |
| Async | Kotlin Coroutines + Flow |
| Markdown | compose-markdown |
Requirements
- Android 8.0+ (API 26)
- A running Gotify server
This repository contains the Android client only. The Gotify server's browser UI is a separate codebase and is not present here; changing that UI requires the Gotify server repository (including its ui/ directory).
Setup
Build from source
- Clone the repository
git clone https://github.com/anand34577/gotify-plus.git
cd gotify-plus
-
Open in Android Studio Hedgehog or newer
-
Sync Gradle — all dependencies resolve from Maven Central and JitPack
-
Build → Generate Signed APK, or run directly on a device / emulator
Login
The app supports two authentication methods:
Username & Password — enters your Gotify credentials and the app creates a new client token automatically via POST /client.
Client Token — paste a pre-existing token from Gotify web UI → Clients.
Both methods verify the server is reachable before saving.
Architecture
app/
├── data/
│ ├── api/ Retrofit interfaces, WebSocket manager, OkHttp client
│ ├── db/ Room database, DAOs, entity↔domain mappers
│ ├── datastore/ User preferences (DataStore)
│ ├── model/ Domain models, sealed ApiResult, StreamState
│ └── repository/ AuthRepository, MessageRepository, ApplicationRepository
├── di/ Hilt modules (NetworkModule, DatabaseModule)
├── notification/ Per-app channel management, priority→behaviour mapping
├── service/ GotifyListenerService (foreground), BootReceiver
└── ui/
├── appinbox/ Per-app message list
├── apps/ Application management screen
├── components/ Shared composables (AppIcon, MessageCard, ConnectionDot…)
├── detail/ Message detail with Markdown + action buttons
├── home/ Main message feed with filter chips
├── login/ Server URL + auth screen
├── navigation/ NavHost, bottom bar, route constants
├── search/ Cached search with result highlighting
├── servers/ Server info sheet
├── settings/ Settings screen
├── theme/ Material 3 color schemes, priority colours
└── viewmodel/ One ViewModel per screen + AppStartupViewModel
Notification Priority Mapping
| Gotify priority | Android behaviour |
|---|---|
| 0 | No notification |
| 1 – 3 | Silent (IMPORTANCE_LOW) |
| 4 – 7 | Sound (IMPORTANCE_DEFAULT) |
| 8 – 10 | Sound + optional vibration (IMPORTANCE_HIGH) |
Gotify API Coverage
| Endpoint | Used for |
|---|---|
POST /client | Create client token on login |
DELETE /client/{id} | Revoke token on logout |
GET /current/user | Validate elevated user sessions |
GET /message | Fetch + paginate all messages |
DELETE /message/{id} | Delete single message |
DELETE /message | Delete all messages |
GET /application | List applications |
POST /application | Create application |
PUT /application/{id} | Edit application |
DELETE /application/{id} | Delete application |
DELETE /application/{id}/message | Clear app messages |
GET /health | Inspect server health |
POST /application/{id}/image | API available; UI upload is pending |
GET /stream | WebSocket — real-time message stream |
GET /version | Verify server reachability |
Permissions
| Permission | Reason |
|---|---|
INTERNET | Server communication |
FOREGROUND_SERVICE | Keep WebSocket alive in background |
POST_NOTIFICATIONS | Show push notifications (Android 13+) |
RECEIVE_BOOT_COMPLETED | Restart listener after reboot |
VIBRATE | High-priority notification vibration |
Acknowledgements
- Gotify — the self-hosted notification server this client connects to
- Jetpack Compose — Android's modern UI toolkit
- compose-markdown — Markdown rendering in Compose
- Coil — image loading
Apps & tools