Skip to content

Push Internals

AstorisTheBrave edited this page Jul 4, 2026 · 1 revision

Push Internals

URSA uses the UnifiedPush Android connector. The design goal is simple: receive a Uptime Kuma Webhook payload through a distributor and render it as a notification, with no relay server and no proprietary push service.

Flow

Uptime Kuma  --Webhook (JSON)-->  distributor (ntfy, ...)  --push-->  UrsaPushService  -->  notification

Receiving

Push events are handled by a PushService (the connector's current API). It is declared in the manifest as not exported: the connector ships its own internal receiver that forwards events to the service, so there is no exported push surface to harden. The service handles four callbacks:

  • new endpoint - the endpoint URL is stored and surfaced in the UI for the user to paste into a Kuma Webhook.
  • message - the payload bytes are parsed and turned into a notification.
  • registration failed and unregistered - logged and reflected in state.

The connector's older MessagingReceiver is deprecated; URSA uses PushService.

The payload

Uptime Kuma's Webhook posts JSON shaped like { heartbeat, monitor, msg }, where msg is ready-made text such as "[name] [Down] connect ECONNREFUSED ...". With ntfy, appending ?up=1 to the endpoint makes it forward these raw bytes untouched.

Because Kuma sends plain JSON (not web-push-encrypted), messages arrive unencrypted. The payload is treated as untrusted input: it is parsed tolerantly (a body that is not the expected JSON yields a safe fallback rather than a crash) and is only ever rendered into a notification, never acted upon. The parser is pure and unit-tested.

Notifications

Notifications use a dedicated channel. On Android 13+ the POST_NOTIFICATIONS runtime permission is required; the UI requests it, and the service drops the notification (with a log warning) rather than crashing if it is missing. A monitor's notifications reuse an id so a new status replaces the previous one.

Registration UI

The Push screen lists installed distributors, lets the user select one, requests the notification permission, and shows the endpoint URL with a copy button and the ntfy ?up=1 hint.

Clone this wiki locally