Surfaces ↓
Notifications
client.notifications Daemon -> webapp notification mirror. Posted fires for a new
notification, Updated when an existing one's content changes, and
Removed when it is dismissed, acted on, or cleared remotely.
Commands
fire-and-forget; the promise resolves once the daemon has taken the message
invokePositive(NotificationInvoke): Promise<void>
await client.notifications.invokePositive({ id: '...' }); invokeNegative(NotificationInvoke): Promise<void>
await client.notifications.invokeNegative({ id: '...' }); Events
the daemon pushes these unprompted; subscribing returns an unsubscribe function
onPosted(handler: (Notification) => void): () => void
const off = client.notifications.onPosted((notification) => {
console.log(notification.id);
});
// call off() to unsubscribe onUpdated(handler: (Notification) => void): () => void
const off = client.notifications.onUpdated((notification) => {
console.log(notification.id);
});
// call off() to unsubscribe onRemoved(handler: (NotificationRemoved) => void): () => void
const off = client.notifications.onRemoved((notificationRemoved) => {
console.log(notificationRemoved.id);
});
// call off() to unsubscribe Types
shapes referenced above, as the SDK types them
One notification surfaced from the connected companion's notification
center. id is companion-stable for the lifetime of the notification
- webapps pass it to invokePositive/invokeNegative and listen for
onNotificationRemoved. Bodies (title/subtitle/message) are all
optional because ANCS treats them as separate attribute fetches.
type Notification = {
id: string;
app: NotificationApp;
category: NotificationCategory;
title?: string;
subtitle?: string;
message?: string;
timestampUnixS?: number;
flags: NotificationFlags;
positiveAction?: NotificationAction;
negativeAction?: NotificationAction;
}; type NotificationRemoved = {
id: string;
reason: DismissReason;
}; type NotificationInvoke = {
id: string;
}; Originating app metadata. bundle_id is platform-stable
(com.apple.MobileSMS, com.spotify.client, etc.); display_name
and icon_asset_id are best-effort and may be missing on Android
gateways that don't surface them cheaply.
type NotificationApp = {
bundleId: string;
displayName?: string;
iconAssetId?: string;
}; type NotificationCategory =
| 'other'
| 'incomingCall'
| 'missedCall'
| 'voicemail'
| 'social'
| 'schedule'
| 'email'
| 'news'
| 'healthAndFitness'
| 'businessAndFinance'
| 'location'
| 'entertainment'; ANCS-shaped flags. silent mirrors the iOS "do not surface
audibly" hint, important is the high-importance flag, and
pre_existing is true for notifications that arrived before the
daemon connected (replayed by the companion on first sync).
type NotificationFlags = {
silent: boolean;
important: boolean;
preExisting: boolean;
}; One ANCS-style action slot. label is the gateway-localized prompt
the webapp renders on the action button.
type NotificationAction = {
label: string;
}; Why a notification went away. Acted covers both positive and
negative invokes; gateways that distinguish dismiss-vs-acted may
surface both as Acted.
type DismissReason = 'userDismissed' | 'acted' | 'remoteDismissed';