mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-05-19 08:02:30 +00:00
fix(pairing): persist shortcut commands and avoid Feishu side effects
- AgentLoop._state_command now persists user message and assistant response for shortcut commands (e.g. /pairing) so WebUI history hydration after _turn_end no longer shows an empty chat. /new is excluded because it intentionally clears the session. - Feishu _on_message sends pairing codes for unauthorized DMs before any media side effects (reactions, downloads, transcription). Group chat unauthorized senders are still silently ignored early. - Update test_feishu_reply to assert the new DM pairing behavior.
This commit is contained in:
parent
589792f41e
commit
b68e9fa21e
@ -1712,6 +1712,18 @@ class FeishuChannel(BaseChannel):
|
||||
while len(self._processed_message_ids) > 1000:
|
||||
self._processed_message_ids.popitem(last=False)
|
||||
|
||||
# Early permission check — avoid side effects for unauthorized users.
|
||||
# Group chats are silently ignored; DMs get a pairing code.
|
||||
if not self.is_allowed(sender_id):
|
||||
if chat_type == "p2p":
|
||||
await self._handle_message(
|
||||
sender_id=sender_id,
|
||||
chat_id=sender_id,
|
||||
content="",
|
||||
is_dm=True,
|
||||
)
|
||||
return
|
||||
|
||||
# Add reaction (non-blocking — tracked background task)
|
||||
task = asyncio.create_task(
|
||||
self._add_reaction(message_id, self.config.react_emoji)
|
||||
|
||||
@ -911,7 +911,8 @@ def test_on_background_task_done_removes_from_set() -> None:
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_on_message_ignores_unauthorized_sender_before_side_effects() -> None:
|
||||
async def test_on_message_unauthorized_dm_sends_pairing_code_without_side_effects() -> None:
|
||||
"""Unauthorized DM sender gets a pairing code but no media side effects."""
|
||||
channel = _make_feishu_channel(group_policy="open")
|
||||
channel.config.allow_from = ["ou_allowed"]
|
||||
channel._add_reaction = AsyncMock()
|
||||
@ -927,6 +928,32 @@ async def test_on_message_ignores_unauthorized_sender_before_side_effects() -> N
|
||||
|
||||
await channel._on_message(event)
|
||||
|
||||
channel._add_reaction.assert_not_awaited()
|
||||
channel._download_and_save_media.assert_not_awaited()
|
||||
channel.transcribe_audio.assert_not_awaited()
|
||||
# _handle_message is called to issue the pairing code in DMs
|
||||
channel._handle_message.assert_awaited_once()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_on_message_unauthorized_group_ignored_before_side_effects() -> None:
|
||||
"""Unauthorized group chat sender is silently ignored before any side effects."""
|
||||
channel = _make_feishu_channel(group_policy="open")
|
||||
channel.config.allow_from = ["ou_allowed"]
|
||||
channel._add_reaction = AsyncMock()
|
||||
channel._download_and_save_media = AsyncMock(return_value=("/tmp/audio.ogg", "[audio]"))
|
||||
channel.transcribe_audio = AsyncMock(return_value="transcript")
|
||||
channel._handle_message = AsyncMock()
|
||||
|
||||
event = _make_feishu_event(
|
||||
chat_type="group",
|
||||
msg_type="audio",
|
||||
content='{"file_key": "file_1"}',
|
||||
sender_open_id="ou_blocked",
|
||||
)
|
||||
|
||||
await channel._on_message(event)
|
||||
|
||||
channel._add_reaction.assert_not_awaited()
|
||||
channel._download_and_save_media.assert_not_awaited()
|
||||
channel.transcribe_audio.assert_not_awaited()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user