From 84f927393d71afac08df03f120ec8995c4af12ad Mon Sep 17 00:00:00 2001 From: CCCCCCTV <2091449962@qq.com> Date: Wed, 25 Feb 2026 12:57:11 +0800 Subject: [PATCH] fix(telegram): avoid duplicate message_thread_id in streaming --- .../platform/sources/telegram/tg_event.py | 50 +++++++++++++++---- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/astrbot/core/platform/sources/telegram/tg_event.py b/astrbot/core/platform/sources/telegram/tg_event.py index d7e3f16780..ade72f1107 100644 --- a/astrbot/core/platform/sources/telegram/tg_event.py +++ b/astrbot/core/platform/sources/telegram/tg_event.py @@ -18,6 +18,7 @@ Plain, Record, Reply, + Video, ) from astrbot.api.platform import AstrBotMessage, MessageType, PlatformMetadata @@ -36,6 +37,7 @@ class TelegramPlatformEvent(AstrMessageEvent): # 消息类型到 chat action 的映射,用于优先级判断 ACTION_BY_TYPE: dict[type, str] = { Record: ChatAction.UPLOAD_VOICE, + Video: ChatAction.UPLOAD_VIDEO, File: ChatAction.UPLOAD_DOCUMENT, Image: ChatAction.UPLOAD_PHOTO, Plain: ChatAction.TYPING, @@ -114,10 +116,18 @@ async def _send_media_with_action( **payload: Any, ) -> None: """发送媒体时显示 upload action,发送完成后恢复 typing""" - await cls._send_chat_action(client, user_name, upload_action, message_thread_id) - await send_coro(**payload) + effective_thread_id = message_thread_id or cast( + str | None, payload.get("message_thread_id") + ) + await cls._send_chat_action( + client, user_name, upload_action, effective_thread_id + ) + send_payload = dict(payload) + if effective_thread_id and "message_thread_id" not in send_payload: + send_payload["message_thread_id"] = effective_thread_id + await send_coro(**send_payload) await cls._send_chat_action( - client, user_name, ChatAction.TYPING, message_thread_id + client, user_name, ChatAction.TYPING, effective_thread_id ) @classmethod @@ -141,14 +151,16 @@ async def _send_voice_with_fallback( """ try: if use_media_action: + media_payload = dict(payload) + if message_thread_id and "message_thread_id" not in media_payload: + media_payload["message_thread_id"] = message_thread_id await cls._send_media_with_action( client, ChatAction.UPLOAD_VOICE, client.send_voice, user_name=user_name, - message_thread_id=message_thread_id, voice=path, - **cast(Any, payload), + **cast(Any, media_payload), ) else: await client.send_voice(voice=path, **cast(Any, payload)) @@ -162,15 +174,17 @@ async def _send_voice_with_fallback( "To enable voice messages, go to Telegram Settings → Privacy and Security → Voice Messages → set to 'Everyone'." ) if use_media_action: + media_payload = dict(payload) + if message_thread_id and "message_thread_id" not in media_payload: + media_payload["message_thread_id"] = message_thread_id await cls._send_media_with_action( client, ChatAction.UPLOAD_DOCUMENT, client.send_document, user_name=user_name, - message_thread_id=message_thread_id, document=path, caption=caption, - **cast(Any, payload), + **cast(Any, media_payload), ) else: await client.send_document( @@ -278,6 +292,13 @@ async def send_with_client( caption=i.text or None, use_media_action=False, ) + elif isinstance(i, Video): + path = await i.convert_to_file_path() + await client.send_video( + video=path, + caption=getattr(i, "text", None) or None, + **cast(Any, payload), + ) async def send(self, message: MessageChain) -> None: if self.get_message_type() == MessageType.GROUP_MESSAGE: @@ -333,7 +354,7 @@ async def send_streaming(self, generator, use_fallback: bool = False): "chat_id": user_name, } if message_thread_id: - payload["reply_to_message_id"] = message_thread_id + payload["message_thread_id"] = message_thread_id delta = "" current_content = "" @@ -375,7 +396,6 @@ async def send_streaming(self, generator, use_fallback: bool = False): ChatAction.UPLOAD_PHOTO, self.client.send_photo, user_name=user_name, - message_thread_id=message_thread_id, photo=image_path, **cast(Any, payload), ) @@ -388,7 +408,6 @@ async def send_streaming(self, generator, use_fallback: bool = False): ChatAction.UPLOAD_DOCUMENT, self.client.send_document, user_name=user_name, - message_thread_id=message_thread_id, document=path, filename=name, **cast(Any, payload), @@ -406,6 +425,17 @@ async def send_streaming(self, generator, use_fallback: bool = False): use_media_action=True, ) continue + elif isinstance(i, Video): + path = await i.convert_to_file_path() + await self._send_media_with_action( + self.client, + ChatAction.UPLOAD_VIDEO, + self.client.send_video, + user_name=user_name, + video=path, + **cast(Any, payload), + ) + continue else: logger.warning(f"不支持的消息类型: {type(i)}") continue