# Autman 插件开发规则与仓库约定 > 来源:已参考 BOSS 上传到本仓库的插件示例,以及 autMan 官方论坛教程:。重点参考帖子:插件编写规则、插件编程-头注篇、插件编写概论、微服务插件编写、Python 简单插件编写、消息类型说明、实时 IM 消息监听、适配器插件编写指南。 ## 1. 仓库用途 本仓库统一存放 BOSS 的 Autman 插件、参考示例、文档和模板。以后新增插件优先按下面目录组织: ```text js/ # ECMAScript5 / 内置 JS 插件,通常放 autMan plugin/replies py/ # Python 插件,通常放 autMan plugin/scripts plugins/ # 我们新写的正式插件;按功能再分目录或命名 examples/ # 调用示例、配置示例 templates/ # 可复制的插件模板 docs/ # 规则、接口说明、研究记录 ``` 已有历史插件可保留原路径。新开发插件建议优先放到 `plugins/`,稳定后可按 Autman 实际导入目录复制到 `js/` 或 `py/`。 ## 2. 插件类型 Autman 支持多种插件/脚本形态: | 类型 | 说明 | 常见位置/用途 | |---|---|---| | HTML 插件 | 由 Autman Web 服务托管页面 | `plugin/web`,主要自用 | | ES5 插件 | Autman 内置 ES5 环境运行,内置大量函数 | `plugin/replies`,适合关键词、路由、轻量集成 | | Python/Node/TS/PHP/Shell/Go 等外部脚本 | Autman 调用宿主系统环境运行,通过 `middleware` 与 Autman 交互 | `plugin/scripts`,适合复杂逻辑、依赖第三方库 | | 微服务路由插件 | 使用 `router` / `method` 头注暴露 HTTP 接口 | 对外接收 Webhook/API 调用 | | 适配器插件 | 对接新的社交媒体/IM,将外部消息转换为 Autman 消息格式 | 需要处理 HTTP/WS 通信和消息格式转换 | 注意:除 HTML 插件外,其他插件运行通常要求 Autman 授权有效。 ## 3. 头注规则 头注必须放在插件文件头部,用于生成插件元数据和触发条件。 ### 3.1 市场/基础元数据 JS 示例: ```js //[open_source: true] //[create_at: 2026-01-01 12:00:00] //[title: 插件名称] //[author: 作者] //[service: 售后联系方式] //[class: 工具类] //[version: 1.0.0] //[platform: qq,wx,tg,tb,web] //[public: false] //[price: 0] //[disable: false] //[description: 插件说明,尽量写清楚用法] //[icon: https://example.com/icon.png] ``` Python 示例: ```python # [title: 插件名称] # [language: python] # [service: 售后联系方式] # [disable: false] # [admin: true] # [rule: ^指令$] # [platform: qq,wx,tg,tb] # [open_source: true] # [version: 1.0.0] # [public: false] # [price: 0] # [description: 插件说明] ``` 字段说明: | 字段 | 说明 | |---|---| | `title` | 插件标题 | | `author` | 作者 | | `service` | 售后/联系方式;上架通常必填 | | `class` | 分类,如工具类、查询类、娱乐类、生活类、图片类等 | | `platform` | 适用平台,多个用英文逗号分隔 | | `public` | 是否公开显示到市场;开发测试建议 `false` | | `disable` | `true` 禁用,`false` 启用 | | `version` | 版本号 | | `price` | 价格 | | `description` | 说明,建议写清楚指令、参数、注意事项 | | `icon` | 图标 URL,建议 48px 正方形,支持 http/https | ### 3.2 关键词/命令触发 ```js //[rule: ^菜单$] //[rule: ^菜单管理$] //[admin: true] //[priority: 300] //[cron: 0 7 * * *] //[bypass: false] ``` 规则: - `rule` 支持正则,可写多行表示多个触发规则。 - `cron` 支持 5 位或 6 位 cron 表达式。 - `admin: true` 表示仅管理员可执行。 - `priority` 数字越大优先级越高。 - `bypass: true` 常用于全拦截规则,例如 `[rule: ?]`,表示旁路并行处理。 - 可用 `imType+` / `imType-`、`userId+` / `userId-`、`groupId+` / `groupId-` 做白名单/黑名单。 示例: ```js //[rule: ^sim状态$] //[rule: ^sim短信\s+(.+?)\s+([\s\S]+)$] //[admin: true] //[platform: qq,wx,tg,tb] //[priority: 100] ``` ### 3.3 微服务路由触发 微服务插件通过 HTTP 路由触发,新增/修改这类插件后通常需要重启 Autman 才生效。 ```js //[router: /simadmin/status] //[method: get] //[method: post] ``` 规则: - `router` 路径必须以 `/` 开头。 - `method` 可写多个,常见为 `get`、`post`,也可支持 `put/delete`。 - GET 参数从 `getRouterParams()` 取。 - POST body 从 `getRouterData()` / `getRouterBody()` 取。 - 最终必须用 `response(obj)` 或兼容方式返回,避免请求挂起。 ### 3.4 配参头注 用于让 Autman 后台渲染插件配置项。 ```js //[param: {"required":true,"key":"otto.simadmin_base_url","bool":false,"placeholder":"http://192.168.1.10:3000","name":"SimAdmin地址","desc":"不要以 / 结尾"}] //[param: {"required":true,"key":"otto.simadmin_token","bool":false,"placeholder":"访问Token","name":"接口鉴权Token","desc":"外部请求必须携带 access_token"}] //[param: {"required":false,"key":"otto.simadmin_push_master","bool":true,"placeholder":"","name":"是否推送管理员","desc":""}] //[param: {"spliter":true}] ``` 约定: - `key` 建议使用统一前缀,例如 `otto.simadmin_xxx` 或 `otto.<插件名>_xxx`。 - 密钥/token 不要写死在源码里,放到配参或环境变量。 - `bool: true` 用于开关项。 - `required` 只表示配置 UI 要求,不等于运行期一定存在;代码里仍需校验。 ## 4. 常见平台/消息类型 论坛中整理的常见类型: | 类型 | 含义 | |---|---| | `qq` | QQ 框架 | | `qb` | QQ 频道机器人 | | `wx` | 微信外接框架 | | `wb` | 内置微信机器人 | | `tg` | Telegram 客户端 | | `tb` | Telegram 官方机器人 | | `wm` | 微信订阅号 | | `wv` | 微信服务号 | | `wk` | 微信客服 | | `dd` | 钉钉机器人 | | `dc` | Discord 机器人 | | `sk` | Slack 机器人 | | `fs` | 飞书机器人 | | `kk` | Kook 机器人 | | `qh` | 群晖 Synology Chat | | `we` | 页面对话 | | `rt` | router 消息 / 微信服务插件消息 | | `terminal` | 交互模式终端对话 | ## 5. ES5 插件内置函数与用法 ### 5.1 基础信息 ```js var name = call("name")() var port = call("port")() var version = call("version")() var machineId = call("machineId")() var id = call("uuid")() var sign = call("md5")("text") var now = call("timeFormat")("yyyy-MM-dd hh:mm:ss") var textTime = call("unixTimeFormat")(second, nanosecond, "yyyy-MM-dd hh:mm:ss") var ok = cancall("someFunc") var coffeeOk = coffee() ``` ### 5.2 消息上下文 常见函数/对象: ```js var content = GetContent() var is_admin = isAdmin() sendText("回复文本") var msg = input() // 等待用户输入,适合交互式插件 sender.reply({ok:true, msg:"success"}) Debug("调试日志") console.log("普通日志") ``` 建议: - 管理类指令必须先判断 `isAdmin()`。 - `input()` 应处理 `null/undefined/空字符串/q退出`。 - JSON 返回优先用对象,便于 Web/API 调用方解析。 ### 5.3 数据桶 ```js bucketSet("bucket", "key", "value") var value = bucketGet("bucket", "key") bucketDel("bucket", "key") var keys = bucketKeys("bucket") ``` 约定: - 桶名和 key 统一前缀,避免和其他插件冲突。 - 从 `bucketGet` 读出的复杂对象需要 `JSON.parse`,必须 try/catch。 - 写入复杂对象用 `JSON.stringify`。 ### 5.4 获取配置参数 配参 key 形如 `otto.simadmin_base_url` 时,代码中通常按后半段读取: ```js var baseUrl = get("simadmin_base_url") var token = get("simadmin_token") ``` 实际以 BOSS 上传的插件为准:`qlck.js` 中 `key: "otto.vhook_qlck_token"`,读取为 `get("vhook_qlck_token")`。 ### 5.5 网络请求 回调风格: ```js request({ useproxy: false, url: "https://example.com/api", headers: {"Content-Type":"application/json"}, method: "post", dataType: "json", body: {a: 1}, timeOut: 10000 }, function(error, response, header, body) { // 处理结果 }) ``` 同步/直接返回风格(BOSS 上传的 `js/qlck.js` 已使用): ```js var resp = request({ url: baseUrl + "/api/health", method: "get", dataType: "json", timeOut: 10000 }) ``` 约定: - HTTP API 插件优先使用 `dataType: "json"`。 - 外部服务业务失败时不一定是 HTTP 非 200,要检查返回 JSON 内的状态字段。 - 请求外部服务前清理 URL 尾部 `/`:`baseUrl.replace(/\/+$/, "")`。 - 超时必须设置,避免插件卡死。 ### 5.6 推送消息 ```js push({ imType: "qq", groupCode: "123456", content: "群消息" }) push({ imType: "wx", userID: "user-id", content: "私聊消息" }) ``` 字段: - 群组:`groupCode` 或部分平台使用 `chatID`。 - 私聊:`userID`。 - 平台:`imType`。 ## 6. 微服务插件运行规则 官方示例提到的微服务函数: ```js getRouterPath() getRouterMethod() getRouterHeaders() getRouterCookies() getRouterParams() getRouterBody() response(obj) ``` BOSS 上传插件和论坛示例中也常见兼容函数名: ```js var method = getMethod() var params = getRouterParams() || {} var data = getRouterData() ``` 建议写法: ```js function jsonResponse(obj) { if (typeof response === "function") { response(obj) } else if (typeof sender !== "undefined" && sender.reply) { sender.reply(obj) } else { sendText(JSON.stringify(obj)) } } ``` 外部 API 插件必须注意: 1. 先做 token 鉴权,鉴权失败后立即 `return`。 2. GET/POST 都支持时,参数读取顺序建议:query 参数 -> POST JSON 覆盖。 3. POST JSON 解析必须 try/catch。 4. 对发短信、重启、开关网络等敏感操作必须管理员或 token 控制。 5. 返回统一 JSON: ```json {"ok":true,"status":"ok","retcode":0,"msg":"success","data":{}} ``` 错误: ```json {"ok":false,"status":"fail","retcode":-1,"msg":"token错误"} ``` ## 7. Python 插件规则 Python 插件通过 `middleware` 与 Autman 交互。常见头注: ```python # [title: 测试] # [language: python] # [disable: false] # [platform: qq,wx] # [rule: ^测试(.*)$] # [admin: false] # [version: 1.0.0] ``` 常见初始化: ```python import middleware sender_id = middleware.getSenderID() sender = middleware.Sender(sender_id) message = sender.getMessage() user_id = sender.getUserID() user_name = sender.getUserName() im_type = sender.getImtype() chat_id = sender.getChatID() is_admin = sender.isAdmin() ``` 回复/监听: ```python sender.reply("请输入内容,q退出") user_input = sender.listen(120000) # 毫秒 if user_input == "q": sender.reply("退出") exit(0) ``` 数据桶: ```python middleware.bucketSet("bucket", user_id, "value") value = middleware.bucketGet("bucket", user_id) middleware.bucketDel("bucket", user_id) ``` 依赖: - Python 插件可自动安装依赖,但要谨慎,避免每次运行都安装。 - 建议在代码里先 `importlib.import_module` 检测,再提示管理员安装或自动安装。 - 网络请求可用 `requests` / `aiohttp`,但要设置 timeout。 ## 8. 适配器插件要点 适配器用于接入新 IM/社交平台。官方建议: 1. 选择不冲突的 `im_type`,尽量 2 个字母,如 `tt`。 2. HTTP 回调地址一般为: ```text http://://receive ``` 3. Autman 与适配器通信的 WS 地址一般为: ```text http://://adapter ``` 4. 适配器需要把外部平台消息转换为 Autman 消息格式: ```json { "event": "message", "event_data": {}, "guild_id": "", "guild_name": "", "bot_id": "", "bot_name": "", "chat_id": "", "chat_name": "", "user_id": "", "user_name": "", "im_type": "tt", "message_id": "", "content": "消息内容" } ``` 5. Autman 返回动作格式: ```json { "aut_action": "send_msg", "aut_echo": "", "aut_params": {} } ``` 适配器要把 Autman 动作翻译成外部平台 API 调用,并在需要时回执消息 ID。 ## 9. 实时 IM 消息监听 Autman 支持本地 SSE 监听实时 IM 消息,官方接口: ```text POST /otto/msghook Accept: text/event-stream Content-Type: application/json ``` 请求 body 示例: ```json {"imtype":"qq","chatid":"11543756","userid":"282617666"} ``` 处理要点: - 仅限本地访问更安全。 - SSE 数据按行读取,关注 `event:` 和 `data:`。 - 需要处理断线重连。 - 解析 `data:` 后再做业务逻辑。 ## 10. 安全与质量约定 开发新插件时必须遵守: 1. **不要硬编码密钥**:token、cookie、API key 放配参、环境变量或本地不提交文件。 2. **外部路由必须鉴权**:尤其是发短信、推送、修改配置、重启、网络开关。 3. **鉴权失败必须 return**:避免只回复错误但继续执行后续逻辑。 4. **敏感操作默认管理员限定**:聊天指令使用 `[admin:true]` 或代码内判断。 5. **统一 JSON 返回**:便于外部系统调用和排错。 6. **请求设置 timeout**:避免 Autman 插件阻塞。 7. **兼容 GET/POST**:微服务接口可同时支持 query 和 JSON body,但 POST JSON 优先。 8. **严格校验参数**:手机号、URL、路径、开关布尔值、枚举值都要校验。 9. **日志不要打印密钥**:token/cookie/API key 必须脱敏。 10. **插件说明写清楚**:头注 description 和 README 中都要写指令、参数、示例。 ## 11. 新插件开发流程 1. 先在 `plugins//` 下写源码和 README。 2. 根据插件类型复制 `templates/` 里的模板。 3. 本地检查头注、鉴权、参数校验和错误返回。 4. 如需适配 BOSS 已有插件风格,优先参考: - `js/qlck.js`:微服务 API + 配参 + token 鉴权 + request 调外部 API。 - `py/nazha.py`:Python middleware 初始化、依赖检测、平台/用户上下文。 5. 提交前确认没有 `.env`、token、cookie、日志、运行时数据。 6. 推送后验证 raw 文件可访问。 ## 12. SimAdmin 插件专项约定 后续实现 SimAdmin 插件时建议: - 配参: - `otto.simadmin_base_url` - `otto.simadmin_access_token` - `otto.simadmin_timeout_ms` - 路由: - `/simadmin/status` - `/simadmin/sms/send` - `/simadmin/sms/list` - 聊天指令: - `sim状态` - `sim短信 <手机号> <内容>` - SimAdmin API 业务失败要检查 JSON 内 `status === "error"`。 - 发送短信必须 token 或管理员控制。 - Base URL 默认不带尾部 `/`,代码内统一 trim。 ## 13. 账号/Cookie 类插件菜单设计经验(QDReader 复盘) 最近制作 `plugins/qdreader/qdreader_sign_autman.js` 时沉淀出一套适用于账号/Cookie 管理类插件的交互与数据规则,后续新插件优先复用: ### 13.1 交互结构 - 优先做“一级菜单 + 二级编号选择”,不要堆很多平铺子命令。 - 账号管理和执行查询分离: - `xxx账号`:只做账号列表、添加/更新、详情/备注、删除、清空。 - `xxx查询`:只做最近执行情况、单账号执行情况、立即执行等执行侧动作。 - 高频输入可以保留快速通道,例如 `xxxck `,但快速通道只做快速提交,不再混入查询/导出/批量导入。 - 用户选择账号时展示编号列表,让用户回复编号;不要让用户手动复制/输入 UID。 - 添加/更新账号成功后立刻询问是否添加备注;备注修改放在账号详情里,不单独做一个割裂的备注菜单。 ### 13.2 数据结构 账号/Cookie 类插件不要把 Cookie、用户绑定、备注、执行状态混在一起,建议拆成独立 map: ```json // cookie_json { "uid": "full cookie" } // user_bind_json { "uid": "sender.getUserID()" } // remark_json { "uid": "主号" } // last_result_json { "uid": "{\"ok\":true,\"msg\":\"成功\",\"time\":\"...\"}" } ``` 这样删除、过滤、展示和权限校验更安全。 ### 13.3 数据桶 - 新插件应创建自己的 bucket,例如 `hermes_qidian`,不要所有插件都塞进 `otto`。 - 如需兼容旧数据,读顺序建议: ```text bucketGet("插件专属bucket", key) ↓ fallback get(key) ↓ fallback bucketGet("otto", key) ``` - 写入新数据时写到专属 bucket,可同时写普通 `set(key)` 保持兼容。 ### 13.4 多用户隔离 - 保存账号时绑定当前用户 ID。 - 账号列表、详情、删除、手动执行只处理当前用户绑定的账号。 - `删除全部` 只删除当前用户账号,不清空全局数据。 - cron/系统触发通常没有用户上下文,是否执行全部账号要显式传 `allUsers` 参数,并在代码和测试里说明。 ### 13.5 安全与测试 - 普通回复永远不要输出完整 Cookie;只展示脱敏 UID、备注、Cookie key 摘要或长度。 - 高风险的导出/批量导入功能默认不做,除非 BOSS 明确需要。 - Node VM 测试应模拟:`sender.reply`、`sender.listen`、`sender.getUserID`、`get/set`、`bucketGet/bucketSet`、`request`。 - 测试必须覆盖:快速提交、菜单添加、备注提示、详情改备注、编号选择删除/查询、旧 bucket 兼容、新 bucket 写入、用户隔离、手动执行只跑当前用户、cron 跑全部账号。