Add push notifications for print events (start, complete, fail) with support for multiple notification providers.
notification_providersCREATE TABLE notification_providers (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL, -- User-defined name ("My WhatsApp")
provider_type TEXT NOT NULL, -- "callmebot", "ntfy", "pushover", "telegram", "email"
enabled BOOLEAN DEFAULT true,
-- Provider-specific config (JSON or individual fields)
config TEXT NOT NULL, -- JSON: {"phone": "+1234", "apikey": "xxx"}
-- Event triggers (which events send notifications)
on_print_start BOOLEAN DEFAULT false,
on_print_complete BOOLEAN DEFAULT true,
on_print_failed BOOLEAN DEFAULT true,
-- Optional: Link to specific printer (NULL = all printers)
printer_id INTEGER REFERENCES printers(id) ON DELETE SET NULL,
-- Timestamps
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
# CallMeBot/WhatsApp
{"phone": "+1234567890", "apikey": "123456"}
# ntfy
{"server": "https://ntfy.sh", "topic": "my-printer", "auth_token": "optional"}
# Pushover
{"user_key": "xxx", "app_token": "yyy", "priority": 0}
# Telegram
{"bot_token": "123:ABC", "chat_id": "12345678"}
# Email (SMTP)
{"smtp_server": "smtp.gmail.com", "smtp_port": 587, "username": "x", "password": "y", "from_email": "x@gmail.com", "to_email": "dest@example.com"}
backend/app/models/notification.pynotification_providers tablebackend/app/schemas/notification.pyNotificationProviderBase - Common fieldsNotificationProviderCreate - For creating new providersNotificationProviderUpdate - For partial updatesNotificationProviderResponse - API response with id/timestampsNotificationTestRequest - For testing notificationsbackend/app/services/notification_service.pyCore notification dispatcher with provider implementations:
class NotificationService:
async def send_notification(self, provider: NotificationProvider, event: str, data: dict) -> bool
async def on_print_start(self, printer_id: int, data: dict, db: AsyncSession)
async def on_print_complete(self, printer_id: int, status: str, data: dict, db: AsyncSession)
# Provider-specific methods
async def _send_callmebot(self, config: dict, message: str) -> bool
async def _send_ntfy(self, config: dict, title: str, message: str) -> bool
async def _send_pushover(self, config: dict, title: str, message: str) -> bool
async def _send_telegram(self, config: dict, message: str) -> bool
async def _send_email(self, config: dict, subject: str, body: str) -> bool
backend/app/api/routes/notifications.pyGET /notifications/ - List all providers
POST /notifications/ - Create provider
GET /notifications/{id} - Get provider details
PATCH /notifications/{id} - Update provider
DELETE /notifications/{id} - Delete provider
POST /notifications/{id}/test - Send test notification
POST /notifications/test-config - Test config before saving
main.pyAdd calls to notification service in existing event handlers:
on_print_start() - After smart_plug_manager call (line ~244)on_print_complete() - After archive update (line ~580)frontend/src/api/client.tsAdd types and API methods for notification providers.
NotificationProviderCard.tsx - Display single provider with enable/disable toggleAddNotificationModal.tsx - Modal for adding/editing providers with provider-specific formsAdd "Notifications" section in SettingsPage.tsx (similar to Smart Plugs section):
🖨️ Print Started
{printer_name}: {filename}
Estimated time: {est_time}
✅ Print Completed
{printer_name}: {filename}
Time: {actual_time}
Filament: {filament_used}g
❌ Print Failed
{printer_name}: {filename}
Status: {failure_reason}
Progress: {progress}%
Use httpx (already available) for async HTTP calls to notification APIs.
None - proceeding with the 5 providers as discussed.