Push Notifications API
Overview
The Push Notifications API enables Web Push notifications for Cloudillo. It uses the VAPID (Voluntary Application Server Identification) protocol to securely deliver notifications to users’ browsers when they’re offline.
Push notifications are sent when actions are received for the user while they are not connected via WebSocket.
Endpoints
Get VAPID Public Key
GET /api/notification/vapid-public-key
Get the VAPID public key for subscribing to push notifications. The key is automatically generated on first request if it doesn’t exist.
Alternative path: GET /api/auth/vapid (alias)
Authentication: Required
Response:
{
"vapidPublicKey": "BM5..."
}| Field | Type | Description |
|---|---|---|
vapidPublicKey |
string | Base64-encoded VAPID public key |
Example:
const response = await api.notifications.getVapidPublicKey()
const vapidPublicKey = response.vapidPublicKey
// Use with browser Push API
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: vapidPublicKey
})Register Subscription
POST /api/notification/subscription
Register a push notification subscription. The subscription is stored and used to send notifications when the user is offline.
Authentication: Required
Request:
{
"subscription": {
"endpoint": "https://fcm.googleapis.com/fcm/send/...",
"expirationTime": null,
"keys": {
"p256dh": "BKgS...",
"auth": "Qs..."
}
}
}| Field | Type | Required | Description |
|---|---|---|---|
subscription.endpoint |
string | Yes | Push service endpoint URL |
subscription.expirationTime |
number | No | Expiration timestamp (Unix milliseconds) |
subscription.keys.p256dh |
string | Yes | P-256 public key (base64url) |
subscription.keys.auth |
string | Yes | Auth secret (base64url) |
Response:
{
"id": 12345
}| Field | Type | Description |
|---|---|---|
id |
number | Subscription ID for later deletion |
Example:
// After getting VAPID public key and subscribing via Push API
const browserSubscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: vapidPublicKey
})
// Send subscription to server
const result = await api.notifications.subscribe({
subscription: browserSubscription.toJSON()
})
// Store subscription ID for later unsubscription
localStorage.setItem('pushSubscriptionId', result.id)Unregister Subscription
DELETE /api/notification/subscription/{id}
Remove a push notification subscription. The subscription will no longer receive notifications.
Authentication: Required
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id |
number | Subscription ID to delete |
Response: 204 No Content
Example:
const subscriptionId = localStorage.getItem('pushSubscriptionId')
if (subscriptionId) {
await api.notifications.unsubscribe(subscriptionId)
localStorage.removeItem('pushSubscriptionId')
}Complete Integration Example
// 1. Check if push is supported
if (!('PushManager' in window)) {
console.log('Push notifications not supported')
return
}
// 2. Get service worker registration
const registration = await navigator.serviceWorker.ready
// 3. Get VAPID public key from server
const { vapidPublicKey } = await api.notifications.getVapidPublicKey()
// 4. Subscribe via browser Push API
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(vapidPublicKey)
})
// 5. Send subscription to Cloudillo server
const result = await api.notifications.subscribe({
subscription: subscription.toJSON()
})
console.log('Push subscription registered with ID:', result.id)
// Helper function to convert base64 key
function urlBase64ToUint8Array(base64String: string): Uint8Array {
const padding = '='.repeat((4 - base64String.length % 4) % 4)
const base64 = (base64String + padding)
.replace(/-/g, '+')
.replace(/_/g, '/')
const rawData = atob(base64)
return Uint8Array.from([...rawData].map(char => char.charCodeAt(0)))
}Notification Settings
Users can control which notification types they receive through the Settings API:
| Setting | Type | Description |
|---|---|---|
notify.push.message |
boolean | Receive notifications for new messages |
notify.push.mention |
boolean | Receive notifications when mentioned |
notify.push.reaction |
boolean | Receive notifications for reactions |
notify.push.connection |
boolean | Receive notifications for connection requests |
notify.push.follow |
boolean | Receive notifications for new followers |
Example:
// Disable reaction notifications
await api.settings.set('notify.push.reaction', false)
// Get current notification settings
const settings = await api.settings.list()
const pushSettings = Object.entries(settings)
.filter(([key]) => key.startsWith('notify.push.'))Web Push Standards
The implementation follows these RFCs:
| RFC | Title |
|---|---|
| RFC 8292 | VAPID for Web Push |
| RFC 8188 | Encrypted Content-Encoding for HTTP |
| RFC 8291 | Message Encryption for Web Push |
See Also
- Settings API - Notification preferences
- WebSocket API - Real-time notifications when online
- Push Notification Architecture - System internals