Skip to content

fix: 保护 @昵称(ID) 格式在命令参数解析时不被空格拆坏#9307

Open
Mer3y1338 wants to merge 2 commits into
AstrBotDevs:masterfrom
Mer3y1338:fix/command-at-mention-space-parsing
Open

fix: 保护 @昵称(ID) 格式在命令参数解析时不被空格拆坏#9307
Mer3y1338 wants to merge 2 commits into
AstrBotDevs:masterfrom
Mer3y1338:fix/command-at-mention-space-parsing

Conversation

@Mer3y1338

@Mer3y1338 Mer3y1338 commented Jul 18, 2026

Copy link
Copy Markdown

问题说明 / Motivation

@mention 的昵称包含空格时(例如 @Heaven Whisper(488267082)),原先的 message_str.split(" ") 会将其拆成多个参数,导致后续参数转换失败(例如 value 收到 Whisper(488267082) 而无法转换为 int)。

Modifications / 改动点

  • 使用预编译正则将 @昵称(ID) 保留为单个命令参数,不受昵称中空格影响。
  • ID 不再限定为纯数字,兼容 Slack/Lark 等平台使用的字符串 ID;ID 仍要求为非空白、非括号内容,避免吞掉后续普通参数。
  • 添加 CommandFilter 回归测试,覆盖:
    • 含空格昵称 + 数字 ID
    • 含空格昵称 + 字符串 ID
    • 普通非 mention 参数
    • 连续两个 mention

影响范围仅为 CommandFilter.filter() 的参数分割逻辑;无新依赖、无破坏性变更。

Test Results / 验证结果

ruff check astrbot/core/star/filter/command.py tests/unit/test_command_filter.py
All checks passed!

pytest tests/unit/test_command_filter.py tests/unit/test_astr_message_event.py -q
82 passed, 1 warning

该 warning 来自既有 audioop 弃用提示,与本次改动无关。

Checklist / 检查清单

  • This is NOT a breaking change. / 这不是一个破坏性变更。
  • My changes have been well-tested, and verification results are provided above. / 我的更改经过测试,并已在上方提供验证结果。
  • No new dependencies are introduced. / 未引入新依赖。
  • My changes do not introduce malicious code. / 未引入恶意代码。

当 @mention 的昵称包含空格时(如 @heaven Whisper(488267082)),
原有的 message_str.split(' ') 会将其拆为多个参数,
导致后续参数类型转换失败(如 value 参数收到 'Whisper(488267082)' 无法转 int)。

使用正则 re.findall(r'@[^@]+?\(\d+\)|[^\s]+', ...) 替代简单 split,
将 @昵称(ID) 作为整体 token 保留,不受昵称中空格影响。

影响范围:仅 CommandFilter.filter() 中参数分割逻辑,
不影响无 @mention 的普通命令解析。
@dosubot dosubot Bot added size:XS This PR changes 0-9 lines, ignoring generated files. area:core The bug / feature is about astrbot's core, backend labels Jul 18, 2026

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • Consider extracting the mention-parsing regex into a named constant with a brief comment about its intent, so future changes to the mention format or additional patterns can be updated in one place.
  • The regex currently assumes the ID is purely numeric (\d+); if non-numeric IDs or different identifier formats are possible now or in the future, you may want to relax this part of the pattern to avoid silently mis-parsing those mentions.
  • If messages can contain multiple @ segments or nested parentheses, double-check that @[^@]+?\(\d+\) behaves as expected and does not accidentally consume too much text; a slightly more constrained character class before the ( might make the matching more robust.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider extracting the mention-parsing regex into a named constant with a brief comment about its intent, so future changes to the mention format or additional patterns can be updated in one place.
- The regex currently assumes the ID is purely numeric (`\d+`); if non-numeric IDs or different identifier formats are possible now or in the future, you may want to relax this part of the pattern to avoid silently mis-parsing those mentions.
- If messages can contain multiple `@` segments or nested parentheses, double-check that `@[^@]+?\(\d+\)` behaves as expected and does not accidentally consume too much text; a slightly more constrained character class before the `(` might make the matching more robust.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the command parameter splitting logic in astrbot/core/star/filter/command.py to prevent splitting @Nickname(ID) formats containing spaces. The reviewer suggested improving the regular expression to support non-numeric user IDs from other platforms (such as Slack or Discord) by replacing \d+ with [\w\-]+.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread astrbot/core/star/filter/command.py Outdated
# 分割为列表,同时保护 @昵称(ID) 格式不被空格拆坏
# 例如 "@Heaven Whisper(488267082) 64" 应拆为 ["@Heaven Whisper(488267082)", "64"]
# 而非 ["@Heaven", "Whisper(488267082)", "64"]
ls = re.findall(r"@[^@]+?\(\d+\)|[^\s]+", message_str)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

这里的正则表达式 r"@[^@]+?\(\d+\)|[^\s]+" 使用了 \d+ 来匹配括号中的用户 ID。虽然这对于 QQ 等使用纯数字 QQ 号作为 ID 的平台非常有效,但 AstrBot 作为一个多平台机器人框架,可能会接入其他平台的适配器(例如微信 wxid、Slack、Discord 或使用 UUID 的平台),这些平台的非数字用户 ID(可能包含字母、下划线、连字符等)将无法被该正则匹配,从而导致在这些平台上包含空格的昵称仍然会被拆分。

为了提高多平台兼容性,建议将 \d+ 替换为 [\w\-]+。这样既能支持包含字母、下划线、连字符等非数字字符的 ID,又因为不允许空格而避免了误匹配普通的带空格括号文本。

Suggested change
ls = re.findall(r"@[^@]+?\(\d+\)|[^\s]+", message_str)
ls = re.findall(r"@[^@]+?\([\w\-]+\)|[^\s]+", message_str)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:core The bug / feature is about astrbot's core, backend size:XS This PR changes 0-9 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant