Tools & data · Prototype, running
Private group messaging relay
A self-hosted message relay for a small group. Messages persist until every recipient acknowledges them, and delivery is tracked per person.
One message, one record per recipient
- Role
- Design & development
- Period
- September 2026
- Status
- Running for a private group
- Platform
- Node on macOS, behind Cloudflare Tunnel
- Built with
- TypeScript
- Node
- Fastify
- SQLite (WAL)
- WebSocket
- Web Push
- argon2
- Cloudflare Tunnel
- launchd
- 1
- delivery record per recipient, per message
- 2
- transports: WebSocket and Web Push
- 1
- way in: the tunnel. The server binds only to localhost
01
The problem
At a crowded event, a message can leave one phone and never reach another, and the sender cannot tell. The relay treats delivery as state it tracks for each person, and keeps a message until every recipient has acknowledged it.
02
How it works
- Sending is a plain HTTPS request. Live delivery, acknowledgments, and presence travel over a WebSocket.
- Web Push wakes a backgrounded phone where the platform allows it. It counts as a notification only; delivery still waits for an acknowledgment.
- A retry engine resends anything unacknowledged.
- Accounts use argon2 password hashing, invitations, and lockout after failed attempts.
03
Tested with two people
The test suite runs on node:test, plus a live browser test that signs in two users and checks that a message moves between them.
Scope & limitations
Built for one private group and run on my own machine. It is not a public service.