跳转到主要内容
Manifest headers 是插件文件顶部的注释声明。autClaw 读取这些声明来显示插件信息、匹配消息、生成配置表单、安装依赖和注册路由。
普通插件作者只需要关注本页字段。连接新 IM 平台所需的接入字段不在这里展开。

基本写法

//[author: your-name]
//[runtime: [email protected]]
//[title: Hello]
//[description: 回复 hello]
//[rule: hello]
const { Sender, getSenderID } = require('./middleware.js')

const sender = new Sender(getSenderID())
await sender.reply('hello')

解析规则

  • JavaScript 使用 //[key: value]
  • Python 使用 #[key: value]
  • 声明必须放在文件顶部的连续注释区;遇到第一行非注释代码后,后面的声明不会作为头部声明读取。
  • key 不区分大小写,建议统一写小写。
  • author 必填。缺少 author 时插件会被标记为 manifest 无效。
  • 大多数字段重复时采用最后一个值;ruleeventmethodparamdependency 和选择器字段可以重复。
  • 布尔值支持 true/false1/0yes/no

常用字段

Header必填示例作用
authoryour-name插件作者。建议使用稳定英文或拼音标识。
title订单查询展示名称。
description按订单号查询状态简短说明,让用户知道插件能做什么。
version1.0.0插件版本。
runtime[email protected][email protected]指定运行环境。
languagejavascriptpython通常可由文件扩展名自动识别。
class工具分类或展示分组。
iconbot展示图标。
disabletrue禁用插件。
admintrue仅管理员可触发。
priority10触发优先级,数字越高越优先。

消息触发:rule

rule 用来匹配用户消息。你可以写多个 rule
//[rule: hello]
//[rule: 查询 (.+)]
正则捕获的内容可以通过 sender.param(1) 读取。
//[rule: 查询 (.+)]
const { Sender, getSenderID } = require('./middleware.js')
const sender = new Sender(getSenderID())
const keyword = await sender.param(1)
await sender.reply(`你要查询:${keyword}`)

事件和定时触发

Header示例作用
eventqq-notice-group_decrease-kick监听事件。插件内用 getEventType() / getEventData() 读取事件信息。
cron0 9 * * *定时触发插件。
cron 只能写一次。支持常见 5 段表达式,也支持带秒的表达式和 cron 描述符。
// 每天 9 点触发
//[cron: 0 9 * * *]

触发范围

用选择器限制插件在哪些 IM、用户或群里生效。
//[imtype+: qq,wx]
//[groupid+: 123456]
//[userid-: 10001,10002]
Header模式说明
imtype / imtype+允许名单只允许指定 IM 渠道触发。
imtype-排除名单排除指定 IM 渠道。
userid / userid+允许名单只允许指定用户触发。
userid-排除名单排除指定用户。
groupid / groupid+允许名单只允许指定群或会话触发。
groupid-排除名单排除指定群或会话。
同一类选择器同时写允许名单和排除名单时,按允许名单处理。建议不要混用。

配置参数:param

param 用 JSON 声明配置项。每一行声明一个配置项。
//[param: {"key":"api_key","name":"API Key","type":"secret","required":true,"placeholder":"sk-..."}]
//[param: {"key":"enabled","name":"启用","type":"boolean","default":true}]
//[param: {"key":"mode","name":"模式","type":"select","options":["fast","safe"],"default":"safe"}]
//[param: {"spliter":true,"name":"高级设置"}]
字段必填说明
key配置键。spliter: true 的分隔项不需要。
name展示名称;不填时使用 key
desc配置说明。
placeholder输入框占位提示。
required是否必填。
typestringbooleannumbersecretselect。默认 string
secret设为 true 时按密钥类型处理。
default默认值。
optionsselect 的选项。
scopeglobalaccount。默认 global
bind当前支持 ingress_token
spliter分隔标题,用来组织配置表单。

依赖:dependency

dependency 提前声明插件需要的包。每一行是一个 JSON 对象。
//[dependency: {"name":"axios","manager":"npm","version":"1.7.9"}]
#[dependency: {"name":"httpx","manager":"pip","version":"0.27.2"}]
字段必填说明
name包名。
manager包管理器,例如 npmpipgo
version版本号。
也可以在代码里按需导入:JavaScript 使用 importModule(...),Python 使用 import_module(...)

HTTP 路由插件

声明 router 后,插件可以处理 HTTP 请求。
//[author: your-name]
//[runtime: [email protected]]
//[title: Demo API]
//[router: /demo/{id}]
//[method: post]
const { Sender, getSenderID } = require('./middleware.js')

const sender = new Sender(getSenderID())
const params = await sender.getRouterParams()
const body = await sender.getRouterBody()
await sender.response({ ok: true, id: params.id, body })
Header示例说明
router/demo/{id}公开路由路径,必须以 / 开头。
methodgetpost请求方法。可重复,也可用逗号分隔。支持 getpostputdelete
serverdemo服务分组名称,可选。
不要使用 /api/open/healthz 作为路由前缀。

Marketplace 字段

如果你要公开发布插件,可以补充这些字段。
//[public: true]
//[open_source: false]
//[price: 9.90]
//[billing_mode: monthly]
//[monthly_price: 3.00]
//[auto_renew_default: true]
Header示例说明
publictrue是否公开展示。
open_sourcefalse是否公开代码内容。
pintrue是否置顶。
price9.90一次性价格,非负,最多两位小数。
billing_modeone_time / monthly收费模式。
monthly_price3.00月付价格,非负,最多两位小数。
auto_renew_defaulttrue默认是否自动续费。

完整示例

//[author: demo]
//[runtime: [email protected]]
//[title: 领卡]
//[description: 用户发送 claim-card 后领取一次卡密]
//[version: 1.0.0]
//[rule: claim-card]
//[admin: false]
//[priority: 10]
//[param: {"key":"period_limit","name":"周期限制","type":"number","default":1}]
//[dependency: {"name":"dayjs","manager":"npm"}]
const { Sender, getSenderID, bucketGet, bucketSet } = require('./middleware.js')

const sender = new Sender(getSenderID())
const user = await sender.getUserID()
const claimed = await bucketGet('card_claims', user)

if (claimed) {
  await sender.reply('你已经领取过了')
  return
}

await bucketSet('card_claims', user, String(Date.now()))
await sender.reply('领取成功')

机器可读文件

Last modified on June 3, 2026