alexei.dolgolyov fe38d20b96 perf(immich): skip full album fetch on idle ticks; delta-fetch for active ones
Optimizes polling for large Immich albums (tested path targets ~200k
assets). Combined impact on idle albums drops per-tick cost from ~150 MB
fetch to ~few hundred bytes; active albums fetch O(changes) instead of
O(library).

Core changes
- ImmichAlbumMeta + get_album_meta() using ?withoutAssets=true as a
  cheap change-detection probe.
- poll() fast-path: skip full fetch when meta fingerprint matches and
  no pending assets are outstanding.
- poll() delta-path: search/metadata with updatedAfter when fingerprint
  changed, falling back to full fetch on count decrease or mixed
  add+remove that delta can't reconcile.
- asyncio.gather over meta probes so a 20-album tracker pays one
  round-trip of latency instead of 20.
- Event payload cap (50 added / 200 removed) so a bulk import can't
  explode a Jinja template or exceed Telegram's message limits.
- Module-level users cache (1h TTL, sha256-keyed) shared across
  providers on the same Immich server.
- Tick-scoped shared-links cache via new
  get_all_shared_links_by_album() — one /api/shared-links request per
  tick instead of one per changed album.

Server changes
- meta_fingerprint JSON column on NotificationTrackerState + migration.
- watcher skips the asset_ids DB rewrite when the fingerprint didn't
  change, avoiding ~8 MB JSON writes on idle ticks for huge albums.
- Adaptive polling: after 10 empty ticks skip 1-in-2, after 30 skip
  1-in-4, reset on first detected change; resets on schedule changes.
- APScheduler jitter (interval/4, capped at 30s) to smooth thundering-
  herd bursts when many trackers share the same scan_interval.
2026-04-22 18:55:26 +03:00
2026-04-22 18:02:09 +03:00
2026-04-22 18:02:09 +03:00

Notify Bridge

A generic bridge between service providers and notification targets.

Notify Bridge monitors services (like Immich photo servers) for changes and dispatches notifications to configurable targets (Telegram, webhooks) using customizable templates.

Architecture

  • Service Providers — Connectors to external services (Immich, more coming)
  • Trackers — Monitor specific collections within a provider for changes
  • Tracking Configs — Define what events to watch for and scheduling rules
  • Notification Targets — Where to send notifications (Telegram chats, webhook URLs)
  • Template Configs — Jinja2 templates that format notifications per provider type

Project Structure

packages/
  core/       — Shared library: providers, models, notifications, templates
  server/     — FastAPI REST server with SQLite database
frontend/     — SvelteKit dashboard (Svelte 5, Tailwind CSS v4)

Quick Docker Deploy

docker run -d \
  --name notify-bridge \
  --restart unless-stopped \
  -p 8420:8420 \
  -v notify-bridge-data:/data \
  -e NOTIFY_BRIDGE_SECRET_KEY=$(openssl rand -hex 32) \
  git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge:latest

Then open http://localhost:8420 in your browser.

Environment Variables

Variable Required Default Description
NOTIFY_BRIDGE_SECRET_KEY Yes Secret key for JWT tokens (min 32 chars)
NOTIFY_BRIDGE_PORT No 8420 Server listen port
NOTIFY_BRIDGE_CORS_ALLOWED_ORIGINS No * Comma-separated allowed CORS origins
NOTIFY_BRIDGE_DEBUG No false Enable debug logging

Docker Compose

services:
  notify-bridge:
    image: git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge:latest
    container_name: notify-bridge
    restart: unless-stopped
    ports:
      - "8420:8420"
    volumes:
      - notify-bridge-data:/data
    environment:
      - NOTIFY_BRIDGE_SECRET_KEY=your-secret-key-min-32-characters

volumes:
  notify-bridge-data:

Quick Start (Development)

# Backend
cd packages/server
pip install -e .
NOTIFY_BRIDGE_DATA_DIR=./test-data NOTIFY_BRIDGE_SECRET_KEY=your-secret-key-min-32chars \
  python -m uvicorn notify_bridge_server.main:app --host 0.0.0.0 --port 8420

# Frontend
cd frontend
npm install
npm run dev

Supported Providers

  • Immich — Photo/video server with album change detection
S
Description
Bridge service events (Immich, …) to notification targets (Telegram, webhooks) via customizable Jinja2 templates and commands.
Readme 9.9 MiB
2026-06-05 21:04:57 +03:00
Languages
Python 59.9%
Svelte 26.1%
HTML 7.6%
TypeScript 3.7%
Jinja 2%
Other 0.6%