From d9eb3295b04de2f1e773106e0a13153e312a0f25 Mon Sep 17 00:00:00 2001 From: DDSRem <1448139087@qq.com> Date: Wed, 1 Apr 2026 23:13:33 +0800 Subject: [PATCH] =?UTF-8?q?fix(telegram):=20=E4=BF=AE=E5=A4=8D=20disable?= =?UTF-8?q?=5Fweb=5Fpage=5Fpreview=20=E4=BC=A0=E9=80=92=E7=BB=99=E4=B8=8D?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E7=9A=84=E6=96=B9=E6=B3=95=E5=8F=8A=20UTF-16?= =?UTF-8?q?=20=E5=81=8F=E7=A7=BB=E9=87=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. disable_web_page_preview 仅在 send_message 时传入,避免 send_photo/send_document 抛出 TypeError 2. _embed_entity_links 中将 Telegram UTF-16 编码单位偏移量转换为 Python 字符偏移量,修复含 emoji 等非 BMP 字符时切片错误 Co-Authored-By: Claude Opus 4.6 --- app/modules/telegram/__init__.py | 8 ++++++-- app/modules/telegram/telegram.py | 24 ++++++++++++++++-------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/app/modules/telegram/__init__.py b/app/modules/telegram/__init__.py index 7ab3c950..cff0f7ed 100644 --- a/app/modules/telegram/__init__.py +++ b/app/modules/telegram/__init__.py @@ -294,12 +294,16 @@ class TelegramModule(_ModuleBase, _MessageBase[Telegram]): key=lambda e: e.get("offset", 0), reverse=True, ) + text_utf16 = text.encode("utf-16-le") 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:] + char_offset = len(text_utf16[:offset * 2].decode("utf-16-le")) + char_length = len(text_utf16[offset * 2: (offset + length) * 2].decode("utf-16-le")) + display_text = text[char_offset: char_offset + char_length] + text = text[:char_offset] + f"{display_text}({url})" + text[char_offset + char_length:] + text_utf16 = text.encode("utf-16-le") return text @staticmethod diff --git a/app/modules/telegram/telegram.py b/app/modules/telegram/telegram.py index 265bb6f1..0cf4b36f 100644 --- a/app/modules/telegram/telegram.py +++ b/app/modules/telegram/telegram.py @@ -782,9 +782,6 @@ class Telegram: "parse_mode": "MarkdownV2", "reply_markup": reply_markup, } - if disable_web_page_preview is not None: - kwargs["disable_web_page_preview"] = disable_web_page_preview - # 处理图片 image = self.__process_image(image) @@ -792,10 +789,14 @@ class Telegram: # 图片消息的标题长度限制为1024,文本消息为4096 caption_limit = 1024 if image else 4096 if len(caption) < caption_limit: - ret = self.__send_short_message(image, caption, **kwargs) + ret = self.__send_short_message(image, caption, + disable_web_page_preview=disable_web_page_preview, + **kwargs) else: sent_idx = set() - ret = self.__send_long_message(image, caption, sent_idx, **kwargs) + ret = self.__send_long_message(image, caption, sent_idx, + disable_web_page_preview=disable_web_page_preview, + **kwargs) return ret except Exception as e: @@ -815,7 +816,8 @@ class Telegram: return image @retry(RetryException, logger=logger) - def __send_short_message(self, image: Optional[bytes], caption: str, **kwargs): + def __send_short_message(self, image: Optional[bytes], caption: str, + disable_web_page_preview: Optional[bool] = None, **kwargs): """ 发送短消息 """ @@ -825,13 +827,16 @@ class Telegram: photo=image, caption=standardize(caption), **kwargs ) else: + if disable_web_page_preview is not None: + kwargs["disable_web_page_preview"] = disable_web_page_preview return self._bot.send_message(text=standardize(caption), **kwargs) except Exception: raise RetryException(f"发送{'图片' if image else '文本'}消息失败") @retry(RetryException, logger=logger) def __send_long_message( - self, image: Optional[bytes], caption: str, sent_idx: set, **kwargs + self, image: Optional[bytes], caption: str, sent_idx: set, + disable_web_page_preview: Optional[bool] = None, **kwargs ): """ 发送长消息 @@ -855,8 +860,11 @@ class Telegram: current_reply_markup = reply_markup if i == 0 else None if item.content_type == ContentTypes.TEXT and (i != 0 or not image): + msg_kwargs = dict(**kwargs) + if disable_web_page_preview is not None: + msg_kwargs["disable_web_page_preview"] = disable_web_page_preview ret = self._bot.send_message( - **kwargs, text=item.content, reply_markup=current_reply_markup + **msg_kwargs, text=item.content, reply_markup=current_reply_markup ) elif item.content_type == ContentTypes.PHOTO or (image and i == 0):