Skip to content

fix: 修复 aiocqhttp 管理员角色字段未透传的问题#5980

Open
Blade096 wants to merge 3 commits intoAstrBotDevs:masterfrom
Blade096:codex/fix-aiocqhttp-admin-role
Open

fix: 修复 aiocqhttp 管理员角色字段未透传的问题#5980
Blade096 wants to merge 3 commits intoAstrBotDevs:masterfrom
Blade096:codex/fix-aiocqhttp-admin-role

Conversation

@Blade096
Copy link

@Blade096 Blade096 commented Mar 10, 2026

修复 aiocqhttp / NapCat 群消息场景下发送者角色未正确透传到 AstrBot 事件对象的问题,导致群管理员和群主在插件侧被误判为普通成员,进而无法通过依赖 event.is_admin() 的管理命令校验。

Modifications / 改动点

  • astrbot/core/platform/astrbot_message.pyMessageMember 中新增 role 字段,用于承载平台侧发送者角色。

  • astrbot/core/platform/sources/aiocqhttp/aiocqhttp_platform_adapter.py 中读取 event.sender["role"],并在合法值为 adminownermember 时透传到 MessageMember.role

  • astrbot/core/platform/astr_message_event.py 中优先从 message_obj.sender.role 初始化事件角色,并将 owneradmin 都视为管理员。

  • astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py 的群成员列表构建逻辑中补充 role 字段,保证成员缓存同步时也能拿到角色信息。

  • tests/unit/test_astr_message_event.pytests/unit/test_astrbot_message.py 中补充对应单元测试,覆盖 owner 管理员判定和 MessageMember.role 默认值行为。

  • This is NOT a breaking change. / 这不是一个破坏性变更。

Screenshots or Test Results / 运行截图或测试结果

执行结果:

> uv run pytest -q tests/unit/test_astr_message_event.py tests/unit/test_astrbot_message.py
102 passed in 7.16s
> uv run ruff check .
All checks passed!

Checklist / 检查清单

  • 😊 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。
  • 👀 我的更改经过了良好的测试,并已在上方提供了“验证步骤”和“运行截图”。
  • 🤓 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到了 requirements.txt 和 pyproject.toml 文件相应位置。
  • 😮 我的更改没有引入恶意代码。

Summary by Sourcery

将来自 aiocqhttp/NapCat 事件的发送者角色信息传递到 AstrBot 的消息和事件对象中,使群管理员和群主能够被正确识别为管理员。

Bug Fixes:

  • 通过将平台的发送者角色正确映射到 AstrBot 事件中,修复了将群管理员和群主误判为普通成员的问题。

Enhancements:

  • 扩展 MessageMember,新增可选的 role 字段,并从 aiocqhttp 群消息和成员缓存中为其赋值。
  • 在事件角色检查中,将群主和管理员角色都视为管理员。

Tests:

  • 添加单元测试,覆盖 is_admin 中对群主角色的处理,以及 MessageMember 的默认角色行为。
Original summary in English

Summary by Sourcery

Propagate sender role information from aiocqhttp/NapCat events into AstrBot message and event objects so group admins and owners are correctly recognized as administrators.

Bug Fixes:

  • Fix misclassification of group admins and owners as regular members by correctly mapping platform sender roles into AstrBot events.

Enhancements:

  • Extend MessageMember to carry an optional role field and populate it from aiocqhttp group messages and member cache.
  • Treat both owner and admin roles as administrators in event role checks.

Tests:

  • Add unit tests covering owner role handling in is_admin and the default role behavior of MessageMember.

