# NoneBot2 + OneBot V11 完整能力清单 > 本文档整理 NoneBot2 框架和 OneBot V11 协议的全部原生能力, > 用于指导 HexiCore 封装层的设计——只封装原生不方便用的部分。 --- # 一、NoneBot2 框架能力 ## 1. 事件响应器(Matcher) | 创建方式 | 用途 | |---|---| | `on_command(cmd, aliases)` | 命令匹配(最常用) | | `on_startswith(prefix)` | 前缀匹配 | | `on_endswith(suffix)` | 后缀匹配 | | `on_fullmatch(text)` | 完全匹配 | | `on_keyword(words)` | 关键词匹配 | | `on_regex(pattern)` | 正则匹配 | | `on_message()` | 所有消息 | | `on_notice()` | 通知事件 | | `on_request()` | 请求事件 | | `on_type(event_types)` | 指定事件类型 | **Matcher 生命周期方法:** ```python matcher.handle() # 注册处理函数 matcher.got(key, prompt) # 等待用户输入 matcher.receive("id") # 等待下一条消息 matcher.send(msg) # 发送消息 matcher.finish(msg) # 发送并结束 matcher.reject(msg) # 拒绝输入,重新等待 matcher.pause() # 暂停,等待下一条消息 matcher.stop_propagation()# 阻止后续匹配器 ``` **内置权限:** ```python from nonebot.permission import SUPERUSER, GROUP_ADMIN, GROUP_OWNER, GROUP, PRIVATE ``` **内置规则:** ```python from nonebot.rule import to_me, is_type, command, keyword, startswith, endswith, fullmatch, regex ``` --- ## 2. 依赖注入(DI) **类型注入(直接写类型注解即可):** ```python async def handler( bot: Bot, event: Event, state: T_State, matcher: Matcher, ): ... ``` **参数依赖(from nonebot.params):** | 依赖 | 返回值 | |---|---| | `CommandArg()` | 命令参数 `Message` | | `Command()` | 命令名 `tuple[str, ...]` | | `RawCommand()` | 原始命令文本 | | `CommandStart()` | 命令前缀 | | `EventMessage()` | 事件消息 `Message` | | `EventPlainText()` | 纯文本 | | `EventToMe()` | 是否 @ 机器人 `bool` | | `Arg(key)` | `got` 获取的参数 | | `ArgStr(key)` | `got` 参数的字符串 | | `ArgPlainText(key)` | `got` 参数的纯文本 | | `RegexGroup()` | 正则捕获组 | | `RegexStr()` | 正则匹配文本 | --- ## 3. 消息系统 ### Message 类(List[MessageSegment]) ```python msg.extract_plain_text() # 提取纯文本 msg.has("image") # 是否包含某类型 msg.only("text") # 是否只有某类型 msg["text"] # 过滤出所有文本段 msg["text", 0] # 第一个文本段 msg.include("text", "image") # 只保留指定类型 msg.exclude("image") # 排除指定类型 msg.count("image") # 计数 msg.index("image") # 索引 msg + "text" # 拼接 Message.template("{} {}").format(a, b) # 模板 ``` ### OneBot V11 MessageSegment ```python MessageSegment.text("hello") # 文本 MessageSegment.image(file) # 图片(URL/路径/base64) MessageSegment.record(file) # 语音 MessageSegment.video(file) # 视频 MessageSegment.at(user_id) # @某人 MessageSegment.at_all() # @全体 MessageSegment.reply(msg_id) # 回复 MessageSegment.face(id) # QQ表情 MessageSegment.poke(type, id) # 戳一戳 MessageSegment.forward(id) # 转发消息 MessageSegment.json(data) # JSON卡片 MessageSegment.xml(data) # XML卡片 MessageSegment.share(url, title) # 链接分享 MessageSegment.music(type, id) # 音乐卡片 MessageSegment.location(lat, lon) # 位置 ``` --- ## 4. UniMessage(跨平台消息,nonebot-plugin-alconna) ```python UniMessage.text("hello") # 文本 UniMessage.at("123456") # @某人 UniMessage.at_all() # @全体 UniMessage.image(url="...") # 图片 UniMessage.audio(url="...") # 音频 UniMessage.voice(url="...") # 语音 UniMessage.video(url="...") # 视频 UniMessage.file("id") # 文件 UniMessage.reply("msg_id") # 回复 UniMessage.emoji("id") # 表情 ``` **发送与操作:** ```python await msg.send() # 发送 await msg.send(at_sender=True) # @发送者 await msg.send(reply_to=True) # 回复原消息 await msg.finish() # 发送并结束 receipt = await msg.send() # 获取回执 await receipt.recall(delay=5) # 5秒后撤回 await receipt.edit(UniMessage.text("新内容")) # 编辑 await receipt.reaction("thumbsup") # 添加表情回应 ``` **序列化:** ```python data = msg.dump() # 存储 msg = UniMessage.load(data) # 还原 ``` --- # 二、OneBot V11 协议能力 ## 1. 消息类 API | API | 参数 | 说明 | |---|---|---| | `send_msg` | `message_type`, `user_id`/`group_id`, `message` | 通用发送 | | `send_private_msg` | `user_id`, `message` | 私聊发送 | | `send_group_msg` | `group_id`, `message` | 群聊发送 | | `delete_msg` | `message_id` | 撤回消息 | | `get_msg` | `message_id` | 获取消息详情 | | `get_forward_msg` | `id` | 获取转发消息内容 | ## 2. 群管理 API | API | 参数 | 说明 | |---|---|---| | `set_group_kick` | `group_id`, `user_id`, `reject_add_request` | 踢出成员 | | `set_group_ban` | `group_id`, `user_id`, `duration` | 禁言(0=解除) | | `set_group_anonymous_ban` | `group_id`, `anonymous_flag`, `duration` | 禁言匿名 | | `set_group_whole_ban` | `group_id`, `enable` | 全员禁言 | | `set_group_admin` | `group_id`, `user_id`, `enable` | 设置/取消管理员 | | `set_group_card` | `group_id`, `user_id`, `card` | 修改群名片 | | `set_group_name` | `group_id`, `group_name` | 修改群名 | | `set_group_leave` | `group_id`, `is_dismiss` | 退群/解散 | | `set_group_special_title` | `group_id`, `user_id`, `special_title` | 设置群头衔 | | `set_group_anonymous` | `group_id`, `enable` | 开关匿名聊天 | ## 3. 请求处理 API | API | 参数 | 说明 | |---|---|---| | `set_friend_add_request` | `flag`, `approve`, `remark` | 好友申请 | | `set_group_add_request` | `flag`, `sub_type`, `approve`, `reason` | 加群/邀请申请 | ## 4. 信息查询 API | API | 参数 | 说明 | |---|---|---| | `get_login_info` | — | 获取登录信息 | | `get_stranger_info` | `user_id`, `no_cache` | 获取陌生人信息 | | `get_friend_list` | — | 获取好友列表 | | `get_group_info` | `group_id`, `no_cache` | 获取群信息 | | `get_group_list` | — | 获取群列表 | | `get_group_member_info` | `group_id`, `user_id`, `no_cache` | 获取群成员信息 | | `get_group_member_list` | `group_id` | 获取群成员列表 | | `get_group_honor_info` | `group_id`, `type` | 获取群荣耀信息 | ## 5. 社交 API | API | 参数 | 说明 | |---|---|---| | `send_like` | `user_id`, `times` | 点赞(最多10次/天) | ## 6. 媒体 API | API | 参数 | 说明 | |---|---|---| | `get_image` | `file` | 获取图片文件 | | `get_record` | `file`, `out_format` | 获取语音文件 | | `can_send_image` | — | 检查能否发图 | | `can_send_record` | — | 检查能否发语音 | ## 7. 系统 API | API | 参数 | 说明 | |---|---|---| | `get_status` | — | 运行状态 | | `get_version_info` | — | 版本信息 | | `set_restart` | `delay` | 重启 | | `clean_cache` | — | 清理缓存 | --- # 三、OneBot V11 事件类型 ## 消息事件 | 事件类 | 关键字段 | |---|---| | `GroupMessageEvent` | `group_id`, `user_id`, `message_id`, `message`, `sender` | | `PrivateMessageEvent` | `user_id`, `message_id`, `message`, `sender` | **GroupMessageEvent.sender 字段:** ```python sender.user_id # QQ号 sender.nickname # 昵称 sender.card # 群名片 sender.role # "owner" / "admin" / "member" sender.title # 群头衔 sender.sex # 性别 sender.age # 年龄 sender.area # 地区 sender.level # 等级 ``` ## 通知事件 | 事件类 | 关键字段 | 说明 | |---|---|---| | `PokeNotifyEvent` | `group_id`, `user_id`, `target_id` | 戳一戳 | | `GroupIncreaseNoticeEvent` | `group_id`, `user_id`, `operator_id` | 成员加入 | | `GroupDecreaseNoticeEvent` | `group_id`, `user_id`, `operator_id` | 成员离开 | | `GroupBanNoticeEvent` | `group_id`, `user_id`, `operator_id`, `duration` | 禁言 | | `GroupAdminNoticeEvent` | `group_id`, `user_id` | 管理员变动 | | `GroupRecallNoticeEvent` | `group_id`, `user_id`, `operator_id`, `message_id` | 群消息撤回 | | `FriendRecallNoticeEvent` | `user_id`, `message_id` | 私聊消息撤回 | | `FriendAddNoticeEvent` | `user_id` | 好友添加 | | `GroupUploadNoticeEvent` | `group_id`, `user_id`, `file` | 文件上传 | | `GroupNotifyEvent` | `sub_type="lucky_king"` | 红包运气王 | | `GroupNotifyEvent` | `sub_type="honor"` | 荣誉变更 | ## 请求事件 | 事件类 | 关键字段 | 说明 | |---|---|---| | `FriendRequestEvent` | `user_id`, `comment`, `flag` | 好友申请 | | `GroupRequestEvent` | `group_id`, `user_id`, `comment`, `flag`, `sub_type` | 加群/邀请申请 | ## 元事件 | 事件类 | 说明 | |---|---| | `MetaEvent` (lifecycle) | 生命周期(enable/disable/connect) | | `MetaEvent` (heartbeat) | 心跳 | --- # 四、HexiCore 封装建议 ## 已有原生能力(无需封装,直接用) | 能力 | 原生用法 | |---|---| | 发消息 | `UniMessage.text("hello").send()` | | 发图片 | `UniMessage.image(url="...").send()` | | @某人 | `UniMessage.at("123").send()` | | 回复消息 | `UniMessage.reply("msg_id").send()` | | 撤回消息 | `bot.delete_msg(message_id=...)` | | 禁言 | `bot.set_group_ban(group_id=..., user_id=..., duration=...)` | | 踢人 | `bot.set_group_kick(group_id=..., user_id=...)` | | 群名片 | `bot.set_group_card(group_id=..., user_id=..., card=...)` | | 管理员 | `bot.set_group_admin(group_id=..., user_id=..., enable=...)` | | 群头衔 | `bot.set_group_special_title(group_id=..., user_id=..., title=...)` | | 好友申请 | `bot.set_friend_add_request(flag=..., approve=...)` | | 加群申请 | `bot.set_group_add_request(flag=..., sub_type=..., approve=...)` | | 判断群/私聊 | `isinstance(event, GroupMessageEvent)` | | 获取发送者 | `event.sender.user_id` / `event.sender.nickname` | | 获取群号 | `event.group_id` | | 获取消息ID | `event.message_id` | | 判断管理员 | `event.sender.role in ("admin", "owner")` | | 判断超级用户 | `str(event.user_id) in driver.config.superusers` | | 遍历消息段 | `for seg in event.message: ...` | | 获取纯文本 | `event.get_plaintext()` | ## 值得封装(原生用起来麻烦) ### 1. 戳一戳(Poke) ```python # 原生:需要知道 API 非标准 await bot.call_api("send_poke", group_id=group_id, user_id=user_id) # HexiCore 封装:简化为 await hexi.poke(group_id, user_id) ``` ### 2. 合并转发消息 ```python # 原生:需要手动构建 node 结构 nodes = [ {"type": "node", "data": {"user_id": "123", "nickname": "name", "content": [seg]}}, ... ] await bot.call_api("send_group_forward_msg", group_id=group_id, message=nodes) # HexiCore 封装:链式构建 forward = hexi.forward() forward.add("123", "name", UniMessage.text("内容")) forward.add("456", "name2", UniMessage.image(url="...")) await forward.send(group_id) ``` ### 3. 消息加精 / 取消加精 ```python # 原生:API 名称不直观 await bot.call_api("set_msg_essence", message_id=msg_id) await bot.call_api("delete_msg_essence", message_id=msg_id) # HexiCore 封装 await hexi.essence(msg_id) # 加精 await hexi.unessence(msg_id) # 取消 ``` ### 4. 获取 At 用户列表 ```python # 原生:需要遍历 at_users = [seg.data["qq"] for seg in event.message if seg.type == "at"] # HexiCore 封装 users = hexi.get_at_users(event) ``` ### 5. 是否好友 / 是否群成员 ```python # 原生:需要调用 API + 异常处理 try: await bot.get_stranger_info(user_id=user_id) is_friend = True except: is_friend = False # HexiCore 封装 is_friend = await hexi.is_friend(user_id) is_member = await hexi.is_member(group_id, user_id) ``` ### 6. 权限推断(可发送/可撤回/可禁言等) ```python # 原生:没有直接 API,需要根据身份推断 role = event.sender.role can_ban = role in ("admin", "owner") # 但还需要检查机器人自身是否是管理员 # HexiCore 封装 can_ban = await hexi.can_ban(group_id, user_id) # 检查目标是否可被禁言 can_kick = await hexi.can_kick(group_id, user_id) # 检查目标是否可被踢 ``` ### 7. 获取回复的原始消息 ```python # 原生:event.reply 只有 message_id,需要再调 API 获取内容 reply_msg = await bot.get_msg(message_id=event.reply.message_id) # HexiCore 封装 reply_content = hexi.get_reply_content(event) # 直接返回 Message 对象 ``` ### 8. 获取消息来源(群号/私聊) ```python # 原生:需要类型判断 + 字段访问 if isinstance(event, GroupMessageEvent): source = event.group_id elif isinstance(event, PrivateMessageEvent): source = event.user_id # HexiCore 封装 source = hexi.get_source(event) # 统一返回 ``` --- ## 总结:HexiCore 定位 ``` HexiCore = 原生能力的便利封装层 目标:让业务层用一行代码完成需要写 3-5 行的操作 原则: 1. 不重复造轮子——原生好用的直接用 2. 封装复杂 API 调用——简化参数、统一接口 3. 提供便捷判断方法——省去类型检查和异常处理 4. 保持轻量——只做薄封装,不改变底层行为 ```