Skip to main content

Notifications

Open Genie delivers notifications to devices through multiple channels with automatic fallback.

Delivery Strategy

Create Notification (DB record)

Is device online?
┌── Yes ──────────────────┐
│ Send via WebSocket │
│ notification.push msg │
└──────────────────────────┘
┌── No ───────────────────┐
│ Has push token? │
│ ┌── Yes ──────────┐ │
│ │ Send via Expo │ │
│ │ or Firebase │ │
│ └─────────────────┘ │
│ ┌── No ───────────┐ │
│ │ Stay as pending │ │
│ └─────────────────┘ │
└──────────────────────────┘

Update status

Status Lifecycle

StatusMeaning
pendingCreated but not yet delivered
sentDelivered via WebSocket or push
deliveredDevice acknowledged receipt
readUser viewed the notification

Push Providers

Expo Push (lib/notifications/push.ts)

For React Native / Expo-based mobile apps. Requires EXPO_ACCESS_TOKEN.

Firebase Cloud Messaging

For native Android/iOS apps. Requires FIREBASE_SERVICE_ACCOUNT pointing to a Firebase service account JSON file.

Device Push Tokens

Each device stores a pushToken in the devices table. Tokens are registered when the device first connects or updates its push credentials.

Notification Categories (lib/notifications/categories.ts)

Categories define actionable buttons that appear on push notifications:

CategoryActions
CAMERA_ALERTView, Dismiss
BACKUP_COMPLETEView Files
REMINDERMark Done, Snooze 15min

Categories are sent with the push payload so the device OS can render action buttons.

Creating Notifications

Via Action (AI or programmatic)

await actionRegistry.execute("send_notification", {
title: "Camera Alert",
body: "Motion detected in backyard",
target: "phones",
level: "warning",
});

Via REST API

POST /api/notifications/send
Content-Type: application/json

{
"title": "Reminder",
"body": "Take out the trash",
"deviceId": "specific-device-uuid",
"level": "info",
"category": "REMINDER"
}

Via WebSocket (server → client)

{
"type": "notification.push",
"payload": {
"id": "notif-uuid",
"title": "Camera Alert",
"body": "Motion detected",
"level": "warning",
"category": "CAMERA_ALERT"
}
}

REST API

MethodPathDescription
GET/api/notificationsList notifications (filterable by device, status)
GET/api/notifications/[id]Get notification details
POST/api/notifications/sendCreate and send a notification

Key Files

FilePurpose
lib/notifications/index.tsCore delivery logic
lib/notifications/push.tsExpo/Firebase push sending
lib/notifications/categories.tsNotification action categories
lib/ws/handlers/notification.tsWebSocket ack/read handlers