fix(telegram): solve attachment path issues for Dev and Docker environments

keyboardstaff committed Mar 22, 2026 at 17:14 UTC 035d53067b31a614fca752aab789bb0879b5763e
1 file changed +26 -15
plugins/_telegram_integration/helpers/handler.py
+26 -15
@@ -24,8 +24,8 @@ from plugins._telegram_integration.helpers.bot_manager import get_bot
24
25
26 PLUGIN_NAME = "_telegram_integration"
27 -DOWNLOAD_FOLDER = "usr/telegram/attachments"
28 -STATE_FILE = "usr/telegram/state.json"
27 +DOWNLOAD_FOLDER = "usr/uploads"
28 +STATE_FILE = "usr/plugins/_telegram_integration/state.json"
29
30 # Context data keys
31 CTX_TG_BOT = "telegram_bot"
@@ -69,6 +69,9 @@ def cleanup_old_attachments():
69 config = plugins.get_plugin_config(PLUGIN_NAME) or {}
70 bots_cfg = config.get("bots") or []
71 total_removed = 0
72 + upload_dir = files.get_abs_path(DOWNLOAD_FOLDER)
73 + if not os.path.isdir(upload_dir):
74 + return
75 for bot_cfg in bots_cfg:
76 bot_name = bot_cfg.get("name", "")
77 if not bot_name:
@@ -76,12 +79,12 @@ def cleanup_old_attachments():
79 max_age_hours = bot_cfg.get("attachment_max_age_hours", 0)
80 if not max_age_hours or max_age_hours <= 0:
81 continue
79 - folder = os.path.join(files.get_abs_path(DOWNLOAD_FOLDER), bot_name)
80 - if not os.path.isdir(folder):
81 - continue
82 + prefix = f"tg_{bot_name}_"
83 cutoff = time.time() - max_age_hours * 3600
83 - for name in os.listdir(folder):
84 - path = os.path.join(folder, name)
84 + for name in os.listdir(upload_dir):
85 + if not name.startswith(prefix):
86 + continue
87 + path = os.path.join(upload_dir, name)
88 try:
89 if os.path.isfile(path) and os.path.getmtime(path) < cutoff:
90 os.remove(path)
@@ -415,13 +418,20 @@ def _extract_message_content(message: TgMessage) -> str:
418 async def _download_attachments(bot, message: TgMessage, bot_name: str = "") -> list[str]:
419 """Download photos, documents, audio, voice, video from message."""
420 paths: list[str] = []
418 - sub = bot_name if bot_name else "_default"
419 - download_base = os.path.join(files.get_abs_path(DOWNLOAD_FOLDER), sub)
420 - os.makedirs(download_base, exist_ok=True)
421 + tg_prefix = f"tg_{bot_name}_" if bot_name else "tg_"
422 + # Host-local path for actual file I/O
423 + download_dir = files.get_abs_path(DOWNLOAD_FOLDER)
424 + os.makedirs(download_dir, exist_ok=True)
425 + # Docker-style path for agent references
426 + download_dir_ref = files.get_abs_path_dockerized(DOWNLOAD_FOLDER)
427
428 async def _dl(file_id: str, filename: str) -> str | None:
423 - dest = os.path.join(download_base, f"{uuid.uuid4().hex[:8]}_{filename}")
424 - return await tc.download_file(bot, file_id, dest)
429 + safe_name = f"{tg_prefix}{uuid.uuid4().hex[:8]}_{filename}"
430 + dest = os.path.join(download_dir, safe_name)
431 + result = await tc.download_file(bot, file_id, dest)
432 + if result:
433 + return os.path.join(download_dir_ref, safe_name)
434 + return None
435
436 # Photo: get largest resolution
437 if message.photo:
@@ -479,10 +489,11 @@ async def send_telegram_reply(
489 async with _temp_bot(instance.bot.token, default=DefaultBotProperties(parse_mode=ParseMode.HTML)) as reply_bot:
490 if attachments:
491 for path in attachments:
482 - if tc.is_image_file(path):
483 - await tc.send_photo(reply_bot, chat_id, path)
492 + local_path = files.fix_dev_path(path)
493 + if tc.is_image_file(local_path):
494 + await tc.send_photo(reply_bot, chat_id, local_path)
495 else:
485 - await tc.send_file(reply_bot, chat_id, path)
496 + await tc.send_file(reply_bot, chat_id, local_path)
497
498 if response_text:
499 html_text = tc.md_to_telegram_html(response_text)