Push
Push lets an application's backend send a notification to its users' phones and tablets. Turn Zero Cloud delivers it to iPhones through Apple and to Android devices through Google. The backend lists the users or the devices, and the platform finds each device the app registered.
The package provides your backend's side of that service. Its client sends one message under the application's platform credential. It reports what the send accepted, and it throws a typed refusal that gives the platform's refusal name.
Use it when
Use Push when the backend must tell a signed-in user something while the app is closed: a game ended, an order shipped, a turn is waiting. The app must sign its users in through the application's realm and register each device after sign-in. Send push notifications covers the credentials, the declaration, the device registration, and the send route.
Do not use it for a web page in a browser or for a text message. Neither is offered.
What it provides
- A client.
createPushClient({ api, token })builds a client from the platform's origin and the application's platform credential. An application whose calls already share one transport function of its own passes that instead, ascreatePushClient({ transport }). - A send to users.
send(users, message)sends one message to every registered device of the named users. The user identifier is the one the realm returns for the signed-in user. - A send to devices.
sendToDevices(installations, message)sends one message to the named installations, the identifiers the app registered its devices under. - The response. Each send returns
messageId, theacceptedcount of deliveries queued, and theunknownUsersorunknownDevicesthat had no registration. - A typed refusal. Every other response throws a
PushRefusal. Itsrefusalmember is the platform's refusal name, andmemberscontains the refusal's other values.
| Message member | Required | What it contains |
|---|---|---|
notification.title |
Yes | Up to 256 characters. |
notification.body |
Yes | Up to 4,000 characters. |
notification.badge |
No | The count on the app's icon. |
notification.sound |
No | A sound the app bundles, or default. |
data |
No | String values for the app, under 4 kilobytes. |
ttlSeconds |
No | How long an offline device's notification is kept, a day by default. |
collapseId |
No | A key under which a newer notification replaces an older one. |
priority |
No | high by default, or normal. |
The module is published as the npm package @turnzero/push. Use the library shows how to copy it into app/lib/push/, declare it as file:lib/push, and install it with npm install. The module imports nothing, reads no environment variable, starts no timer, and keeps no state.
No test checks this sample. It builds the client from the two values the deploy injects and sends to one user:
import { createPushClient, PushRefusal } from '@turnzero/push';
const push = createPushClient({ api: process.env.TURNZERO_CLOUD_API, token: process.env.TURNZERO_CLOUD_TOKEN });
const sent = await push.send([userId], { notification: { title: 'Game over', body: 'You stumped it.' } });
A test double ships at the package's testing subpath, @turnzero/push/testing. createPushDouble responds to a send as the platform does, from devices and a monthly quota the test gives it, and records every send. Test your application locally shows the doubles in use.
Availability
Version 0.2.2 is the package's current version, and list_library reports the version the platform currently publishes. The entry includes the testing subpath from version 0.1.0. The entry contains the package's product statement, its detailed contract, its integration guide, and the compiled modules.
Turn Zero Cloud runs the push service. A delivery pass sends each accepted delivery to its provider within seconds, retries a transient failure, and marks a device its provider reports gone. read_push returns the device counts, the last hour's outcomes, and the month's count beside the plan's allowance.
Related feature packages
Account signs users in and tells the backend who they are. Secrets stores the Apple key and the Google service-account file by name. Logging records the delivery counters and one line per delivery.
Refusals
Branch on the refusal's name, never on its message.
| Refusal | Status | Meaning |
|---|---|---|
invalid_request |
400 | A member of the message is malformed, and the detail identifies it; or a member contains a NUL character (U+0000) or an unpaired UTF-16 surrogate, which the detail identifies instead. |
end_user_credential_not_admitted |
403 | The send ran under an end-user session, refused ahead of the route's own check. |
platform_credential_required |
403 | The send ran under a session or a minted token. |
push_not_configured |
409 | The environment has no provider configured. |
realm_not_declared |
404 | The application declares no accounts service. |
usage_over_quota |
429 | The send would pass the plan's monthly push allowance. |
A send refused usage_over_quota queued nothing. Its members give the month's count, the allowance, and the send's own deliveries.
What an application must do
Declare the push service and the accounts service in the manifest, store both providers' credentials, and call configure_push for each environment the application has. Register each device from the app after sign-in, and register it again when the platform gives the app a new token.
Send once for each event. The client retries nothing, because a send the platform accepted before its response was lost is already queued. Give a message a collapseId where a repeat must replace the earlier notification rather than add one.
Keep a refused send from failing the request that made it. Record the refusal, and respond to the request.