From b44a8f629e5b7b37923a820fb2662422ccad3370 Mon Sep 17 00:00:00 2001 From: woleigedouer <38418090+woleigedouer@users.noreply.github.com> Date: Tue, 19 May 2026 14:33:45 +0800 Subject: [PATCH 1/3] fix(telegram): normalize reply sender_id to self_id for bot replies Telegram adapter stored Reply.sender_id as numeric user ID while self_id is the bot username, causing WakingCheckStage to never match replies to bot messages in groups. --- .../platform/sources/telegram/tg_adapter.py | 6 +- tests/test_telegram_adapter.py | 71 +++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/astrbot/core/platform/sources/telegram/tg_adapter.py b/astrbot/core/platform/sources/telegram/tg_adapter.py index 76863a1949..7ef7a33e8c 100644 --- a/astrbot/core/platform/sources/telegram/tg_adapter.py +++ b/astrbot/core/platform/sources/telegram/tg_adapter.py @@ -506,11 +506,15 @@ def _apply_caption() -> None: reply_abm = await self.convert_message(reply_update, context, False) if reply_abm: + reply_sender_id = str(reply_abm.sender.user_id) + if reply_sender_id == str(context.bot.id): + reply_sender_id = message.self_id + message.message.append( Comp.Reply( id=reply_abm.message_id, chain=reply_abm.message, - sender_id=reply_abm.sender.user_id, + sender_id=reply_sender_id, sender_nickname=reply_abm.sender.nickname, time=reply_abm.timestamp, message_str=reply_abm.message_str, diff --git a/tests/test_telegram_adapter.py b/tests/test_telegram_adapter.py index 8290899d1a..e5a0d33746 100644 --- a/tests/test_telegram_adapter.py +++ b/tests/test_telegram_adapter.py @@ -79,6 +79,77 @@ def _build_context() -> MagicMock: return context +def _find_reply_component(message) -> Comp.Reply: + return next( + component for component in message.message if isinstance(component, Comp.Reply) + ) + + +@pytest.mark.asyncio +async def test_telegram_reply_to_bot_normalizes_sender_id_to_self_id(): + TelegramPlatformAdapter = _load_telegram_adapter() + adapter = TelegramPlatformAdapter( + make_platform_config("telegram"), + {}, + asyncio.Queue(), + ) + reply_to_message = create_mock_update( + message_text="机器人上一条回复", + user_id=12345678, + username="test_bot", + message_id=10, + ).message + document = create_mock_file("https://api.telegram.org/file/test/report.md") + document.file_name = "report.md" + update = create_mock_update( + message_text=None, + chat_type="group", + document=document, + caption="请继续分析", + reply_to_message=reply_to_message, + ) + + result = await adapter.convert_message(update, _build_context()) + + assert result is not None + reply = _find_reply_component(result) + assert result.self_id == "test_bot" + assert reply.sender_id == result.self_id + assert reply.qq == 12345678 + + +@pytest.mark.asyncio +async def test_telegram_reply_to_user_keeps_sender_id_as_user_id(): + TelegramPlatformAdapter = _load_telegram_adapter() + adapter = TelegramPlatformAdapter( + make_platform_config("telegram"), + {}, + asyncio.Queue(), + ) + reply_to_message = create_mock_update( + message_text="普通用户消息", + user_id=87654321, + username="alice", + message_id=11, + ).message + document = create_mock_file("https://api.telegram.org/file/test/report.md") + document.file_name = "report.md" + update = create_mock_update( + message_text=None, + chat_type="group", + document=document, + caption="请看附件", + reply_to_message=reply_to_message, + ) + + result = await adapter.convert_message(update, _build_context()) + + assert result is not None + reply = _find_reply_component(result) + assert reply.sender_id == "87654321" + assert reply.qq == 87654321 + + @pytest.mark.asyncio async def test_telegram_document_caption_populates_message_text_and_plain(): TelegramPlatformAdapter = _load_telegram_adapter() From ce2a79ae27aada58c4cc48cd09fc118d540a16ae Mon Sep 17 00:00:00 2001 From: woleigedouer <38418090+woleigedouer@users.noreply.github.com> Date: Tue, 19 May 2026 16:22:55 +0800 Subject: [PATCH 2/3] Update astrbot/core/platform/sources/telegram/tg_adapter.py Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- astrbot/core/platform/sources/telegram/tg_adapter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/astrbot/core/platform/sources/telegram/tg_adapter.py b/astrbot/core/platform/sources/telegram/tg_adapter.py index 7ef7a33e8c..d5afd002c0 100644 --- a/astrbot/core/platform/sources/telegram/tg_adapter.py +++ b/astrbot/core/platform/sources/telegram/tg_adapter.py @@ -506,7 +506,7 @@ def _apply_caption() -> None: reply_abm = await self.convert_message(reply_update, context, False) if reply_abm: - reply_sender_id = str(reply_abm.sender.user_id) + reply_sender_id = reply_abm.sender.user_id if reply_sender_id == str(context.bot.id): reply_sender_id = message.self_id From 795da3dc66efdef214378281f2fdbfb81258668e Mon Sep 17 00:00:00 2001 From: woleigedouer <38418090+woleigedouer@users.noreply.github.com> Date: Tue, 19 May 2026 16:23:16 +0800 Subject: [PATCH 3/3] Update tests/test_telegram_adapter.py Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> --- tests/test_telegram_adapter.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/test_telegram_adapter.py b/tests/test_telegram_adapter.py index e5a0d33746..59e27e0f9c 100644 --- a/tests/test_telegram_adapter.py +++ b/tests/test_telegram_adapter.py @@ -148,6 +148,15 @@ async def test_telegram_reply_to_user_keeps_sender_id_as_user_id(): reply = _find_reply_component(result) assert reply.sender_id == "87654321" assert reply.qq == 87654321 + # reply metadata should be preserved + assert reply.id == reply_to_message.message_id + assert reply.chain + # ensure the reply chain still carries the original reply text + if getattr(reply_to_message, "text", None): + assert any( + getattr(component, "text", None) == reply_to_message.text + for component in reply.chain + ) @pytest.mark.asyncio