diff --git a/app/modules/telegram/__init__.py b/app/modules/telegram/__init__.py index a9c55a89..e43900c7 100644 --- a/app/modules/telegram/__init__.py +++ b/app/modules/telegram/__init__.py @@ -195,20 +195,22 @@ class TelegramModule(_ModuleBase, _MessageBase[Telegram]): text = msg.get("text") user_id = msg.get("from", {}).get("id") user_name = msg.get("from", {}).get("username") + # Extract chat_id to enable correct reply targeting + chat_id = msg.get("chat", {}).get("id") if text and user_id: logger.info(f"收到来自 {client_config.name} 的Telegram消息:" - f"userid={user_id}, username={user_name}, text={text}") + f"userid={user_id}, username={user_name}, chat_id={chat_id}, text={text}") # 检查权限 admin_users = client_config.config.get("TELEGRAM_ADMINS") user_list = client_config.config.get("TELEGRAM_USERS") - chat_id = client_config.config.get("TELEGRAM_CHAT_ID") + config_chat_id = client_config.config.get("TELEGRAM_CHAT_ID") if text.startswith("/"): if admin_users \ and str(user_id) not in admin_users.split(',') \ - and str(user_id) != chat_id: + and str(user_id) != config_chat_id: client.send_msg(title="只有管理员才有权限执行此命令", userid=user_id) return None else: @@ -223,7 +225,8 @@ class TelegramModule(_ModuleBase, _MessageBase[Telegram]): source=client_config.name, userid=user_id, username=user_name, - text=text + text=text, + chat_id=str(chat_id) if chat_id else None ) return None diff --git a/app/modules/telegram/telegram.py b/app/modules/telegram/telegram.py index feb6a437..92987032 100644 --- a/app/modules/telegram/telegram.py +++ b/app/modules/telegram/telegram.py @@ -25,6 +25,7 @@ class Telegram: _event = Event() _bot: telebot.TeleBot = None _callback_handlers: Dict[str, Callable] = {} # 存储回调处理器 + _user_chat_mapping: Dict[str, str] = {} # userid -> chat_id mapping for reply targeting def __init__(self, TELEGRAM_TOKEN: Optional[str] = None, TELEGRAM_CHAT_ID: Optional[str] = None, **kwargs): """ @@ -59,6 +60,8 @@ class Telegram: @_bot.message_handler(func=lambda message: True) def echo_all(message): + # Update user-chat mapping when receiving messages + self._update_user_chat_mapping(message.from_user.id, message.chat.id) RequestUtils(timeout=15).post_res(self._ds_url, json=message.json) @_bot.callback_query_handler(func=lambda call: True) @@ -67,6 +70,9 @@ class Telegram: 处理按钮点击回调 """ try: + # Update user-chat mapping for callbacks too + self._update_user_chat_mapping(call.from_user.id, call.message.chat.id) + # 解析回调数据 callback_data = call.data user_id = str(call.from_user.id) @@ -112,6 +118,23 @@ class Telegram: self._polling_thread.start() logger.info("Telegram消息接收服务启动") + def _update_user_chat_mapping(self, userid: int, chat_id: int) -> None: + """ + 更新用户与聊天的映射关系 + :param userid: 用户ID + :param chat_id: 聊天ID + """ + if userid and chat_id: + self._user_chat_mapping[str(userid)] = str(chat_id) + + def _get_user_chat_id(self, userid: str) -> Optional[str]: + """ + 获取用户对应的聊天ID + :param userid: 用户ID + :return: 聊天ID或None + """ + return self._user_chat_mapping.get(str(userid)) if userid else None + def get_state(self) -> bool: """ 获取状态 @@ -153,10 +176,8 @@ class Telegram: if link: caption = f"{caption}\n[查看详情]({link})" - if userid: - chat_id = userid - else: - chat_id = self._telegram_chat_id + # Determine target chat_id with improved logic using user mapping + chat_id = self._determine_target_chat_id(userid, original_chat_id) # 创建按钮键盘 reply_markup = None @@ -175,6 +196,29 @@ class Telegram: logger.error(f"发送消息失败:{msg_e}") return False + def _determine_target_chat_id(self, userid: Optional[str] = None, + original_chat_id: Optional[str] = None) -> str: + """ + 确定目标聊天ID,使用用户映射确保回复到正确的聊天 + :param userid: 用户ID + :param original_chat_id: 原消息的聊天ID + :return: 目标聊天ID + """ + # 1. 优先使用原消息的聊天ID (编辑消息场景) + if original_chat_id: + return original_chat_id + + # 2. 如果有userid,尝试从映射中获取用户的聊天ID + if userid: + mapped_chat_id = self._get_user_chat_id(userid) + if mapped_chat_id: + return mapped_chat_id + # 如果映射中没有,回退到使用userid作为聊天ID (私聊场景) + return userid + + # 3. 最后使用默认聊天ID + return self._telegram_chat_id + def send_medias_msg(self, medias: List[MediaInfo], userid: Optional[str] = None, title: Optional[str] = None, link: Optional[str] = None, buttons: Optional[List[List[Dict]]] = None, @@ -216,10 +260,8 @@ class Telegram: if link: caption = f"{caption}\n[查看详情]({link})" - if userid: - chat_id = userid - else: - chat_id = self._telegram_chat_id + # Determine target chat_id with improved logic using user mapping + chat_id = self._determine_target_chat_id(userid, original_chat_id) # 创建按钮键盘 reply_markup = None @@ -278,10 +320,8 @@ class Telegram: if link: caption = f"{caption}\n[查看详情]({link})" - if userid: - chat_id = userid - else: - chat_id = self._telegram_chat_id + # Determine target chat_id with improved logic using user mapping + chat_id = self._determine_target_chat_id(userid, original_chat_id) # 创建按钮键盘 reply_markup = None