fix(telegram): 修复 disable_web_page_preview 传递给不支持的方法及 UTF-16 偏移量问题

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 <noreply@anthropic.com>
This commit is contained in:
DDSRem
2026-04-01 23:13:33 +08:00
committed by jxxghp
parent 5440dbae51
commit d9eb3295b0
2 changed files with 22 additions and 10 deletions

View File

@@ -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

View File

@@ -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):