fix(onebot): 合并转发节点传入 bot self_id 作为 uin,修复 retcode=1200 - #93
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughbootstrap 注册 bot client 与 bot self_id provider;OneBot sender 解析 bot_self_id,并在合并转发和兜底节点中写入 Changesbot self_id 解析与写入
Sequence Diagram(s)初始化注册 sequenceDiagram
participant Bootstrap as "bootstrap.py:_register_bot_client_provider"
participant ClientProvider as "set_bot_client_provider"
participant SelfIdProvider as "set_bot_self_id_provider"
Bootstrap->>ClientProvider: register _resolve_bot_client
Bootstrap->>SelfIdProvider: register _resolve_bot_self_id
发送时解析 self_id sequenceDiagram
participant Sender as "OneBotMessageSender.send_to_user"
participant Context as "MessageContext.message_obj.self_id"
participant Tool as "get_bot_self_id(platform_name)"
participant Node as "Node(..., uin=bot_self_id)"
Sender->>Context: read message_obj.self_id
alt message_obj.self_id exists
Context-->>Sender: self_id
else message_obj.self_id missing
Sender->>Tool: resolve bot_self_id by platform_name
Tool-->>Sender: bot_self_id or "10000"
end
Sender->>Node: build merged-forward and fallback nodes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
审阅者指南添加了正确的 bot self_id(uin)的解析和在 OneBot 转发节点中的传递,以修复 retcode=1200,并从 bootstrap 中接好全局 self_id provider,使得主动发送可以获取 QQ 号。 文件级变更
技巧与命令与 Sourcery 交互
自定义你的体验访问你的 控制面板 来:
获取帮助Original review guide in EnglishReviewer's GuideAdds proper bot self_id (uin) resolution and propagation into OneBot forward nodes to fix retcode=1200, and wires a global self_id provider from bootstrap so proactive sends can obtain the QQ number. File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - 我发现了 1 个问题,并给出了一些整体性的反馈:
- 在
_resolve_bot_self_id中,bot_client参数从未被使用;请考虑要么将其从函数签名中移除,要么复用已经解析好的 client,而不是通过get_bot_self_id重新推导 self_id,以避免混淆和重复逻辑。 - 硬编码的兜底 self_id 值 "10000" 在多处出现,且蕴含业务逻辑;建议将其提取为一个语义清晰的模块级常量,以便更容易理解其意图与用途,并在后续需要调整时集中修改。
面向 AI Agents 的提示词
Please address the comments from this code review:
## Overall Comments
- In `_resolve_bot_self_id`, the `bot_client` parameter is never used; either remove it from the signature or reuse the already-resolved client instead of re-deriving self_id via `get_bot_self_id` to avoid confusion and duplication.
- The hardcoded fallback self_id value "10000" appears in multiple places and encodes business logic; consider extracting it into a clearly named module-level constant to make the intent and usage easier to track and adjust.
## Individual Comments
### Comment 1
<location path="src/infrastructure/messaging/senders/onebot_sender.py" line_range="86-87" />
<code_context>
return get_bot_client(platform_name or "")
+ @classmethod
+ def _resolve_bot_self_id(
+ cls, context: MessageContext | None, bot_client: Any | None
+ ) -> str:
+ """解析 bot 的 self_id(QQ 号),用于合并转发节点的 user_id。
</code_context>
<issue_to_address>
**suggestion:** Remove or leverage the unused `bot_client` parameter in `_resolve_bot_self_id`.
Since `bot_client` is always passed from `send_to_user` but never used here, it currently adds complexity without value. Consider either removing it from both the method and call site, or deriving `self_id` directly from the provided client (mirroring the bootstrap provider) to avoid the extra `get_bot_self_id` lookup.
Suggested implementation:
```python
from typing import Any
from .types import MessageContext, SendRequest, SendResult, get_bot_self_id
```
```python
@classmethod
def _resolve_bot_self_id(
cls, context: MessageContext | None, bot_client: Any | None
) -> str:
"""解析 bot 的 self_id(QQ 号),用于合并转发节点的 user_id。
解析顺序:
1. 命令响应场景:从事件消息对象的 ``self_id`` 读取(最可靠)。
2. 若有显式传入的 ``bot_client``,优先从 client 上解析 ``self_id``,
避免额外的 get_bot_self_id 查找。
3. 主动推送场景:通过全局 provider 按 platform_name 解析(由
bootstrap 注册,读取 CQHttp 的 ``_wsr_api_clients``)。
4. 兜底:返回非零占位 ``"10000"``,避免新版 NapCat / Lagrange
因 user_id 为空或 0 报 retcode=1200。
"""
# 1. 从事件对象中直接读取(命令响应场景)
if context is not None:
event = getattr(context, "event", None)
if event is not None:
self_id = getattr(event, "self_id", None)
if self_id:
return str(self_id)
# 2. 从显式传入的 bot_client 上解析(如果可用)
if bot_client is not None:
self_id = getattr(bot_client, "self_id", None)
if self_id:
return str(self_id)
# 3. 通过全局 provider + platform_name 解析
platform_name = getattr(context, "platform_name", "") if context is not None else ""
self_id = get_bot_self_id(platform_name or "")
if self_id:
return str(self_id)
# 4. 兜底占位,避免 retcode=1200
return "10000"
```
</issue_to_address>帮我变得更有用!请对每条评论点击 👍 或 👎,我会根据你的反馈改进后续的代码审查。
Original comment in English
Hey - I've found 1 issue, and left some high level feedback:
- In
_resolve_bot_self_id, thebot_clientparameter is never used; either remove it from the signature or reuse the already-resolved client instead of re-deriving self_id viaget_bot_self_idto avoid confusion and duplication. - The hardcoded fallback self_id value "10000" appears in multiple places and encodes business logic; consider extracting it into a clearly named module-level constant to make the intent and usage easier to track and adjust.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `_resolve_bot_self_id`, the `bot_client` parameter is never used; either remove it from the signature or reuse the already-resolved client instead of re-deriving self_id via `get_bot_self_id` to avoid confusion and duplication.
- The hardcoded fallback self_id value "10000" appears in multiple places and encodes business logic; consider extracting it into a clearly named module-level constant to make the intent and usage easier to track and adjust.
## Individual Comments
### Comment 1
<location path="src/infrastructure/messaging/senders/onebot_sender.py" line_range="86-87" />
<code_context>
return get_bot_client(platform_name or "")
+ @classmethod
+ def _resolve_bot_self_id(
+ cls, context: MessageContext | None, bot_client: Any | None
+ ) -> str:
+ """解析 bot 的 self_id(QQ 号),用于合并转发节点的 user_id。
</code_context>
<issue_to_address>
**suggestion:** Remove or leverage the unused `bot_client` parameter in `_resolve_bot_self_id`.
Since `bot_client` is always passed from `send_to_user` but never used here, it currently adds complexity without value. Consider either removing it from both the method and call site, or deriving `self_id` directly from the provided client (mirroring the bootstrap provider) to avoid the extra `get_bot_self_id` lookup.
Suggested implementation:
```python
from typing import Any
from .types import MessageContext, SendRequest, SendResult, get_bot_self_id
```
```python
@classmethod
def _resolve_bot_self_id(
cls, context: MessageContext | None, bot_client: Any | None
) -> str:
"""解析 bot 的 self_id(QQ 号),用于合并转发节点的 user_id。
解析顺序:
1. 命令响应场景:从事件消息对象的 ``self_id`` 读取(最可靠)。
2. 若有显式传入的 ``bot_client``,优先从 client 上解析 ``self_id``,
避免额外的 get_bot_self_id 查找。
3. 主动推送场景:通过全局 provider 按 platform_name 解析(由
bootstrap 注册,读取 CQHttp 的 ``_wsr_api_clients``)。
4. 兜底:返回非零占位 ``"10000"``,避免新版 NapCat / Lagrange
因 user_id 为空或 0 报 retcode=1200。
"""
# 1. 从事件对象中直接读取(命令响应场景)
if context is not None:
event = getattr(context, "event", None)
if event is not None:
self_id = getattr(event, "self_id", None)
if self_id:
return str(self_id)
# 2. 从显式传入的 bot_client 上解析(如果可用)
if bot_client is not None:
self_id = getattr(bot_client, "self_id", None)
if self_id:
return str(self_id)
# 3. 通过全局 provider + platform_name 解析
platform_name = getattr(context, "platform_name", "") if context is not None else ""
self_id = get_bot_self_id(platform_name or "")
if self_id:
return str(self_id)
# 4. 兜底占位,避免 retcode=1200
return "10000"
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| def _resolve_bot_self_id( | ||
| cls, context: MessageContext | None, bot_client: Any | None |
There was a problem hiding this comment.
suggestion: 移除或利用 _resolve_bot_self_id 中未使用的 bot_client 参数。
由于 bot_client 始终由 send_to_user 传入,但在这里从未使用,目前只是在增加无意义的复杂度。建议要么在该方法及其调用处同时移除该参数,要么直接从传入的 client 上推导 self_id(与 bootstrap provider 的行为保持一致),以避免额外的 get_bot_self_id 查找。
建议实现如下:
from typing import Any
from .types import MessageContext, SendRequest, SendResult, get_bot_self_id @classmethod
def _resolve_bot_self_id(
cls, context: MessageContext | None, bot_client: Any | None
) -> str:
"""解析 bot 的 self_id(QQ 号),用于合并转发节点的 user_id。
解析顺序:
1. 命令响应场景:从事件消息对象的 ``self_id`` 读取(最可靠)。
2. 若有显式传入的 ``bot_client``,优先从 client 上解析 ``self_id``,
避免额外的 get_bot_self_id 查找。
3. 主动推送场景:通过全局 provider 按 platform_name 解析(由
bootstrap 注册,读取 CQHttp 的 ``_wsr_api_clients``)。
4. 兜底:返回非零占位 ``"10000"``,避免新版 NapCat / Lagrange
因 user_id 为空或 0 报 retcode=1200。
"""
# 1. 从事件对象中直接读取(命令响应场景)
if context is not None:
event = getattr(context, "event", None)
if event is not None:
self_id = getattr(event, "self_id", None)
if self_id:
return str(self_id)
# 2. 从显式传入的 bot_client 上解析(如果可用)
if bot_client is not None:
self_id = getattr(bot_client, "self_id", None)
if self_id:
return str(self_id)
# 3. 通过全局 provider + platform_name 解析
platform_name = getattr(context, "platform_name", "") if context is not None else ""
self_id = get_bot_self_id(platform_name or "")
if self_id:
return str(self_id)
# 4. 兜底占位,避免 retcode=1200
return "10000"Original comment in English
suggestion: Remove or leverage the unused bot_client parameter in _resolve_bot_self_id.
Since bot_client is always passed from send_to_user but never used here, it currently adds complexity without value. Consider either removing it from both the method and call site, or deriving self_id directly from the provided client (mirroring the bootstrap provider) to avoid the extra get_bot_self_id lookup.
Suggested implementation:
from typing import Any
from .types import MessageContext, SendRequest, SendResult, get_bot_self_id @classmethod
def _resolve_bot_self_id(
cls, context: MessageContext | None, bot_client: Any | None
) -> str:
"""解析 bot 的 self_id(QQ 号),用于合并转发节点的 user_id。
解析顺序:
1. 命令响应场景:从事件消息对象的 ``self_id`` 读取(最可靠)。
2. 若有显式传入的 ``bot_client``,优先从 client 上解析 ``self_id``,
避免额外的 get_bot_self_id 查找。
3. 主动推送场景:通过全局 provider 按 platform_name 解析(由
bootstrap 注册,读取 CQHttp 的 ``_wsr_api_clients``)。
4. 兜底:返回非零占位 ``"10000"``,避免新版 NapCat / Lagrange
因 user_id 为空或 0 报 retcode=1200。
"""
# 1. 从事件对象中直接读取(命令响应场景)
if context is not None:
event = getattr(context, "event", None)
if event is not None:
self_id = getattr(event, "self_id", None)
if self_id:
return str(self_id)
# 2. 从显式传入的 bot_client 上解析(如果可用)
if bot_client is not None:
self_id = getattr(bot_client, "self_id", None)
if self_id:
return str(self_id)
# 3. 通过全局 provider + platform_name 解析
platform_name = getattr(context, "platform_name", "") if context is not None else ""
self_id = get_bot_self_id(platform_name or "")
if self_id:
return str(self_id)
# 4. 兜底占位,避免 retcode=1200
return "10000"There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
src/infrastructure/messaging/senders/onebot_sender.py (1)
87-110: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win让 self_id 解析真正使用传入的
bot_client。Line 87 接收
bot_client,但当前只查event.message_obj.self_id和全局 provider;若命令响应场景有event.bot、但message_obj.self_id缺失,会落到占位值。请补充从bot_client.self_id/_wsr_api_clients解析的分支,或移除该参数并验证所有事件都稳定携带message_obj.self_id。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/infrastructure/messaging/senders/onebot_sender.py` around lines 87 - 110, The self_id resolution in the onebot sender is ignoring the passed bot_client, so command-response flows can fall back to the placeholder when message_obj.self_id is missing. Update the self_id resolver in the onebot_sender logic to first use bot_client.self_id (or derive from the CQHttp _wsr_api_clients when available) before falling back to event.message_obj.self_id and get_bot_self_id(platform_name), or remove the unused bot_client parameter if all callers guarantee message_obj.self_id is always present.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@bootstrap.py`:
- Around line 242-247: The new docstrings in bootstrap.py trigger Ruff RUF002
because they contain full-width Chinese punctuation, so the lint step may fail.
Update the affected docstring text around the bot client/self_id provider
documentation to use ASCII punctuation only, or adjust the Ruff configuration to
allow Chinese punctuation if that is the intended project policy. Use the
existing docstring block in the bootstrap logic as the target location.
- Around line 281-285: The self_id lookup in the client helper that reads
_wsr_api_clients should avoid iterating the live dict directly because it can
change during WebSocket activity and raise a RuntimeError. Update the logic in
the self_id resolution path to take a snapshot of api_clients keys first, then
iterate that snapshot and return the first non-empty, non-"0" id. Keep the fix
localized to the getattr(client, "_wsr_api_clients", None) / self_id selection
block so the lookup remains stable under concurrent connection changes.
In `@src/infrastructure/messaging/senders/onebot_sender.py`:
- Around line 89-96: The new docstring in OneBot sender is triggering Ruff
RUF002 because it contains full-width punctuation. Update the documentation text
in the affected helper around the self_id parsing logic in onebot_sender.py to
use ASCII punctuation consistently, or adjust the Ruff configuration to allow
Chinese punctuation if that is the intended project standard. Make sure the fix
targets the docstring associated with the self_id resolution flow used for
merged-forward user_id handling.
---
Nitpick comments:
In `@src/infrastructure/messaging/senders/onebot_sender.py`:
- Around line 87-110: The self_id resolution in the onebot sender is ignoring
the passed bot_client, so command-response flows can fall back to the
placeholder when message_obj.self_id is missing. Update the self_id resolver in
the onebot_sender logic to first use bot_client.self_id (or derive from the
CQHttp _wsr_api_clients when available) before falling back to
event.message_obj.self_id and get_bot_self_id(platform_name), or remove the
unused bot_client parameter if all callers guarantee message_obj.self_id is
always present.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b89cd41c-38fd-46d0-9672-3e069f78eb37
📒 Files selected for processing (2)
bootstrap.pysrc/infrastructure/messaging/senders/onebot_sender.py
| """注册 bot client / bot self_id provider,供主动推送场景使用。 | ||
|
|
||
| 主动推送没有消息事件,sender 无法从 event 取 bot 客户端。 | ||
| 这里通过 AstrBot platform_manager 按平台名解析出底层 bot 客户端 | ||
| (如 aiocqhttp 的 CQHttp 实例),用于调用 NapCat stream action。 | ||
| (如 aiocqhttp 的 CQHttp 实例),用于调用 NapCat stream action, | ||
| 并从中解析出 bot 的 self_id(QQ 号)供合并转发节点使用。 |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
处理 Ruff RUF002 告警,避免 lint 阶段失败。
这些新增 docstring 含全角标点,Ruff 已在这些行报告 RUF002。若该规则在 CI 中阻断,请改为 ASCII 标点,或在 Ruff 配置中明确允许中文标点。
Also applies to: 271-276
🧰 Tools
🪛 Ruff (0.15.18)
[warning] 242-242: Docstring contains ambiguous , (FULLWIDTH COMMA). Did you mean , (COMMA)?
(RUF002)
[warning] 244-244: Docstring contains ambiguous , (FULLWIDTH COMMA). Did you mean , (COMMA)?
(RUF002)
[warning] 246-246: Docstring contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF002)
[warning] 246-246: Docstring contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF002)
[warning] 246-246: Docstring contains ambiguous , (FULLWIDTH COMMA). Did you mean , (COMMA)?
(RUF002)
[warning] 246-246: Docstring contains ambiguous , (FULLWIDTH COMMA). Did you mean , (COMMA)?
(RUF002)
[warning] 247-247: Docstring contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF002)
[warning] 247-247: Docstring contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF002)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@bootstrap.py` around lines 242 - 247, The new docstrings in bootstrap.py
trigger Ruff RUF002 because they contain full-width Chinese punctuation, so the
lint step may fail. Update the affected docstring text around the bot
client/self_id provider documentation to use ASCII punctuation only, or adjust
the Ruff configuration to allow Chinese punctuation if that is the intended
project policy. Use the existing docstring block in the bootstrap logic as the
target location.
Source: Linters/SAST tools
| api_clients = getattr(client, "_wsr_api_clients", None) | ||
| if isinstance(api_clients, dict): | ||
| for self_id in api_clients.keys(): | ||
| if self_id and str(self_id) != "0": | ||
| return str(self_id) |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
遍历前先快照 _wsr_api_clients。
该 dict 由反向 WebSocket 连接维护,发送期间连接增删时直接遍历 keys 可能抛 RuntimeError: dictionary changed size during iteration,导致 self_id 解析失败。
建议修复
- for self_id in api_clients.keys():
+ for self_id in list(api_clients):
if self_id and str(self_id) != "0":
return str(self_id)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| api_clients = getattr(client, "_wsr_api_clients", None) | |
| if isinstance(api_clients, dict): | |
| for self_id in api_clients.keys(): | |
| if self_id and str(self_id) != "0": | |
| return str(self_id) | |
| api_clients = getattr(client, "_wsr_api_clients", None) | |
| if isinstance(api_clients, dict): | |
| for self_id in list(api_clients): | |
| if self_id and str(self_id) != "0": | |
| return str(self_id) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@bootstrap.py` around lines 281 - 285, The self_id lookup in the client helper
that reads _wsr_api_clients should avoid iterating the live dict directly
because it can change during WebSocket activity and raise a RuntimeError. Update
the logic in the self_id resolution path to take a snapshot of api_clients keys
first, then iterate that snapshot and return the first non-empty, non-"0" id.
Keep the fix localized to the getattr(client, "_wsr_api_clients", None) /
self_id selection block so the lookup remains stable under concurrent connection
changes.
| """解析 bot 的 self_id(QQ 号),用于合并转发节点的 user_id。 | ||
|
|
||
| 解析顺序: | ||
| 1. 命令响应场景:从事件消息对象的 ``self_id`` 读取(最可靠)。 | ||
| 2. 主动推送场景:通过全局 provider 按 platform_name 解析(由 | ||
| bootstrap 注册,读取 CQHttp 的 ``_wsr_api_clients``)。 | ||
| 3. 兜底:返回非零占位 ``"10000"``,避免新版 NapCat / Lagrange | ||
| 因 user_id 为空或 0 报 retcode=1200。 |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
处理 Ruff RUF002 告警,避免 lint 阶段失败。
这些新增 docstring 含全角标点,Ruff 已在这些行报告 RUF002。若该规则在 CI 中阻断,请改为 ASCII 标点,或在 Ruff 配置中明确允许中文标点。
🧰 Tools
🪛 Ruff (0.15.18)
[warning] 89-89: Docstring contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF002)
[warning] 89-89: Docstring contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF002)
[warning] 89-89: Docstring contains ambiguous , (FULLWIDTH COMMA). Did you mean , (COMMA)?
(RUF002)
[warning] 91-91: Docstring contains ambiguous : (FULLWIDTH COLON). Did you mean : (COLON)?
(RUF002)
[warning] 92-92: Docstring contains ambiguous : (FULLWIDTH COLON). Did you mean : (COLON)?
(RUF002)
[warning] 92-92: Docstring contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF002)
[warning] 92-92: Docstring contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF002)
[warning] 93-93: Docstring contains ambiguous : (FULLWIDTH COLON). Did you mean : (COLON)?
(RUF002)
[warning] 93-93: Docstring contains ambiguous ( (FULLWIDTH LEFT PARENTHESIS). Did you mean ( (LEFT PARENTHESIS)?
(RUF002)
[warning] 94-94: Docstring contains ambiguous , (FULLWIDTH COMMA). Did you mean , (COMMA)?
(RUF002)
[warning] 94-94: Docstring contains ambiguous ) (FULLWIDTH RIGHT PARENTHESIS). Did you mean ) (RIGHT PARENTHESIS)?
(RUF002)
[warning] 95-95: Docstring contains ambiguous : (FULLWIDTH COLON). Did you mean : (COLON)?
(RUF002)
[warning] 95-95: Docstring contains ambiguous , (FULLWIDTH COMMA). Did you mean , (COMMA)?
(RUF002)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/infrastructure/messaging/senders/onebot_sender.py` around lines 89 - 96,
The new docstring in OneBot sender is triggering Ruff RUF002 because it contains
full-width punctuation. Update the documentation text in the affected helper
around the self_id parsing logic in onebot_sender.py to use ASCII punctuation
consistently, or adjust the Ruff configuration to allow Chinese punctuation if
that is the intended project standard. Make sure the fix targets the docstring
associated with the self_id resolution flow used for merged-forward user_id
handling.
Source: Linters/SAST tools
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 176520cc79
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if node_content: | ||
| nodes.append(Node(content=node_content, name=nickname)) | ||
| nodes.append( | ||
| Node(content=node_content, name=nickname, uin=bot_self_id) |
There was a problem hiding this comment.
在运行现有 tests/unit/infrastructure/test_onebot_sender.py 时,这个新增关键字会调用被 monkeypatch 的 _Node(content, name) 测试替身;该替身没有 uin 参数,因此覆盖合并转发路径的单元测试会在发送前以 TypeError: __init__() got an unexpected keyword argument 'uin' 失败。请同步更新测试替身(最好同时断言 uin),否则 OneBot sender 的回归测试无法执行。
Useful? React with 👍 / 👎.
| 3. 兜底:返回非零占位 ``"10000"``,避免新版 NapCat / Lagrange | ||
| 因 user_id 为空或 0 报 retcode=1200。 |
|
感谢这个修复,方向是对的。我们当前 我建议这个 PR 再收敛一下实现,主要是避免用固定 QQ 号兜底,以及补上回归测试。下面是具体定位和建议改法。 1. 不要用
|
|
napcat、snowluma现均已支持宽松的uin="0"作为缺省值,会自动fallback到Bot自身账号 |
OneBotMessageSender 构建合并转发 Node 时未传 uin,导致 Node.uin 默认
为 "0",序列化后 user_id="0"。新版 NapCat / Lagrange 会拒绝 user_id
为 0 或空的转发节点,返回 retcode=1200 ("forward node user_id/uin is
required"),使 RSS 推送到 QQ 群失败。
修复:
- onebot_sender: 新增 _resolve_bot_self_id,优先从 event.message_obj.self_id
读取(命令响应场景),其次通过 get_bot_self_id provider 解析(主动推送
场景),最后兜底非零占位 "10000";构建与回退 Node 时均传入 uin。
- bootstrap: 注册 set_bot_self_id_provider,从 CQHttp 的 _wsr_api_clients
解析已连接 bot 的 self_id(types.py 已预留 hook 但未注册)。
同时将 bot_client 解析上移到节点构建之前,使 uin 在构建节点时即可用。
176520c to
62ce5ee
Compare
问题
RSS 推送到 QQ 群(aiocqhttp / OneBot)失败,推送历史报错:
根因
OneBotMessageSender.send_to_user构建合并转发Node时只传了content和name,未传uin:AstrBot 的
Node组件uin默认为"0",Node.to_dict()序列化后变成user_id: "0"。新版 NapCat / Lagrange 对合并转发节点做了严格校验,拒绝user_id为 0 或空的转发节点,返回retcode=1200("forward node user_id/uin is required")。旧版 go-cqhttp / 早期 NapCat 较为宽容,所以此前未暴露。此外
aiocqhttp在收到retcode=1200时抛出ActionFailed异常而非返回失败结果,异常直接被外层except捕获,try块内的纯文本回退逻辑被跳过;即便回退执行,回退的Node同样不带uin,仍会失败。修复
1.
src/infrastructure/messaging/senders/onebot_sender.py_resolve_bot_self_id,按以下顺序解析 bot 的self_id(QQ 号):event.message_obj.self_id读取(最可靠);get_bot_self_id(platform_name)解析;"10000",避免 user_id 为空或 0 再次触发retcode=1200。Node(主循环、空消息兜底、纯文本回退)均传入uin=bot_self_id。bot_client解析上移到节点构建之前,使uin在构建节点时即可用。2.
bootstrap.pytypes.py已预留set_bot_self_id_provider/get_bot_self_idhook,但bootstrap.py此前只注册了set_bot_client_provider,漏注册了set_bot_self_id_provider,导致get_bot_self_id()永远返回默认"10000"。_register_bot_client_provider中新增_resolve_bot_self_id闭包:复用已有的_resolve_bot_client解析出CQHttp实例后,从其_wsr_api_clients(以self_id为键保存已连接的反向 WS API 客户端,AstrBot core 的terminate也读取该属性)取第一个非零键作为真实 bot QQ 号;并注册到set_bot_self_id_provider。验证
python -m py_compile两个文件均通过。uin解析在事件场景下读message_obj.self_id(AstrBot aiocqhttp 适配器在_convert_handle_message_event中设置abm.self_id = str(event.self_id)),主动推送场景下读_wsr_api_clients,两者均与现有代码路径一致。兼容性
uin字段。user_id)。_wsr_api_clients属性访问使用getattr+isinstance防御,不存在时返回空串由调用方兜底,不会抛错。Summary by Sourcery
确保 OneBot 合并转发消息包含有效的机器人
self_id/uin,以满足更严格的 NapCat/Lagrange 校验要求,并防止在 QQ 群消息投递时出现retcode=1200错误。Bug Fixes:
uin填充为机器人self_id,以避免由于user_id缺失或为 0 而导致的ActionFailed retcode=1200。self_id提供器,以便在主动推送场景中能够解析真实的 QQ 号,而不是总是退回到默认占位值。Enhancements:
self_id,并带有非零回退值,在不同运行时上下文中提升 OneBot 消息发送的健壮性。Original summary in English
Summary by Sourcery
Ensure OneBot merged forward messages include a valid bot self_id/uin to satisfy stricter NapCat/Lagrange validation and prevent retcode=1200 failures in QQ group deliveries.
Bug Fixes:
Enhancements:
Summary by CodeRabbit