Files
musicshare/docs/PUSH.md
T
chrisandClaude Opus 5.5 f112a3515c Notifications and sending songs to friends
Reactions to your songs, new followers, and songs sent to you are now
notifications: a bell on the feed (app and website) with an unread
count that updates live, and a list that marks them read. "Send ✉" on
a song sends it to people who follow you, with an optional note.
Settings picks which kinds to be notified about.

Push delivery uses no third-party accounts:
- Android: UnifiedPush through a distributor app (ntfy), pointed at
  our own ntfy server (docker-compose.ntfy.yml). Works the same in
  the F-Droid build; no Firebase.
- Browsers: standard Web Push from the existing service worker.
Both use Web Push encryption with a VAPID key pair the server makes
and keeps in the database. Push addresses are checked like any other
user-supplied URL. Setup is in docs/PUSH.md; the privacy page covers
the new data.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 22:14:34 -04:00

2.7 KiB

Notifications

musicshare tells people about reactions to their songs, new followers, and songs sent to them. Each user picks which kinds in Settings. Everything always shows under the bell on the feed; push notifications are extra.

Nothing goes through Google's Firebase or another push company's account:

  • Phones (Android): UnifiedPush. A "distributor" app on the phone keeps one connection open to a push server, and apps receive their notifications through it. We run the push server ourselves (ntfy, docker-compose.ntfy.yml). People install the ntfy app (free, open source, on F-Droid and Play) and point it at our server.
  • Browsers: standard Web Push. The server signs messages with its own key pair (VAPID), so there's no account with anyone, but each browser maker runs its own delivery service (Chrome uses Google's, Firefox uses Mozilla's). That's built into browsers and can't be swapped.
  • iPhone: Apple only allows its own push service. Not set up.

Messages are end-to-end encrypted (RFC 8291) in every case: the push server and browser relays only see ciphertext.

Server setup

  1. Pick a subdomain for the push server, e.g. push.binarygnome.com, and point DNS at the server.
  2. Set NTFY_DOMAIN in deploy/production.env.
  3. Start it with the other services. Add -f docker-compose.ntfy.yml to the usual command:
    docker compose -f docker-compose.yml -f docker-compose.prod.yml -f docker-compose.behind-proxy.yml \
      -f docker-compose.ntfy.yml --env-file deploy/production.env up -d
    
  4. In the reverse proxy (NPMplus), add a proxy host for that subdomain:
    • Forward to http://127.0.0.1:3739.
    • Turn on websocket support and HTTPS.
  5. Check it: curl https://push.binarygnome.com/v1/health should say {"healthy":true}.

The server's Web Push keys are generated the first time they're needed and kept in the server_keys table. Don't delete that row: every phone and browser would have to turn notifications on again. To manage the keys yourself, set VAPID_PUBLIC_KEY and VAPID_PRIVATE_KEY (make a pair with npx web-push generate-vapid-keys).

On a phone

  1. Install ntfy (F-Droid or Play).
  2. In ntfy, open Settings > Default server and enter https://push.binarygnome.com. Without this step it uses the public ntfy.sh server, which also works, but then the push server isn't ours.
  3. In musicshare, go to Settings > Notifications > Turn on for this phone.

ntfy shows one quiet, permanent notification so Android keeps its connection alive. People can hide it by long-pressing it and turning off that notification category.