from __future__ import annotations import logging logger = logging.getLogger(__name__) SESSION_KEY_SEPARATOR = "::" class TelegramSession: @staticmethod def build_dm_key(chat_id: str) -> str: return f"dm{SESSION_KEY_SEPARATOR}{chat_id}" @staticmethod def build_group_key(chat_id: str) -> str: return f"group{SESSION_KEY_SEPARATOR}{chat_id}" @staticmethod def build_topic_key(chat_id: str, thread_id: str) -> str: return f"topic{SESSION_KEY_SEPARATOR}{chat_id}{SESSION_KEY_SEPARATOR}{thread_id}" @staticmethod def parse_session_key(key: str) -> dict: parts = key.split(SESSION_KEY_SEPARATOR, 2) if len(parts) == 2 and parts[0] == "dm": return {"type": "dm", "chat_id": parts[1]} if len(parts) == 2 and parts[0] == "group": return {"type": "group", "chat_id": parts[1]} if len(parts) == 3 and parts[0] == "topic": return {"type": "topic", "chat_id": parts[1], "thread_id": parts[2]} return {"type": "unknown", "key": key} class TelegramThreading: @staticmethod def extract_thread_id(unified_message: dict) -> str | None: thread_id = unified_message.get("thread_id") if thread_id: return str(thread_id) msg_id = unified_message.get("msg_id", "") if msg_id.startswith("tg:cb:"): return unified_message.get("thread_id") return None @staticmethod def resolve_reply_target(unified_message: dict) -> dict: group = unified_message.get("group") thread_id = TelegramThreading.extract_thread_id(unified_message) is_topic = unified_message.get("is_topic_message", False) target_type = "dm" target_id = unified_message.get("sender", {}).get("id", "") reply_to_id = str(unified_message.get("reply_to_id")) if unified_message.get("reply_to_id") else None if group: target_type = "group" target_id = group.get("id", "") if is_topic and thread_id: target_type = "topic" return { "target_type": target_type, "target_id": target_id, "thread_id": thread_id, "reply_to_id": reply_to_id, "session_key": TelegramThreading._build_session_key(target_type, target_id, thread_id), } @staticmethod def get_topic_agent_config(account: dict, group_id: str, thread_id: str) -> dict | None: groups = account.get("groups", {}) group_cfg = groups.get(group_id, {}) topics = group_cfg.get("topics", {}) if thread_id in topics: return topics[thread_id] return None @staticmethod def _build_session_key(target_type: str, target_id: str, thread_id: str | None) -> str: if target_type == "dm": return TelegramSession.build_dm_key(target_id) if target_type == "topic" and thread_id: return TelegramSession.build_topic_key(target_id, thread_id) return TelegramSession.build_group_key(target_id)