PLAN.md 8.2 KB

Notification Templates Management System

Overview

Replace hardcoded notification messages with a flexible template system that allows users to customize notification content per event type, with provider-specific formatting support.


Data Model

New Table: notification_templates

CREATE TABLE notification_templates (
    id INTEGER PRIMARY KEY,
    event_type VARCHAR(50) NOT NULL,  -- print_start, print_complete, etc.
    name VARCHAR(100) NOT NULL,       -- User-friendly name
    title_template TEXT NOT NULL,     -- Template for notification title
    body_template TEXT NOT NULL,      -- Template for notification body
    is_default BOOLEAN DEFAULT 0,     -- System default (non-deletable)
    created_at DATETIME,
    updated_at DATETIME
);

Event Types:

  • print_start
  • print_complete
  • print_failed
  • print_stopped
  • print_progress
  • printer_offline
  • printer_error
  • filament_low
  • maintenance_due
  • test (for test notifications)

Template Variables

Variables use {variable_name} syntax (Python format strings).

Per-Event Variables:

Event Variables
print_start {printer}, {filename}, {estimated_time}
print_complete {printer}, {filename}, {duration}, {filament_grams}
print_failed {printer}, {filename}, {duration}, {reason}
print_stopped {printer}, {filename}, {duration}
print_progress {printer}, {filename}, {progress}, {remaining_time}
printer_offline {printer}
printer_error {printer}, {error_type}, {error_detail}
filament_low {printer}, {slot}, {remaining_percent}, {color}
maintenance_due {printer}, {items} (formatted list)
test {app_name}

Common Variables (all events):

  • {timestamp} - Current date/time
  • {app_name} - "Bambuddy"

Default Templates

Pre-seeded templates for each event (marked is_default=True):

print_start:
  title: "Print Started"
  body: "{printer}: {filename}\nEstimated: {estimated_time}"

print_complete:
  title: "Print Completed"
  body: "{printer}: {filename}\nTime: {duration}\nFilament: {filament_grams}g"

print_failed:
  title: "Print Failed"
  body: "{printer}: {filename}\nTime: {duration}\nReason: {reason}"

print_stopped:
  title: "Print Stopped"
  body: "{printer}: {filename}\nTime: {duration}"

print_progress:
  title: "Print {progress}% Complete"
  body: "{printer}: {filename}\nRemaining: {remaining_time}"

printer_offline:
  title: "Printer Offline"
  body: "{printer} has disconnected"

printer_error:
  title: "Printer Error: {error_type}"
  body: "{printer}\n{error_detail}"

filament_low:
  title: "Filament Low"
  body: "{printer}: Slot {slot} at {remaining_percent}%"

maintenance_due:
  title: "Maintenance Due"
  body: "{printer}:\n{items}"

test:
  title: "Bambuddy Test"
  body: "This is a test notification. If you see this, notifications are working!"

Provider-Specific Formatting

The template system supports provider-specific formatting via a simple approach:

  1. Plain text (default) - Used for CallMeBot, ntfy, Pushover, Email
  2. Markdown - Automatically applied for Telegram (wrap title in *bold*)

The notification service will:

  • Render the template with variables
  • Apply provider-specific formatting when sending

Implementation Steps

Backend

  1. Create model backend/app/models/notification_template.py

    • NotificationTemplate SQLAlchemy model
  2. Create schemas backend/app/schemas/notification_template.py

    • NotificationTemplateCreate, Update, Response
    • TemplateVariables (documentation of available vars per event)
  3. Add migration in backend/app/core/database.py

    • Create table if not exists
    • Seed default templates
  4. Create API routes backend/app/api/routes/notification_templates.py

    • GET /api/v1/notification-templates - List all templates
    • GET /api/v1/notification-templates/{id} - Get single template
    • PUT /api/v1/notification-templates/{id} - Update template
    • POST /api/v1/notification-templates/{id}/reset - Reset to default
    • GET /api/v1/notification-templates/variables - List available variables per event
    • POST /api/v1/notification-templates/preview - Preview template with sample data
  5. Update notification service backend/app/services/notification_service.py

    • Load templates from database
    • Render templates with variables
    • Remove hardcoded message builders
  6. Register routes in backend/app/main.py

Frontend

  1. Add API client methods frontend/src/api/client.ts

    • getNotificationTemplates, updateNotificationTemplate, etc.
  2. Create template editor component frontend/src/components/NotificationTemplateEditor.tsx

    • Template editing UI with variable insertion buttons
    • Live preview with sample data
    • Reset to default button
  3. Update SettingsPage frontend/src/pages/SettingsPage.tsx

    • Add "Templates" sub-section in Notifications tab
    • List all templates with edit capability

UI Design

Templates Section (in Settings > Notifications)

+--------------------------------------------------+
| Message Templates                                |
| Customize notification messages for each event   |
+--------------------------------------------------+
|                                                  |
| +----------------+  +----------------+           |
| | Print Started  |  | Print Complete |  ...     |
| | "Print Started"|  | "Print Compl..." |        |
| | [Edit]         |  | [Edit]         |          |
| +----------------+  +----------------+           |
|                                                  |
+--------------------------------------------------+

Template Editor Modal

+--------------------------------------------------+
| Edit Template: Print Complete              [X]   |
+--------------------------------------------------+
| Title:                                           |
| [Print Completed_________________________]       |
|                                                  |
| Body:                                            |
| +----------------------------------------------+ |
| | {printer}: {filename}                        | |
| | Time: {duration}                             | |
| | Filament: {filament_grams}g                  | |
| +----------------------------------------------+ |
|                                                  |
| Available Variables:                             |
| [+printer] [+filename] [+duration] [+filament]   |
|                                                  |
| Preview:                                         |
| +----------------------------------------------+ |
| | Title: Print Completed                       | |
| | Body:  Bambu X1C: Benchy.3mf                 | |
| |        Time: 1h 23m                          | |
| |        Filament: 15.2g                       | |
| +----------------------------------------------+ |
|                                                  |
| [Reset to Default]              [Cancel] [Save]  |
+--------------------------------------------------+

File Changes Summary

File Action
backend/app/models/notification_template.py Create
backend/app/schemas/notification_template.py Create
backend/app/api/routes/notification_templates.py Create
backend/app/core/database.py Modify (add migration + seeding)
backend/app/models/__init__.py Modify (export new model)
backend/app/services/notification_service.py Modify (use templates)
backend/app/main.py Modify (register routes)
frontend/src/api/client.ts Modify (add API methods + types)
frontend/src/components/NotificationTemplateEditor.tsx Create
frontend/src/pages/SettingsPage.tsx Modify (add templates section)

Notes

  • Default templates cannot be deleted, only modified and reset
  • Templates are language-agnostic (user writes in their preferred language)
  • The existing notification_language setting can be removed later (templates replace i18n)
  • Variables that are unavailable for an event will render as empty string
  • Template rendering uses safe formatting (missing vars don't crash)