命令系统
读完这一页,你会知道命令回调收到什么、命令在哪些场景生效。 你还会明白为什么用户必须按你注册的写法来敲。
命令要在插件的 on_load 里注册。用户在 QQ 发送命令后,框架解析命令树,再调用对应的函数。
命令节点和 Builder 都从 botqraft.api.command 导入。先认识回调的来源、参数和场景,再用 SimpleCommandBuilder 注册命令。
接收 source 和 context
带参数的回调使用两个参数:
from botqraft.api.command import CommandContext, QQCommandSource
def echo(source: QQCommandSource, context: CommandContext) -> None:
source.reply(context['text'])source是这次命令的真实 QQ 消息来源。context保存命令节点解析出的参数。参数节点名叫text时,就用context['text']取值。source.reply(...)回复触发命令的那条消息。回复关联使用原始消息 ID 和原会话。
只用来源的回调可以写成 def ping(source): ...。节点回调支持零到两个参数,依次是来源和上下文。
QQCommandSource 的常用成员如下:
| 成员 | 用途 |
|---|---|
user | 查看发起命令的用户。 |
scene | 查看当前场景:group 或 c2c。 |
conversation | 查看当前会话地址。 |
msg_id | 查看原始入站消息 ID。 |
message_data | 读取消息正文等解析结果。 |
origin_received | 取得原始收到的事件。 |
get_server() | 取得当前实例的 QQServerInterface。 |
has_permission(level) | 检查当前有效权限。 |
插件的 on_load 收到绑定插件的 QQPluginServerInterface。用这个接口登记命令、帮助和其他插件资源。回复细节见响应事件与回复消息,权限规则见权限。
选择 scope
scope 决定命令在哪种 QQ 场景里可用:
| 注册值 | 场景 |
|---|---|
('group', 'c2c') | 群聊和 C2C 私聊,默认值。 |
('group',) | 群聊。 |
('c2c',) | C2C 私聊。 |
原生命令树通过 server.register_command(root, scope=('group',)) 指定场景。Builder 的 register(server) 使用默认场景。要指定场景,方法见下一页。
命令和帮助分别登记 scope。同一条命令要填相同的场景。能不能执行由节点的 requires(...) 检查,帮助的权限只控制帮助显不显示。
命令名称要和注册时一致
命令根做的是精确匹配,/ 保留在名称里。也就是说:注册时写什么,用户就得发什么。
比如注册 /echo 之后,在 QQ 发送:
/echo Hello worldecho Hello world 用的是另一个根名称,匹配不上。请让用户的写法和注册的路径保持一致。
群消息进入命令解析前,正文按下面的规则处理:
GROUP_AT_MESSAGE_CREATE去掉前导 ASCII 空格。- 当前 dev 版本对
GROUP_MESSAGE_CREATE做前缀修正:跳过前导 ASCII 空格后,正文开头必须是<@id>,且对应的MentionedUser.is_you is True。满足条件时,移除一个标签及其后的 ASCII 空格。 - 其他正文保持原样,包括
<@!id>、正文中间的标签和重复的后续标签。内部与尾部空格、引用元素、完整 mentions、raw_payload、data和原始收件日志也保持原样。 - C2C 正文保持原样。
事件字段见事件消息格式。
在真实 QQ 消息中执行
插件命令要在 QQ 里验证。运维控制台执行的是内置的 /botqraft 命令树。
需要从插件触发另一条命令时,调用 server.execute_command(command, source)。传入本实例真实的 QQCommandSource:可以用命令回调的来源,也可以用入站消息的 event.get_command_source()。来源的身份、消息 ID 和会话地址都来自真实收到的数据。
接下来,用 SimpleCommandBuilder 声明命令路径。