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
| Status | Meaning |
|---|---|
pending | Created but not yet delivered |
sent | Delivered via WebSocket or push |
delivered | Device acknowledged receipt |
read | User 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:
| Category | Actions |
|---|---|
CAMERA_ALERT | View, Dismiss |
BACKUP_COMPLETE | View Files |
REMINDER | Mark 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
| Method | Path | Description |
|---|---|---|
GET | /api/notifications | List notifications (filterable by device, status) |
GET | /api/notifications/[id] | Get notification details |
POST | /api/notifications/send | Create and send a notification |
Key Files
| File | Purpose |
|---|---|
lib/notifications/index.ts | Core delivery logic |
lib/notifications/push.ts | Expo/Firebase push sending |
lib/notifications/categories.ts | Notification action categories |
lib/ws/handlers/notification.ts | WebSocket ack/read handlers |