fix(commands): /albums honors per-chat scope, disable link previews

- /albums ignored CommandTrackerListener.allowed_album_ids and listed
  every album tracked by the provider — scoped chats saw neighbours'
  albums.  Thread the listener through _cmd_albums and apply the same
  intersect filter the media commands already use in _cmd_immich.
- Command text replies are listings (albums, events, people, ...) that
  embed multiple links; Telegram's default behavior of rendering a
  preview for the first URL is never useful here and ignored the
  "Disable link previews" toggle operators set on their target.  Always
  pass disable_web_page_preview=True from send_reply.
This commit is contained in:
2026-04-22 03:03:09 +03:00
parent 83215473c7
commit 4ff3876e49
3 changed files with 27 additions and 5 deletions
@@ -6,7 +6,7 @@ import asyncio
import logging
from typing import Any
from ...database.models import ServiceProvider
from ...database.models import CommandTrackerListener, ServiceProvider
from ...services import make_immich_provider
from ...services.http_session import get_http_session
from ..command_utils import get_trackers_for_provider
@@ -17,7 +17,10 @@ _LOGGER = logging.getLogger(__name__)
async def _cmd_albums(
provider: ServiceProvider, locale: str,
provider: ServiceProvider,
locale: str,
*,
listener: CommandTrackerListener | None = None,
) -> dict[str, Any]:
trackers = await get_trackers_for_provider(provider.id)
if not trackers:
@@ -31,6 +34,14 @@ async def _cmd_albums(
if aid not in seen:
seen.add(aid)
album_ids.append(aid)
# Per-chat album scope — match what _cmd_immich does for media commands.
# Without this, /albums leaks the full list of tracked albums into chats
# that were explicitly scoped to a subset.
if listener is not None and listener.allowed_album_ids is not None:
allowed = set(listener.allowed_album_ids)
album_ids = [aid for aid in album_ids if aid in allowed]
if not album_ids:
return {"albums": []}
@@ -86,7 +86,7 @@ class ImmichCommandHandler(ProviderCommandHandler):
ctx = await _cmd_status(provider, locale)
return CommandResponse(text=_render_cmd_template(cmd_templates, "status", locale, ctx))
if cmd == "albums":
ctx = await _cmd_albums(provider, locale)
ctx = await _cmd_albums(provider, locale, listener=listener)
return CommandResponse(text=_render_cmd_template(cmd_templates, "albums", locale, ctx))
if cmd == "events":
ctx = await _cmd_events(provider, count, locale)