diff --git a/astrbot/core/platform/sources/telegram/tg_adapter.py b/astrbot/core/platform/sources/telegram/tg_adapter.py index 76863a1949..d5afd002c0 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 = 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..59e27e0f9c 100644 --- a/tests/test_telegram_adapter.py +++ b/tests/test_telegram_adapter.py @@ -79,6 +79,86 @@ 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 + # 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 async def test_telegram_document_caption_populates_message_text_and_plain(): TelegramPlatformAdapter = _load_telegram_adapter()