@dosubot dosubot bot added size:S This PR changes 10-29 lines, ignoring generated files. area:platform The bug / feature is about IM platform adapter, such as QQ, Lark, Telegram, WebChat and so on. labels Mar 10, 2026
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - 我这边发现了 1 个问题,并给出了一些整体性的反馈:

  • 允许的角色取值("admin"、"owner"、"member")在多处被硬编码;建议将它们集中到共享的常量或枚举中,以避免发生不一致,并让后续修改更安全。
  • aiocqhttp_message_event.get_group 中,role 被直接透传,而没有经过 _convert_handle_message_event 中所使用的校验;建议在这里也应用相同的归一化/校验逻辑,这样缓存成员就能与实时事件保持一致的行为。
  • AstrMessageEvent.role 的文档字符串被改成了只有英文,但附近的文档字符串仍是中文;建议保持与周围注释在语言/风格上的一致性,以提升可读性。
给 AI 代理的提示词
Please address the comments from this code review:

## Overall Comments
- The allowed role values ("admin", "owner", "member") are hardcoded in multiple places; consider centralizing them into a shared constant or enum to avoid divergence and make future changes safer.
- In `aiocqhttp_message_event.get_group`, `role` is passed through without the validation used in `_convert_handle_message_event`; consider applying the same normalization/validation so cached members behave consistently with live events.
- The `AstrMessageEvent.role` docstring was changed to English only while nearby docstrings remain Chinese; consider keeping the language/style consistent with surrounding comments for readability.

## Individual Comments

### Comment 1
<location path="astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py" line_range="244-247" />
<code_context>
                 MessageMember(
                     user_id=member["user_id"],
                     nickname=member.get("nickname") or member.get("card"),
+                    role=member.get("role"),
                 )
                 for member in members
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Validate or normalize `member["role"]` to match the expected role set.

This path now passes `member.get("role")` through without the constraints used for `sender_role` ("admin"/"owner"/"member"/None). If CQHTTP ever returns an unexpected role string, it will bypass the checks in `AstrMessageEvent` and introduce inconsistent role values. Please reuse the same validation/normalization logic here so all sources produce a consistent, validated role set.

Suggested implementation:

```python
                MessageMember(
                    user_id=member["user_id"],
                    nickname=member.get("nickname") or member.get("card"),
                    role=normalize_role(member.get("role")),
                )
                for member in members
            ],

```

1. Ensure there is a `normalize_role` (or similarly named) function in this module that implements the same validation/normalization logic currently used for `sender_role` (e.g. mapping only `"admin"`, `"owner"`, `"member"` to themselves and returning `None` or a default for any other value).
2. If the `sender_role` normalization is currently inline (e.g. `if role not in (...)`), extract that logic into `normalize_role(role: Optional[str]) -> Optional[str]` and replace the inline normalization used for `sender_role` with a call to `normalize_role` as well, to keep the behavior consistent between senders and members.
</issue_to_address>

Sourcery 对开源项目永久免费 —— 如果你觉得我们的代码审查有帮助,请考虑帮忙分享 ✨
帮我变得更有用!请对每条评论点 👍 或 👎,我会根据你的反馈改进后续的代码审查。
Original comment in English

Hey - I've found 1 issue, and left some high level feedback:

  • The allowed role values ("admin", "owner", "member") are hardcoded in multiple places; consider centralizing them into a shared constant or enum to avoid divergence and make future changes safer.
  • In aiocqhttp_message_event.get_group, role is passed through without the validation used in _convert_handle_message_event; consider applying the same normalization/validation so cached members behave consistently with live events.
  • The AstrMessageEvent.role docstring was changed to English only while nearby docstrings remain Chinese; consider keeping the language/style consistent with surrounding comments for readability.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The allowed role values ("admin", "owner", "member") are hardcoded in multiple places; consider centralizing them into a shared constant or enum to avoid divergence and make future changes safer.
- In `aiocqhttp_message_event.get_group`, `role` is passed through without the validation used in `_convert_handle_message_event`; consider applying the same normalization/validation so cached members behave consistently with live events.
- The `AstrMessageEvent.role` docstring was changed to English only while nearby docstrings remain Chinese; consider keeping the language/style consistent with surrounding comments for readability.

## Individual Comments

