Files
haos-hacs-immich-album-watcher/plans/primary-plan.md
alexei.dolgolyov 88ffd5d077
Some checks failed
Validate / Hassfest (push) Has been cancelled
Add Claude AI Telegram bot enhancement (Phase 6)
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>
2026-03-19 14:38:51 +03:00

10 KiB

Immich Watcher: Standalone Web App + Shared Core Architecture

Status: Planning Created: 2026-03-19


Context

The current immich_album_watcher HA integration contains ~3,600 lines of tightly coupled code: Immich API client, change detection, Telegram notifications, and HA entities/services. A separate HA Blueprint (~2,000 lines) adds message templating, filtering, scheduled notifications, and memory mode.

Goal: Enable Immich album change notifications without Home Assistant via a standalone web application, while keeping the HAOS integration functional and sharing as much logic as possible.


Decisions

Decision Choice Rationale
Architecture Hybrid (Option C) HAOS standalone with shared core lib, optional server sync. No breaking changes for HA-only users.
Frontend SvelteKit + Shadcn-svelte Small bundle, fast, calm UI aesthetic. Good fit for self-hosted.
Notifications Telegram + Generic webhook Telegram from existing code. Webhook enables Discord/Slack/ntfy/custom.
Auth Multi-user (admin/user roles) Supports shared Immich servers. Admin manages servers/users, users manage own trackers.
Backend FastAPI + SQLite + APScheduler Async-native Python, zero external DB deps, proven scheduler.

Repository Structure

immich-watcher/
  packages/
    core/                              # Shared Python library
      pyproject.toml
      src/immich_watcher_core/
        immich_client.py               # Immich API (from coordinator.py)
        models.py                      # AssetInfo, AlbumData, AlbumChange, SharedLinkInfo
        change_detector.py             # Change detection (from coordinator.py)
        telegram/
          client.py                    # Telegram Bot API (from sensor.py)
          cache.py                     # File cache with pluggable backend
          media.py                     # Media download, size checks, group splitting
        webhook/
          client.py                    # Generic webhook notification provider
        templates.py                   # Jinja2 template engine
        storage.py                     # Abstract storage protocol + SQLite impl
        constants.py                   # Shared constants (from const.py)
      tests/

    server/                            # Standalone FastAPI app
      pyproject.toml
      src/immich_watcher_server/
        main.py                        # FastAPI entry point
        database/models.py             # SQLModel ORM
        database/migrations/           # Alembic
        api/                           # REST endpoints
        services/
          scheduler.py                 # APScheduler background polling
          watcher.py                   # Album polling orchestrator
          notifier.py                  # Notification dispatch
      Dockerfile
      docker-compose.yml

    haos/                              # Home Assistant integration (moved)
      custom_components/immich_album_watcher/
        ... (refactored to use core library)
      hacs.json

  frontend/                            # SvelteKit web UI source
    package.json
    src/
    dist/                              # Built static files served by FastAPI

  plans/                               # This folder
  README.md
  LICENSE

Shared Core Library Extractions

Core Module Source File What Gets Extracted
immich_client.py coordinator.py All /api/ calls, session injection via constructor
models.py coordinator.py L66-326 Dataclasses (already HA-independent)
change_detector.py coordinator.py L979-1066 detect_album_changes() pure function
telegram/client.py sensor.py (~1200 lines) Full Telegram Bot API: send_message/photo/video/media_group
telegram/cache.py storage.py TelegramFileCache with CacheBackend protocol
templates.py NEW (from blueprint logic) Jinja2 renderer with ~40 variables matching blueprint
storage.py storage.py Abstract protocol + SQLite implementation
webhook/client.py NEW Generic webhook POST JSON with event data

The ImmichClient accepts an aiohttp.ClientSession in constructor -- HA provides its managed session, standalone creates its own.


Standalone Server Design

Backend: FastAPI + SQLite + APScheduler

Database tables: users, immich_servers, notification_targets, message_templates, album_trackers, album_states, telegram_cache, notification_queue

Key API endpoints:

  • POST /api/auth/setup / POST /api/auth/login -- JWT auth
  • CRUD /api/servers -- Immich server connections
  • GET /api/servers/{id}/albums -- Fetch album list from Immich
  • CRUD /api/trackers -- Album trackers (album selection, event types, template overrides, targets)
  • CRUD /api/templates -- Message templates with preview
  • CRUD /api/targets -- Notification targets (Telegram chats, webhooks)
  • CRUD /api/users -- User management (admin only)
  • GET /api/status -- Dashboard data

Background: APScheduler runs one job per tracker at its scan interval. Each job: fetch album -> detect changes -> render template -> dispatch notification.

