切换外观
VexBot 插件开发文档
插件接口版本:1。本接口用于扩展 VexBot 机器人主程序,与 Minecraft 服务端的 VexBot JAR 分开管理。
QQ 官机同样使用本规则接口。群权限范围填写完整 qg:AppID:group_openid,用户范围填写 qug:AppID:member_openid 或 qup:AppID:user_openid;身份按应用与场景分别检查。群规则接收平台下发的 @消息,通知发送受有效回复上下文及主动发送权限约束,详见 官机接入。
用途与边界
一个插件就是一个 UTF-8 JSON 文件,可以增加 QQ 群命令、文本模板回复、Minecraft 入服/退服通知,以及在面板中编辑的配置项。无需 Python、Java 或第三方依赖;插件文件不会被作为代码运行。
规则插件不支持 Python / JavaScript 脚本、控制台命令、玩家封禁、数据库修改、网络请求、第三方依赖和任意图片消息。指定指令或关键词的文字回复可由服主在图片回复设置中选择本地渲染,不允许插件执行 HTML、下载 URL 或读取图片文件。定时任务由内置插件管理,外部规则插件不能自行创建任务。玩家管理仍在成员页面配置。归属地保持手动填写,不提供自动查询。
只需要固定的「关键词 → 文字」回复时,可直接使用下方的内置关键词回复,无需编写文件。需要参数、模板变量或入退服事件时,再使用 JSON 规则插件;公告、预设命令和备份计划使用 定时任务。
第一次开发先完成 快速开始 和 OneBot 接入,准备一个已关联服务器的测试群以及具有 plugins.manage 权限的管理会话。首次群命令示例无需游戏桥接在线;入退服通知需要游戏端桥接在线。内置命令及身份条件分别见 群命令 和 账号绑定。
第一个可运行的插件
保存以下内容为 UTF-8 编码的 hello_world.json:
json
{
"api_version": 1,
"id": "hello_world",
"name": "你好,社区",
"version": "1.0.0",
"description": "发送你好,收到社区的问候。",
"author": "你的名字",
"settings": {
"greeting": {
"type": "string",
"label": "问候内容",
"default": "欢迎一起玩 Minecraft!",
"max_length": 500
}
},
"rules": [
{
"event": "group_command",
"command": "你好",
"reply": "{settings.greeting}\n当前服务器:{server_name}",
"cooldown": 3
}
]
}- 登录面板,进入顶部「扩展」。
- 点击「导入插件」,选择这个 JSON 文件。新插件默认停用,导入不会发送消息。
- 点击插件卡片的「设置」,修改问候内容并单独保存。
- 打开「权限」,确认允许发送群消息和群命令,且服务器、群、使用者范围包含测试环境。
- 点击「启用」。无需重启主程序。
- 在已关联的 QQ 群中发送
你好,应收到问候内容和当前服务器名称。此示例为精确匹配,你好 Steve不会触发。
也可以把文件放进配置文件所在目录下的 plugins/hello_world.json,然后点击「扫描目录」。文件名必须与 id 一致。使用 --config 指向其他目录时,插件和插件状态也使用那个配置目录。
项目附带 examples/community_helper.json,提供「服讯」「问候 内容」及可选入服欢迎,导入后初始停用。面板可下载示例;同 ID 不能重复导入。修改示例 ID 后即可作为自己的插件安装。
验收与排查
第一次成功后,修改问候设置并保存,等至少 3 秒再发 你好,确认新内容立即生效;停用后确认不再回复。连续发送时,冷却期间不重复回复是正常行为。
| 现象 | 检查与处理 |
|---|---|
| 导入提示 JSON 或声明错误 | 使用 UTF-8 JSON,去掉注释和尾随逗号;检查 api_version、ID、默认值和模板变量 |
| 显示同 ID 已存在 | 新插件更换 ID 和文件名;升级已有插件使用同 ID、不同版本的面板更新流程 |
| 群里没有回复 | 先确认 OneBot 在线、该群已关联服务器、插件已启用;再检查「权限」、精确匹配、冷却和是否被同名关键词回复先处理 |
| 提示仅限管理员 / 需要绑定 | 检查规则 admin_only、bound_only;机器人管理员是 onebot.admins,QQ 群管理员身份不会自动授权 |
| 读取玩家名显示「未绑定」 | 检查当前服务器的绑定和 read_bindings 权限;读取关闭时不会提供绑定姓名 |
| 状态变量显示「未授权」或离线 | 检查 read_server 权限及桥接心跳;离线快照可能保留旧人数,应同时展示 {online} |
| 修改磁盘文件后回复没变化 | 「重新载入」只刷新面板;修改 JSON 定义后使用卡片「重新加载」,或通过面板导入新版本 |
| 保存返回 409 | 关闭弹窗并重新载入,使用新的 revision 编辑;不要重复提交旧正文 |
以下章节说明内置插件、字段和管理 API,成功运行第一个示例后再按需要查阅。
内置插件与权限
内置关键词回复插件
「扩展 → 关键词回复 → 管理回复」提供添加、搜索、编辑和删除,每个关联群共享这些回复。最多 200 条,关键词最多 80 字,回复最多 3500 字;可清空所有回复,也可单独停用插件。启用状态和回复内容保存到 data/plugin-state.json,保存立即生效。它精确匹配整条消息,内容按纯文字发送,花括号不会展开为模板,CQ 文本不会执行。
首次升级启动将原配置 [replies] 原样导入,有旧回复时保持启用,没有时默认停用。导入仅执行一次,后续重启和扫描不会恢复已删除的回复或重置启用状态。原 [replies] 保留为迁移备份,不再用于运行时回复;配置 API 不接受修改该字段。帮助、绑定等内置命令先执行,其后是已启用的关键词回复,再处理导入插件的群命令。
编辑器以「收到这句话 → 发送这段文字」组织每条问答,与远程服务器指令分开编辑。在「本地试一条群消息」输入文字,可检查当前草稿的精确匹配与回复内容;新增、修改和移除会同步更新结果,空条目或重复名称会提示先检查草稿。这个检查不发送 QQ 消息、不执行服务器命令,也不改变未保存状态。实际群响应仍受内置命令优先级、插件开关与权限限制;预览为文字展示,CQ 码、HTML 和花括号均不执行或展开。
内置 ID keyword_replies 保留,不可通过 JSON 导入或移除;需要关闭时停用即可。reply_map 是此内置插件的专用设置类型,不属于外部 JSON 插件声明格式。
管理员 API 使用 PUT /api/extensions/keyword_replies,正文例如 {"revision":"当前插件 revision","enabled":true,"settings":{"replies":{"官网":"https://example.com","规则":"友善交流"}}}。settings.replies 是完整替换,空对象表示清空所有回复;可只提交 enabled 切换状态。未提供 enabled 时保留原状态。接口需要面板管理令牌,版本冲突返回 409;网站注册 API 密钥不能管理插件。插件状态文件总量限制为 4 MiB,单次 HTTP 请求仍限制为 256 KiB。
内置定时任务插件
内置 ID scheduled_tasks 提供群公告、游戏公告、预设命令和备份,不能被 JSON 文件替换、更新或移除。卡片「管理任务」打开任务与执行记录;启用状态和授权保存到 data/plugin-state.json,任务保存在 SQLite 中,两者都随备份保存。全新安装默认停用;首次迁移时保留已有启用任务的运行状态,后续重启不会重新启用已经停用的插件。
停用插件后自动与手动执行均暂停,已发送或提交的操作继续等待结果。重新启用时跳过暂停期间到期的任务。权限包括 send_group、send_game、execute_commands、create_backups 及服务器、群范围;每次执行重新检查,命令还必须存在于服务器的预设命令列表。外部 JSON 规则无法使用这些新增的定时动作。详细操作见 定时任务与白名单申请。
面板权限管理
每个插件卡片提供「权限」,可以限制发送群消息、群命令、游戏事件、绑定玩家名和服务器状态读取,以及服务器、群、使用者、QQ 允许 / 拒绝名单。权限由管理员保存到 data/plugin-state.json,不属于插件声明,插件导入文件不能自行授权。已有插件升级保留原行为,新导入插件仍停用。
PUT /api/extensions/{id} 可增加 permissions,省略时保留已有授权,例如:
json
{
"revision": "当前插件 revision",
"permissions": {
"send_group": true, "group_commands": true, "game_events": false,
"read_bindings": false, "read_server": true,
"servers": ["survival"], "groups": ["123456789"],
"user_mode": "bound", "allow_users": [], "deny_users": []
}
}permissions 省略的子字段使用默认值(能力开关 true,名单空,user_mode 为 all)。更新授权时建议发送完整对象。名单最多 100 项,空名单不额外限制,QQ 拒绝名单优先。面板授权与规则的身份限制需同时满足;游戏通知不使用 QQ 身份名单。读取绑定关闭后不提供绑定姓名,读取状态关闭后对应模板显示“未授权”。完整行为见 定时任务与白名单申请。
| 权限字段 | 生效范围 |
|---|---|
send_group | 向关联群发送文字;与对应事件能力同时检查 |
group_commands | 处理导入插件群命令与内置关键词回复 |
game_events | 处理真实入退服事件通知 |
read_bindings | 在群命令模板中提供绑定玩家名,不授予绑定或解绑能力 |
read_server | 在模板中提供桥接状态、在线人数与玩家列表;服务器 ID / 名称仍可使用 |
servers / groups | 限制可用服务器 ID / 群号,使用字符串数组 |
user_mode | all 所有成员、bound 当前服务器已绑定成员、admins 机器人管理员 |
allow_users / deny_users | QQ 允许 / 拒绝名单,拒绝优先;空允许名单不额外限制 |
send_game / execute_commands / create_backups | 内置定时任务使用,外部 JSON 规则不能据此创建游戏动作、执行命令或备份 |
文件结构
| 字段 | 类型 | 说明 |
|---|---|---|
api_version | 整数 | 必须为 1 |
id | 字符串 | 小写字母开头,其后仅小写字母、数字、下划线,最多 40 字 |
name | 字符串 | 显示名称,1–80 字 |
version | 字符串 | 版本标识,1–40 字;建议使用 1.0.0 |
description | 字符串 | 可选,最多 500 字 |
author | 字符串 | 可选,最多 80 字 |
changelog | 字符串 | 可选,最多 2000 字,纯文字更新说明 |
settings | 对象 | 可选,最多 20 个设置项 |
rules | 数组 | 必填,1–20 条规则 |
最多安装 30 个插件,每个文件最多 64 KiB。JSON 不支持注释和尾随逗号。只接受上述顶层字段,不会加载声明中的代码或任意文件路径。
可视化设置
设置项名称与插件 ID 使用相同的命名规则。每项必须填写 type、label 和 default;可选的 description 显示在输入控件下方。
| type | default 类型 | 控件 | 可选限制 |
|---|---|---|---|
string | 字符串 | 多行文本框 | max_length,1–2000,默认 2000 |
boolean | 布尔值 | 勾选框 | 使用 true / false |
integer | 整数 | 数字输入框 | min、max |
number | 数字 | 可带小数的输入框 | min、max |
select | 字符串 | 美化下拉框 | options,1–30 个不同字符串,默认值需在其中 |
数值必须为有限数,绝对值不能超过十亿;默认值也必须符合声明。插件设置保存到 data/plugin-state.json,不改变主程序 config.toml,不会触发主程序的「保存全部设置」。保存后立即生效,重启后保留。
模板用 {settings.设置项名称} 引用配置,例如 {settings.greeting}。设置值是普通文本,内部的花括号不会再次作为模板解析。此版本没有密钥设置项,不要在插件配置中保存登录令牌。
群命令
json
{
"event": "group_command",
"command": "建议",
"match": "prefix",
"reply": "收到你的建议:{arg}\n提交人:{user_id},玩家:{player}",
"bound_only": true,
"admin_only": false,
"cooldown": 10
}| 字段 | 说明 |
|---|---|
event | 固定为 group_command |
command | 1–40 字,不能含空白 |
match | exact(默认)精确匹配整条消息;prefix 接受命令或「命令 + 普通空格 + 参数」 |
reply | 1–2000 字的回复模板 |
admin_only | 可选,默认 false,仅允许 onebot.admins 中的 QQ 号使用 |
bound_only | 可选,默认 false,要求在当前服务器已绑定游戏账号 |
cooldown | 1–3600 秒,默认 3 秒,按插件/规则/群/发送人计算 |
when | 可选,引用一个 boolean 设置项,该设置为 true 时规则才参与匹配 |
规则的 admin_only 或 bound_only 不满足时发送固定说明;面板能力或范围授权不满足时消费匹配消息,不发送回复。冷却期间匹配命令会被消费,不重复回复,也不会转发到游戏。when 为 false 时跳过规则,消息继续走其他规则或普通聊天转发。
内置「帮助、help、/help、状态、在线、绑定、我的绑定、解绑、执行、/申请、/注册、/白名单、/白名单状态、/确认登录、/拒绝登录」优先,插件不能声明这些命令。登录确认只在机器人私聊处理,不能通过群插件替代。已启用的关键词回复插件也优先于导入插件。有效消息仍经过原有的账号识别、匿名消息过滤、事件去重与限流。
插件按 ID 的字母顺序处理,同一插件按规则数组顺序处理。第一条匹配规则处理后停止,避免一条消息产生多份回复。不同插件请使用不同命令;多个插件声明相同命令时,排序靠前的插件优先。
只会响应已关联的 QQ 群,不接收陌生群或私聊。回复通过 OneBot 11 的 text 消息段发送,模板中的 CQ 字符串保持为普通文本。
游戏事件通知
json
{
"event": "player_join",
"reply": "[{server_name}] 欢迎 {player} 回来!",
"when": "join_notice",
"cooldown": 30
}player_join 和 player_quit 对应桥接的真实入服、退服事件;需要已安装并连接的游戏端 VexBot 插件。通知仅发送到该服务器已关联的群,不能在插件文件中指定任意收件人。聊天事件和普通心跳不触发这些通知。
游戏规则不接受 command、match、QQ 管理员或绑定身份限制。支持 reply、when、cooldown;冷却按服务器和玩家 UUID(旧事件无 UUID 时使用玩家名)分别计算。
内置进退服通知与插件通知是独立功能,两者启用时都会发送。如果只想用自定义模板,可关闭「自动化 → 消息与事件 → 进退服通知」。示例的入服欢迎设置默认关闭。
模板变量
| 变量 | 内容 |
|---|---|
{server_name} | 当前服务器显示名称 |
{server_id} | 当前服务器 ID |
{group_id} | 当前 QQ 群号 |
{user_id} | 群消息发送人的 QQ 号;游戏通知为空 |
{arg} | prefix 群命令的参数;其他事件为空 |
{player} | 群命令:当前账号绑定的玩家名,未绑定为「未绑定」;游戏事件:玩家名 |
{players} | 最近桥接心跳中的玩家名列表,无记录为「暂无玩家」 |
{online_count} | 最近心跳的在线玩家人数,无记录为 0 |
{online} | 桥接连接状态,显示「在线」或「离线」 |
{settings.key} | 插件设置项 key 的值 |
人数及玩家列表来自最近一次心跳;离线时可能保留旧快照,应同时展示 {online}。模板只是固定变量替换,不支持表达式、函数、属性遍历、递归模板或正则表达式。未声明的上述形式变量会导致插件校验失败。
加载、升级与移除
- 启用 / 停用:立即应用并持久保存,重启时恢复选择。
- 设置:单独保存插件设置;多个页面使用版本校验,旧页面不会覆盖新设置,冲突时关闭设置弹窗、重新载入后再编辑。
- 重新载入:更新面板中的状态和设置,不读取磁盘上的新定义。
- 重新加载:重新读取这一插件的 JSON,适用于修改命令、模板或规则。
- 扫描目录:重新发现目录中的 JSON 文件,保留当前已保存的配置与启用选择。
- 移除:仅停用后可移除,原文件移至
data/plugin-archive/,配置保留。重新导入相同 ID 总是停用,并重新使用默认设置。
升级时在面板导入同 ID、不同版本的 JSON,确认版本与更新说明后更新,检查设置和权限再启用。面板保留兼容设置,新字段使用默认值,并保存旧版本供回退;不自动下载升级。直接替换磁盘文件再「重新加载」不会生成版本历史,建议使用面板更新流程。详见下方「插件版本更新与回退」。
单个插件格式错误不会阻止其他插件或主程序启动。状态文件损坏时所有插件停用且禁止写入,以免覆盖已有设置;修复或备份该文件后重启。通知发送失败记录错误,不重放,以免重复发送。
性能约束
插件只在消息或游戏事件到达时匹配,使用固定字符串匹配及一次变量替换,没有持续动画、脚本解释器、轮询任务或后台线程。单插件最多每 10 秒发送 12 条群消息,群命令与游戏通知共用额度;超出时丢弃,原有群事件限流仍生效。冷却记录最多 10000 项,满时暂时跳过新事件。
扩展页面只在打开时刷新,正在编辑设置时暂停刷新,不覆盖输入内容。插件管理使用现有本地 CSS、系统字体和响应式布局,无新增前端依赖。
管理 API
以下接口都需要 Authorization: Bearer <面板管理令牌或具备 plugins.manage 权限的团队会话令牌>。不要把令牌放在 URL 中。所有读取响应禁止缓存。
| 方法 | 路径 | 用途 |
|---|---|---|
| GET | /api/extensions | 获取插件列表、设置与 revision |
| POST | /api/extensions/install | 导入,JSON 正文为 { "revision": "...", "plugin": { ...完整插件... } } |
| POST | /api/extensions/upgrade | 更新同 ID 插件,正文 { "revision": "...", "plugin": { ...新版本... } } |
| GET | /api/extensions/<id>/versions | 获取可回退的版本元信息 |
| POST | /api/extensions/<id>/rollback | 回退,正文 { "revision": "...", "version_id": "..." } |
| POST | /api/extensions/scan | 重新扫描,正文 { "revision": "..." } |
| PUT | /api/extensions/<id> | 保存,正文包含 revision,可带 enabled、完整 settings 及 permissions 对象 |
| POST | /api/extensions/<id>/reload | 重新读取单个插件,正文 { "revision": "..." } |
| DELETE | /api/extensions/<id> | 归档停用插件,正文 { "revision": "..." } |
| GET | /api/extension-documents/guide | 下载本开发文档 |
| GET | /api/extension-documents/example | 下载完整示例 |
写入成功返回最新列表与 revision;后续写入必须使用新的 revision。401 表示令牌错误或管理会话过期,403 表示团队会话缺少 plugins.manage,400 表示定义/设置非法,404 表示插件不存在,409 表示设置版本冲突,500 表示文件写入失败。不要循环重试写入,应先读取最新状态。团队权限设置见 团队管理。
发布前验证
- 检查 ID、文件名、默认值、数值范围和模板变量。
- 在测试群启用插件,分别验证精确匹配、带参数命令和权限不足时的提示。
- 打开设置,修改每项设置,保存后检查回复内容。
- 确认重复消息不会重放、冷却期间不连发。
- 停用插件后确认不再处理命令;重启后确认启用选择和设置保留。
- 如包含进退服规则,使用真实游戏事件检查群通知,并确认是否需要关闭内置通知。
主程序测试:
powershell
.\.venv\Scripts\python.exe -m unittest discover -s tests -v测试中的 OneBot 发送为模拟对象,不向真实 QQ 群发送消息。
插件版本更新与回退
可在插件 JSON 顶层添加 changelog(最多 2000 字),作为纯文字更新说明。导入同 ID、不同版本的文件时,面板显示旧/新版本及说明,确认后更新;无需先移除旧插件。相同版本号拒绝覆盖,请为新版本填写不同的 version。
更新保留兼容的设置及权限,新字段采用默认值、已不兼容的字段恢复新默认值;更新后保持停用,请检查后手动启用。每个插件最多保存 5 个旧版本,全局最多 150 个。列表「版本与回退」可查看历史并回退定义、设置和权限,回退后同样保持停用。更新写入失败会恢复原定义和状态;历史记录在全部写入成功后保存。
管理 API:POST /api/extensions/upgrade 接受 {plugin, revision};GET /api/extensions/{id}/versions 返回历史元信息;POST /api/extensions/{id}/rollback 接受 {version_id, revision}。只支持原有声明式 JSON,不运行插件脚本、不自动从第三方仓库下载,也不会把修改的权限直接放开。