Chat notifications
Configure Chat push content and inspect delivery workers and badge counts.
Chat uses Cloud's browser notification delivery. Configure the installation's public origin and HTTPS, deploy Core and Chat with the same platform contract, and register a browser endpoint before testing. An unsupported Badging API does not prevent notifications.
Choose notification content
The administrator setting chat.push_preview defaults to true. It includes
the beginning of the message in the browser notification, including on a locked
screen and paired devices. Turn it off to show the chat name and sender only.
The setting applies to everyone and also removes message text from email.
Already prepared notifications keep the content they had when sent. Messages
use the recipient's last interactive Chat read locale, or the operator's
app.locale default when none is stored.
Cloud's notification preferences expose three Chat kinds:
chat.mention: mentions, replies, and followed item discussions; browser recommended, email selectable.chat.message: new messages in chats whose effective level is All messages; browser recommended, email unavailable with an explanation.chat.added: another person adds the recipient to a chat or channel; browser recommended, email selectable. Creating a chat does not notify its creator.
A chat's Off level blocks message and personal pushes until it expires. Cloud's do not disturb and quiet hours suppress browser delivery without a catch-up notification. Service accounts never receive pushes.
Check delivery
Chat commits a notification outbox row with each completed message or membership
addition. The chat:delivery job advances a durable recipient cursor in batches
of 500. The chat:push job coalesces each person/chat pair and waits three seconds
from the first candidate. Reading before that job runs suppresses its notification
on every device. Current access and notification level are checked again before
content is sent to Cloud.
The browser group is the exact public conversation ID, including for messages
in threads. Destinations use /app/chat/c/<chat>/m/<message> or
/app/chat/c/<chat>/t/<thread>/m/<message>. Later unread messages replace that
chat's notification quietly. Personal notifications or reading since the last
push can alert again; mentions and replies bypass the rolling limit of one alert per person
per ten seconds.
The jobs use Sync's default bounded retention: seven days and 256 maximum-size
messages' worth of bytes per stream. At capacity JetStream drops the oldest
pending work. Unread counters remain in Postgres. Cloud discovers the two jobs
in its standard administrative Sync controls, including queue depth and dead
letters. Inspect the chat:notification-outbox log source for publication retries.
The additive startup migration creates chat.notification_outbox,
chat.notification_pending, and chat.notification_push_state. Last push
sequence and time survive process restarts. No environment variable is added.
Enable resource discussion notifications after the upgrade
Update Core first to the release with automatic app credentials (PR #2112),
then deploy Chat and the discussion providers. Chat declares
platformPermissions: ["resources:readers"] and receives its workload credential
automatically from Core. There is no Chat credential to create or environment
variable to add. Deployment of Chat's declaration admits the reader checks, as described in
App-to-app reader checks.
A provider offers the discussions role and access.readable on both its item
and container Types. The same path works for built-in and third-party providers. Following an
item discussion selects its incoming messages for push; mentions and replies
also qualify. The conversation's notification level still applies.
Chat checks the item with its expected container and checks the container separately. Only the intersection of both readable subsets can receive push. It uses only current participants of that conversation or followers of that thread. An item moved to another container is no longer readable through the old conversation. Chat checks during recipient preparation and again before the final send. Every prepared decision expires after three seconds; lock waits are bounded. Owner checks run outside Chat database transactions.
- A checked result keeps only the readable recipients. A rejection drops the recipient without retrying.
- A temporary failure omits the item from counts and retries delivery through
the existing job, with at most five short failure attempts between
continuations. Rate limits and lock timeouts
allow at most five delayed continuations within five minutes across all
batches of a job; each retry
checks access freshly. Core’s
Retry-Afterdelay is respected (60 seconds when absent). After the retry budget is exhausted, the push is dropped and the dead letter is visible in the administrative Sync controls. Administration → Chat shows the last delivery failure for each provider. An earlier positive decision cannot authorize the push. not_configuredsuppresses push until setup is complete. Administration → Chat shows each recorded provider item type's delivery state, time and reason, such as a missing reader function, automatic credential or Core admission. Before any delivery check it says Not checked yet. Interactive count checks do not update delivery health. Successful checks become healthy only after hand-off succeeds; expired decisions report a failure. The snapshot holds 100 provider item types; overflow is reported rather than hiding a recorded failure.
System-chat pushes never include a “+n more” count, because coalesced messages can belong to different resources. Chat checks both the chosen personal message and the newest message when they belong to different item discussions. Cloud cannot recall a push after accepting it; later revocation still blocks opening the resource.
Check the badge
GET /api/chat/badge returns { "count": number } for the signed-in person.
The same function supplies push badges and the navigation badge. It adds chats
with effective All messages and unread content to the existing unread
mentions/replies count. Each component is capped at 99; permission checks and
bounded candidate scans can undercount inaccessible or very large collections.
Service-account credentials receive zero. System-chat mention and reply
counts use the same item and container reader checks. Interactive decisions, including denials,
may be reused for at most 60 seconds. Each person can trigger at most 50 new
item/container pairs per 60 seconds, and all interactive traffic shares a limit
of 250 pairs (500 platform requests).
Overlapping requests share a cache reservation. These limits leave at least
1,001 of Core's 1,501 reader requests per minute outside interactive traffic;
delivery always checks freshly. Push jobs reuse only cached count decisions,
so their badges never spend the interactive reader budget. Cached-only count reads inside a database
snapshot omit decisions that were not prepared before entering it.
Read state is authoritative in Postgres. The browser closes a local group with
closeGroup("chat", conversation.id) and refreshes the count after reading;
a push accepted by the browser vendor cannot be recalled remotely.