Backend: Fix CORS wildcard+credentials, add secret key warning, remove raw
API keys from sync endpoint, fix N+1 queries in watcher/sync, fix
AttributeError on event_types, delete dead scheduled.py/templates.py,
add limit cap on history, re-validate server on URL/key update, apply
tracking/template config IDs in update_target.
HA Integration: Replace datetime.now() with dt_util.now(), fix notification
queue to only remove successfully sent items, use album UUID for entity
unique IDs, add shared links dirty flag and users cache hourly refresh,
deduplicate _is_quiet_hours, add HTTP timeouts, cache albums in config
flow, change iot_class to local_polling.
Frontend: Make i18n reactive via $state (remove window.location.reload),
add Modal transitions/a11y/Escape key, create ConfirmModal replacing all
confirm() calls, add error handling to all pages, replace Unicode nav
icons with MDI SVGs, add card hover effects, dashboard stat icons, global
focus-visible styles, form slide transitions, mobile responsive bottom
nav, fix password error color, add ~20 i18n keys (EN/RU).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Major model restructuring for clean separation of concerns:
New entities:
- TrackingConfig: What to react to (event types, asset filters,
periodic/scheduled/memory mode config) - reusable across targets
- TemplateConfig: All ~15 template slots from blueprint (event
messages, asset formatting, date/location, scheduled messages)
with full defaults - separate entities per locale
Changed entities:
- AlbumTracker: Simplified to album selection + polling + target_ids
(removed event_types, template_id, all filter fields)
- NotificationTarget: Extended with tracking_config_id and
template_config_id FKs (many-to-one, reusable configs)
Removed entities:
- MessageTemplate (replaced by TemplateConfig)
- ScheduledJob (absorbed into TrackingConfig)
Updated services:
- watcher.py: Each target checked against its own tracking_config
for event filtering before sending notification
- notifier.py: Uses target's template_config to select the right
template slot based on event type
New API routes:
- /api/tracking-configs/* (CRUD)
- /api/template-configs/* (CRUD + per-slot preview)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix jinja2.sandbox import: use `from jinja2.sandbox import
SandboxedEnvironment` (dotted attribute access doesn't work)
in templates.py, sync.py, and notifier.py
- Fix greenlet crash in tracker trigger: SQLAlchemy async sessions
can't survive across aiohttp.ClientSession context managers.
Eagerly load all tracker/server data before entering HTTP context.
Split check_tracker into check_tracker (scheduler, own session)
and check_tracker_with_session (API, reuses route session).
- Fix _check_album to accept pre-loaded params instead of tracker
object (avoids lazy-load access after greenlet context break)
Tested end-to-end against live Immich server:
- Server connection + album browsing: OK (39 albums)
- Template creation + preview: OK
- Webhook target creation: OK
- Tracker creation + trigger: OK (initialized 4 assets)
- Second trigger: OK (no_changes detected)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Integrate Claude AI into the notification system for intelligent
conversational interactions and AI-powered captions.
New modules:
- ai/service.py: Claude API client with conversation history,
caption generation, and album activity summarization
- ai/telegram_webhook.py: Telegram webhook handler for incoming
bot messages, routes to AI service for responses
Features:
- Conversational bot: users chat with the bot about albums
- AI captions: intelligent notification messages based on album
context (people, locations, dates) - enabled per target via
"ai_captions" config flag
- Album summaries: "what's new?" triggers AI-generated overview
- /start command with welcome message
- Webhook register/unregister endpoints
Architecture:
- Per-chat conversation history (in-memory, capped at 20 messages)
- Graceful degradation: AI features completely disabled without
IMMICH_WATCHER_ANTHROPIC_API_KEY env var (zero impact)
- AI caption failure falls back to Jinja2 template rendering
- Health endpoint reports ai_enabled status
Config: IMMICH_WATCHER_ANTHROPIC_API_KEY, IMMICH_WATCHER_AI_MODEL,
IMMICH_WATCHER_AI_MAX_TOKENS
Server now has 45 API routes (was 42 after Phase 5).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Build a complete standalone web server for Immich album change
notifications, independent of Home Assistant. Uses the shared
core library from Phase 1.
Server features:
- FastAPI with async SQLite (SQLModel + aiosqlite)
- Multi-user auth with JWT (admin/user roles, setup wizard)
- CRUD APIs: Immich servers, album trackers, message templates,
notification targets (Telegram + webhook), user management
- APScheduler background polling per tracker
- Jinja2 template rendering with live preview
- Album browser proxied from Immich API
- Event logging and dashboard status endpoint
- Docker deployment (single container, SQLite in volume)
39 API routes, 14 integration tests passing.
Also adds Phase 6 (Claude AI Telegram bot enhancement) to the
primary plan as an optional future phase.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>