diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 517e924..0c67679 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,27 +1,22 @@ -# v0.2.6 (2026-04-22) +# v0.2.7 (2026-04-22) -Bug-fix release. Notably: saving settings was silently overwriting the -Telegram webhook secret with its own display mask, invalidating HMAC on -every webhook-mode bot after any settings save. Also fixes template-editor -variable discovery for provider-specific command slots (`/search`, `/status`, -`/repos`, `/issues`, `/boards`), asset enrichment (city / country / favorite) -for Immich `/search` / `/find` / `/person` / `/place`, and video rendering -in command media groups. +Follow-up to v0.2.6: unifies the Telegram send routine across notifications +and bot commands so both sides share the same aiohttp session, the same +`file_id` caches, and the same rules for video / thumbnail URL construction. +Eliminates repeat uploads that happened because single-asset sends and media +groups were keyed in different caches. ## Bug Fixes -- **Don't clobber the Telegram webhook secret with its mask on save** — `GET /settings` returns the secret masked as `***`; the frontend bound that masked value into state and shipped it back on any Save, so the PUT handler persisted the mask as the new secret. The next GET re-masked the mask to itself, so the UI showed no corruption while HMAC verification silently broke for every webhook-mode bot. Incoming values that begin with `***` are now treated as *unchanged*; empty strings still clear the secret explicitly. **Operators running webhook-mode bots should save the page once with a known-good secret after upgrading.** ([8531168](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/8531168)) -- **Surface Variables button / autocomplete for provider-specific command slots** — the command-template-configs UI only resolved slot variables against the shared catalog, so Immich's `/search` and `/status`, Gitea's `/repos` / `/issues`, and Planka's `/boards` offered no autocomplete. It now resolves against the active provider (`varsRef[provider_type][slot]`) first, falling back to shared entries. ([fab6169](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/fab6169)) -- **Enrich raw Immich search results through `build_asset_dict`** — `/search`, `/find`, `/person`, `/place` previously handed raw API rows to templates, so `city` / `country` (from `exifInfo`) and `is_favorite` (mapped from `isFavorite`) were missing and templates couldn't render location or favorite indicators. Now normalised the same way as notification events. ([fab6169](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/fab6169)) -- **Videos render correctly in command media groups** — `/latest`, `/random`, `/favorites` were sending videos as still thumbnails because the media-group path duplicated asset-typing logic. Extracted `build_telegram_asset_entry` into a shared helper so the notification dispatcher and command groups agree on video typing and `/video/playback` URLs. ([fab6169](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/fab6169)) -- **Command media groups reuse the Telegram `file_id` cache** — `send_media_group` was re-uploading assets on every repeat command instead of honoring the cache the notification dispatcher already populates. Now shares the cache, avoiding re-upload churn. ([fab6169](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/fab6169)) +- **Single-asset sends now hit the asset cache** — `TelegramClient._get_cache_and_key` treats `cache_key` values that look like asset UUIDs as asset-cache entries. Single-asset sends were storing `file_id`s in `url_cache` while the media-group path stored them in `asset_cache`, so repeat sends of the same asset never hit the cache and re-uploaded. ([6de9a12](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/6de9a12)) +- **Notifications and commands now share the Telegram client factory** — new `services/telegram_send.py` is the single construction path for `TelegramClient`: always wires the shared aiohttp session and both `file_id` caches. `send_reply` and `send_media_group` in `commands/handler.py` now delegate to the factory instead of constructing their own uncached clients, so commands reuse `file_id`s populated by notification dispatches (and vice versa) instead of re-uploading the same bytes. ([6de9a12](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/6de9a12)) +- **Single rule for `/video/playback` vs thumbnail URLs** — extracted `build_asset_media_urls` so the notification dispatcher's `asset_to_media` and the bot command handlers' `common._format_assets` agree on when to use the playback URL and when to use the thumbnail. Removes a subtle drift that could show stills in one path and video in the other for the same asset. ([6de9a12](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/6de9a12)) ---
All Commits -- [fab6169](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/fab6169) — fix(commands): enrich search assets, surface variables for all command slots *(alexei.dolgolyov)* -- [8531168](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/8531168) — fix(settings): don't clobber webhook secret with its mask on save *(alexei.dolgolyov)* +- [6de9a12](https://git.dolgolyov-family.by/alexei.dolgolyov/notify-bridge/commit/6de9a12) — fix(telegram): unify send routine across notifications and commands *(alexei.dolgolyov)*
diff --git a/frontend/package.json b/frontend/package.json index 69b8889..f13256e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "notify-bridge-frontend", "private": true, - "version": "0.2.6", + "version": "0.2.7", "type": "module", "scripts": { "dev": "vite dev", diff --git a/packages/core/pyproject.toml b/packages/core/pyproject.toml index 1756cb8..52a5c66 100644 --- a/packages/core/pyproject.toml +++ b/packages/core/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "notify-bridge-core" -version = "0.2.6" +version = "0.2.7" description = "Core library for Notify Bridge — service provider abstractions, models, notifications, and templates" requires-python = ">=3.12" dependencies = [ diff --git a/packages/server/pyproject.toml b/packages/server/pyproject.toml index 3569cd7..31f97bb 100644 --- a/packages/server/pyproject.toml +++ b/packages/server/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "notify-bridge-server" -version = "0.2.6" +version = "0.2.7" description = "Standalone Notify Bridge server — FastAPI REST API with SQLite database" requires-python = ">=3.12" dependencies = [