Frontend: SvelteKit + Shadcn-svelte

Pages:

  1. Setup wizard -- First-run: create admin account, connect Immich server
  2. Login -- Username/password
  3. Dashboard -- Active trackers overview, recent events timeline, server status
  4. Servers -- Add/edit Immich server connections (URL + API key validation)
  5. Trackers -- Create/edit album trackers:
    • Album picker (multi-select, fetched from Immich)
    • Event type toggles (assets added/removed, renamed, sharing changed, deleted)
    • Notification target selection
    • Template selection or per-tracker override
    • Scan interval, quiet hours
  6. Templates -- Jinja2 template editor:
    • CodeMirror with Jinja2 syntax highlighting
    • Live preview with sample album data
    • Variable reference sidebar
    • Default templates for common use cases
  7. Targets -- Manage notification destinations (Telegram chats, webhooks)
  8. Users -- User management (admin only)
  9. Settings -- Global defaults

Auth: Multi-user, bcrypt + JWT

  • Multiple user accounts with admin/user roles
  • Admin: full access (user management, server configuration)
  • User: manage own trackers, templates, and targets
  • First-run setup creates initial admin account

Deployment: Single Docker container, SQLite in mounted volume


HAOS Integration Changes

The integration gets refactored to delegate to core:

# coordinator.py becomes thin wrapper
class ImmichAlbumWatcherCoordinator(DataUpdateCoordinator):
    def __init__(self, ...):
        self._client = ImmichClient(session, url, api_key)  # from core

    async def _async_update_data(self):
        album = await self._client.get_album(self._album_id)
        change = detect_album_changes(old, album, pending)  # from core
        if change: self._fire_events(change, album)          # HA-specific
        return album

# sensor.py Telegram methods delegate to core
async def _execute_telegram_notification(self, ...):
    telegram = TelegramClient(session, token, cache)  # from core
    return await telegram.send_notification(...)

Phases

Rule 1: Before starting work on any phase, create a detailed trackable subplan at plans/phase-N-<name>.md with granular tasks, specific files to create/modify, and acceptance criteria. Do not begin implementation until the subplan is reviewed.

Rule 2: After completing each phase, perform a detailed code review of all changes. Use the code-reviewer agent to check for bugs, logic errors, security vulnerabilities, code quality issues, and adherence to project conventions. Document review findings in the phase subplan under a "## Review" section and fix any issues before committing.

Phase 1: Extract Core Library [x]

  • Extract models, Immich client, change detection, Telegram client, cache into packages/core/
  • Write unit tests for all extracted modules
  • Subplan: plans/phase-1-core-library.md

Phase 2: Wire Core into HAOS Integration [x]

  • Move integration to packages/haos/
  • Refactor coordinator.py, sensor.py, storage.py to use core library
  • Update manifest.json, hacs.json for new structure
  • Verify identical behavior with real Immich server
  • Subplan: plans/phase-2-haos-refactor.md

Phase 3: Build Server Backend [x]

  • FastAPI app with database, scheduler, API endpoints
  • Telegram + webhook notification providers
  • Jinja2 template engine with variable system matching blueprint
  • Subplan: plans/phase-3-server-backend.md

Phase 4: Build Frontend [x]

  • SvelteKit app with all pages (setup, dashboard, trackers, templates, targets, users)
  • Template editor with live preview
  • Album picker connected to Immich API
  • Subplan: plans/phase-4-frontend.md

Phase 5: HAOS-Server Sync (Optional) [x]

  • Add optional server URL to HA config flow
  • Implement tracker/template config sync
  • Subplan: plans/phase-5-haos-server-sync.md

Phase 6: Claude AI Telegram Bot Enhancement (Optional) [x]

  • Integrate Claude AI to enhance the Telegram notification bot
  • Enable conversational interactions: users can ask questions about their albums, get summaries, request specific photos
  • AI-powered message formatting: intelligent caption generation, album descriptions
  • Smart notification filtering: AI decides notification importance/relevance
  • Natural language tracker configuration via Telegram chat
  • Subplan: plans/phase-6-claude-ai-bot.md

Verification

  1. Core library: Unit tests for Immich client (mocked HTTP), change detection (pure function), Telegram client (mocked API), template rendering
  2. HAOS integration: After refactoring, verify all existing entities, services, and events work identically with a real Immich server
  3. Server backend: API integration tests with SQLite in-memory DB, scheduler tests
  4. Frontend: Manual testing of all pages, template editor preview, album picker
  5. End-to-end: Docker Compose up -> create account -> connect Immich -> create tracker -> trigger album change -> verify notification received