From 77d5d92c3bee6076360da471ef414c161aafbd96 Mon Sep 17 00:00:00 2001 From: Sebastian <39752847+sebastian0619@users.noreply.github.com> Date: Tue, 1 Sep 2026 14:48:51 +0800 Subject: [PATCH] fix(vocechat): accept numeric user IDs --- app/modules/vocechat/vocechat.py | 17 +++++++++--- tests/test_vocechat.py | 44 ++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 tests/test_vocechat.py diff --git a/app/modules/vocechat/vocechat.py b/app/modules/vocechat/vocechat.py index 3c9a2f30e..e27b51833 100644 --- a/app/modules/vocechat/vocechat.py +++ b/app/modules/vocechat/vocechat.py @@ -236,15 +236,26 @@ class VoceChat: def __send_request(self, userid: str, caption: str) -> bool: """ 向VoceChat发送报文 - userid格式:UID#xxx / GID#xxx + userid格式:数字用户ID / UID#xxx / GID#xxx """ if not self._client: return False if userid.startswith("GID#"): action = "send_to_group" - else: + idstr = userid[4:] + elif userid.startswith("UID#"): action = "send_to_user" - idstr = userid[4:] + idstr = userid[4:] + elif "#" not in userid: + action = "send_to_user" + idstr = userid + else: + logger.error(f"VoceChat消息接收对象格式错误:{userid}") + return False + + if not idstr.isdigit(): + logger.error(f"VoceChat消息接收对象ID无效:{userid}") + return False with lock: result = self._client.post_res(f"{self._host}api/bot/{action}/{idstr}", data=caption.encode("utf-8")) diff --git a/tests/test_vocechat.py b/tests/test_vocechat.py new file mode 100644 index 000000000..76b472fb3 --- /dev/null +++ b/tests/test_vocechat.py @@ -0,0 +1,44 @@ +from types import SimpleNamespace +from unittest.mock import Mock + +import pytest + +from app.modules.vocechat.vocechat import VoceChat + + +@pytest.mark.parametrize( + ("userid", "endpoint"), + [ + ("123", "send_to_user/123"), + ("UID#123", "send_to_user/123"), + ("GID#456", "send_to_group/456"), + ], +) +def test_send_msg_normalizes_vocechat_target(userid: str, endpoint: str): + client = Mock() + client.post_res.return_value = SimpleNamespace(status_code=200) + vocechat = VoceChat( + VOCECHAT_HOST="https://voce.example.com", + VOCECHAT_API_KEY="test-key", + VOCECHAT_CHANNEL_ID="456", + ) + vocechat._client = client + + assert vocechat.send_msg(title="测试消息", userid=userid) is True + assert client.post_res.call_args.args[0] == ( + f"https://voce.example.com/api/bot/{endpoint}" + ) + + +@pytest.mark.parametrize("userid", ["UID#", "GID#", "SID#123", "abc"]) +def test_send_msg_rejects_invalid_vocechat_target(userid: str): + client = Mock() + vocechat = VoceChat( + VOCECHAT_HOST="https://voce.example.com", + VOCECHAT_API_KEY="test-key", + VOCECHAT_CHANNEL_ID="456", + ) + vocechat._client = client + + assert vocechat.send_msg(title="测试消息", userid=userid) is False + client.post_res.assert_not_called()