### Comment 1
<location path="astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py" line_range="244-247" />
<code_context>
                 MessageMember(
                     user_id=member["user_id"],
                     nickname=member.get("nickname") or member.get("card"),
+                    role=member.get("role"),
                 )
                 for member in members
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Validate or normalize `member["role"]` to match the expected role set.

This path now passes `member.get("role")` through without the constraints used for `sender_role` ("admin"/"owner"/"member"/None). If CQHTTP ever returns an unexpected role string, it will bypass the checks in `AstrMessageEvent` and introduce inconsistent role values. Please reuse the same validation/normalization logic here so all sources produce a consistent, validated role set.

Suggested implementation:

```python
                MessageMember(
                    user_id=member["user_id"],
                    nickname=member.get("nickname") or member.get("card"),
                    role=normalize_role(member.get("role")),
                )
                for member in members
            ],

```

1. Ensure there is a `normalize_role` (or similarly named) function in this module that implements the same validation/normalization logic currently used for `sender_role` (e.g. mapping only `"admin"`, `"owner"`, `"member"` to themselves and returning `None` or a default for any other value).
2. If the `sender_role` normalization is currently inline (e.g. `if role not in (...)`), extract that logic into `normalize_role(role: Optional[str]) -> Optional[str]` and replace the inline normalization used for `sender_role` with a call to `normalize_role` as well, to keep the behavior consistent between senders and members.
</issue_to_address>

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
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

此拉取请求旨在解决 aiocqhttpNapCat 平台下,群消息发送者的角色信息(如管理员和群主)未能正确传递到 AstrBot 事件对象的问题。通过引入角色字段并更新相关逻辑,确保了这些特殊成员能够被正确识别为管理员,从而使依赖于 event.is_admin() 的管理命令能够正常执行,提升了系统的权限管理准确性。

Highlights

  • 扩展 MessageMember 对象: 新增了 role 字段以承载发送者角色信息。
  • 角色信息透传: 实现了从 aiocqhttp 事件中正确读取并透传发送者角色(管理员、群主、成员)到 MessageMember
  • 管理员判定逻辑更新: 更新了事件角色初始化逻辑,确保 owneradmin 角色都被正确识别为管理员。
  • 群成员列表同步: 完善了群成员列表构建逻辑,以同步成员的角色信息。
  • 单元测试覆盖: 增加了单元测试,覆盖了群主管理员判定和 MessageMember.role 的默认行为。
Changelog
  • astrbot/core/platform/astr_message_event.py
    • 更新了 AstrMessageEvent 的初始化方法,使其能够从 message_obj.sender.role 获取并设置事件角色,并对非法角色值进行默认处理。
    • 修改了 is_admin 方法,使其将 owneradmin 角色都视为管理员。
  • astrbot/core/platform/astrbot_message.py
    • MessageMember 类中添加了可选的 role 字段。
  • astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py
    • get_group 方法中,为从 aiocqhttp 获取的群成员数据构建 MessageMember 对象时,加入了 role 字段的赋值。
  • astrbot/core/platform/sources/aiocqhttp/aiocqhttp_platform_adapter.py
    • _convert_handle_message_event 方法中,从 aiocqhttp 事件的 sender 中提取 role 信息,并将其传递给 MessageMember 构造函数,同时对角色值进行了有效性检查。
  • tests/unit/test_astr_message_event.py
    • 新增了测试用例,验证当角色为 owneris_admin 方法返回 True
  • tests/unit/test_astrbot_message.py
    • 更新了 MessageMember 的创建测试,以断言新添加的 role 字段在未指定时默认为 None
Activity
  • 目前没有检测到人类活动,例如评论或审查。
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

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

Choose a reason for hiding this comment

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

Code Review

这个 PR 修复了 aiocqhttp 平台下管理员角色未能正确传递的问题,代码改动清晰,覆盖了数据结构、适配器逻辑和单元测试,做得很好。我只在代码风格方面有一个小建议,可以让其中一部分逻辑更简洁。

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

Labels

area:platform The bug / feature is about IM platform adapter, such as QQ, Lark, Telegram, WebChat and so on. size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant