Skip to content

Wake phones through the push relay (GRYT-1656) - #283

Merged
sivert-io merged 1 commit into
mainfrom
claude/GRYT-1656-push
Oct 7, 2026
Merged

sivert-io merged 1 commit into
mainfrom
claude/GRYT-1656-push

Conversation

@sivert-io

Copy link
Copy Markdown
Member

Wake phones through the push relay (GRYT-1656)

The phone hands this server the capability the relay gave it, and the server posts it to the relay when there's something to wake it for:

  • a DM, in either chat:send or mls:send. A reaction, edit or delete in an MLS DM doesn't count.
  • a direct mention or a role mention, in a channel the person can read. @everyone and @here don't push, because they'd wake the whole server.

Nobody gets a push while they're at a screen. That means any socket that's neither idle on the desktop (isAFK) nor a phone that said it went to the background (push:presence). One push per phone per conversation every 15 seconds, so a busy DM is one buzz.

The relay URL defaults to https://push.gryt.chat. GRYT_PUSH_RELAY_URL=off turns pushes off, and it only takes https, or http to localhost. The server picks the relay, never the phone, so a phone can't point the server at an arbitrary URL.

A 404 or 410 from the relay deletes the capability here too. Pushing is fire and forget and runs after delivery, so a slow or dead relay can't hold up a message.

New table push_devices, keyed on (server_user_id, install_id), at most ten per account. Merging a guest into an account drops the guest's rows, and the phone registers again as the account when it reconnects.

Review-required (src/db). Things to look at:

  • The mention filter in chat.ts. User mentions are checked with mayViewChannel, and role mentions were already limited to readers by massMentionAudience.
  • isPresent: a desktop that's open but not idle blocks phone pushes. That's the behaviour I picked, and it's easy to change.
  • Channel mutes live on the phone only, so a mention in a channel you muted still pushes. Follow-up: GRYT-1689.

Checked locally with the phone branch and the relay. The simulator registered and the server stored the capability. A guest's "@thunder" with the phone in the background reached the relay, which sent it on to Apple's sandbox. Apple refused it only because the test key was made up. The two messages before it, with no mention, didn't push. 2,002 tests pass, including two guard tests this tripped: the guest merge and the client-record allowlist.

🤖 Generated with Claude Code

The phone hands this server the capability the relay gave it, and the server posts it to the relay when there's something to wake it for:

- a DM, in either chat:send or mls:send. A reaction, edit or delete in an MLS DM doesn't count.
- a direct mention or a role mention, in a channel the person can read. @everyone and @here don't push, because they'd wake the whole server.

Nobody gets a push while they're at a screen. That means any socket that's neither idle on the desktop (`isAFK`) nor a phone that said it went to the background (`push:presence`). One push per phone per conversation every 15 seconds, so a busy DM is one buzz.

The relay URL defaults to https://push.gryt.chat. `GRYT_PUSH_RELAY_URL=off` turns pushes off, and it only takes https, or http to localhost. The server picks the relay, never the phone, so a phone can't point the server at an arbitrary URL.

A 404 or 410 from the relay deletes the capability here too. Pushing is fire and forget and runs after delivery, so a slow or dead relay can't hold up a message.

New table `push_devices`, keyed on (server_user_id, install_id), at most ten per account. Merging a guest into an account drops the guest's rows, and the phone registers again as the account when it reconnects.

Review-required (src/db). Things to look at:
- The mention filter in chat.ts. User mentions are checked with `mayViewChannel`, and role mentions were already limited to readers by `massMentionAudience`.
- `isPresent`: a desktop that's open but not idle blocks phone pushes. That's the behaviour I picked, and it's easy to change.
- Channel mutes live on the phone only, so a mention in a channel you muted still pushes. Follow-up: GRYT-1689.

Checked locally with the phone branch and the relay. The simulator registered and the server stored the capability. A guest's "@thunder" with the phone in the background reached the relay, which sent it on to Apple's sandbox. Apple refused it only because the test key was made up. The two messages before it, with no mention, didn't push. 2,002 tests pass, including two guard tests this tripped: the guest merge and the client-record allowlist.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
sivert-io added a commit to Gryt-chat/docs that referenced this pull request Oct 7, 2026
… page

Twelve events the server already has and the page left out. The socket
coverage check has a 70% floor, and the three push:* events in
Gryt-chat/server#283 tipped the server's side to 69%. This lifts it to
75% with those three still undocumented. They can't go on the page
until the server has them, because the docs side fails on events the
server doesn't have yet. So they follow once #283 merges.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
sivert-io added a commit to Gryt-chat/docs that referenced this pull request Oct 7, 2026
… page (#156)

Twelve events the server already has and the page left out. The socket
coverage check has a 70% floor, and the three push:* events in
Gryt-chat/server#283 tipped the server's side to 69%. This lifts it to
75% with those three still undocumented. They can't go on the page
until the server has them, because the docs side fails on events the
server doesn't have yet. So they follow once #283 merges.

Co-authored-by: Claude Opus 5.5 <[email protected]>
@sivert-io
sivert-io merged commit 6ea0f56 into main Oct 7, 2026
6 of 7 checks passed
@sivert-io
sivert-io deleted the claude/GRYT-1656-push branch October 7, 2026 11:37
sivert-io added a commit to Gryt-chat/docs that referenced this pull request Oct 7, 2026
push:register and push:unregister hand over and take back the capability
the relay gave the phone. push:presence says whether the app is in the
background. They're on server main since Gryt-chat/server#283, so the
reference check can see them now.

Co-authored-by: Claude Opus 5.5 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant