From 321bf94de8ccb1be4ffec59f86335d3f2ed6d3c2 Mon Sep 17 00:00:00 2001 From: DDSRem <1448139087@qq.com> Date: Wed, 1 Apr 2026 22:38:29 +0800 Subject: [PATCH] =?UTF-8?q?fix(telegram):=20=E8=BD=AC=E5=8F=91=E9=A2=91?= =?UTF-8?q?=E9=81=93=E6=B6=88=E6=81=AF=E6=97=A0=E6=B3=95=E6=8E=A5=E6=94=B6?= =?UTF-8?q?=E5=8F=8A=E5=86=85=E5=AE=B9=E4=B8=A2=E5=A4=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit message_handler 默认只处理 text 类型,转发的媒体消息(视频、图片等)被忽略; 解析器未读取 caption 字段导致媒体消息文字丢失; 新增提取 text_link 实体 URL 和 reply_markup URL 按钮信息到文本中。 Co-Authored-By: Claude Opus 4.6 --- app/modules/telegram/__init__.py | 61 +++++++++++++++++++++++++++++++- app/modules/telegram/telegram.py | 5 ++- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/app/modules/telegram/__init__.py b/app/modules/telegram/__init__.py index 2aa419a1..86b77ede 100644 --- a/app/modules/telegram/__init__.py +++ b/app/modules/telegram/__init__.py @@ -191,11 +191,18 @@ class TelegramModule(_ModuleBase, _MessageBase[Telegram]): """ 处理普通文本消息 """ - text = msg.get("text") + text = msg.get("text") or msg.get("caption") user_id = msg.get("from", {}).get("id") user_name = msg.get("from", {}).get("username") chat_id = msg.get("chat", {}).get("id") + # 将 text_link 实体中的 URL 嵌入到文本中 + if text: + text = self._embed_entity_links(text, msg.get("entities") or msg.get("caption_entities")) + + # 将 reply_markup 中的 URL 按钮信息追加到文本中 + text = self._append_reply_markup_links(text, msg.get("reply_markup")) + images = self._extract_images(msg) if user_id: @@ -271,6 +278,58 @@ class TelegramModule(_ModuleBase, _MessageBase[Telegram]): return images if images else None + @staticmethod + def _embed_entity_links(text: str, entities: Optional[List[dict]]) -> str: + """ + 将 text_link 实体中的 URL 嵌入到文本中 + + :param text: 原始文本 + :param entities: 消息实体列表 + :return: 嵌入链接后的文本 + """ + if not entities: + return text + text_link_entities = sorted( + [e for e in entities if e.get("type") == "text_link" and e.get("url")], + key=lambda e: e.get("offset", 0), + reverse=True, + ) + for entity in text_link_entities: + offset = entity.get("offset", 0) + length = entity.get("length", 0) + url = entity["url"] + display_text = text[offset: offset + length] + text = text[:offset] + f"{display_text}({url})" + text[offset + length:] + return text + + @staticmethod + def _append_reply_markup_links(text: Optional[str], reply_markup: Optional[dict]) -> Optional[str]: + """ + 将 reply_markup 中的 URL 按钮信息追加到文本末尾 + + :param text: 原始文本 + :param reply_markup: 消息的 reply_markup 字段 + :return: 追加按钮链接后的文本 + """ + if not reply_markup: + return text + inline_keyboard = reply_markup.get("inline_keyboard") + if not inline_keyboard: + return text + button_lines = [] + for row in inline_keyboard: + for button in row: + btn_text = button.get("text", "") + btn_url = button.get("url") + if btn_url: + button_lines.append(f"{btn_text}({btn_url})") + if not button_lines: + return text + buttons_text = "\n".join(button_lines) + if text: + return f"{text}\n{buttons_text}" + return buttons_text + @staticmethod def _clean_bot_mention(text: str, bot_username: Optional[str]) -> str: """ diff --git a/app/modules/telegram/telegram.py b/app/modules/telegram/telegram.py index db2b9488..5e3a7084 100644 --- a/app/modules/telegram/telegram.py +++ b/app/modules/telegram/telegram.py @@ -101,7 +101,10 @@ class Telegram: "温馨提示:直接发送名称或`订阅`+名称,搜索或订阅电影、电视剧", ) - @_bot.message_handler(func=lambda message: True) + @_bot.message_handler(content_types=[ + "text", "photo", "video", "document", "animation", + "audio", "voice", "sticker", "video_note", + ], 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)