跳至主要內容

开发规范

YunzaiDocs2026/1/21大约 11 分钟

注意

本章仅代表个人观点并使用ai辅助生成,仅供参考。

您可以选择性遵守或不遵守

本章用于约定插件的开发方式、结构规范与行为约束,以保证插件生态的稳定性、可维护性与跨框架兼容性。所有第三方插件开发者在编写插件前,均应仔细阅读并遵守本规范。

基本原则

  • 插件应遵循单一职责原则,避免将多个无关功能耦合在同一个插件中
  • 插件不得依赖 Yunzai 的内部实现细节,仅允许使用公开 API
  • 插件应保证在异常情况下不会影响 Yunzai 或其他插件的正常运行
  • 插件不得假设运行环境的具体实现 (如依赖TRSS-Yunzai特性)

免责声明

强烈建议每个将代码上传至开源平台的开发者都在README中添加明确的免责声明,以规避潜在及不必要的风险。

插件许可要求 重要

如果你的插件需要发布到Git平台(如Github、Gitee等),请仔细阅读此部分内容。

长久以来绝大多数插件开发者都不清楚或者不明确自己的项目应该使用何种开源协议,选择正确的开源协议能够有效保证开发者的权益。

Yunzai 采用 GPL-3.0 许可证。

  • 如果您的插件以类/模块形式在本进程中被加载,或直接 import/引用本框架的内部实现、全局对象或相对路径模块,则该插件应以 GPL-3.0 或与 GPL-3.0 兼容的许可证发布(因为这类插件通常被视为对本项目的衍生作品)。
  • 如果您的插件以独立进程、外部服务或明确的 IPC/网络协议与 Yunzai 通信,并在技术上与 Yunzai 保持“独立程序”边界,那么插件可以使用不同的许可证(GPL-3.0 以外),但插件作者需自己评估与遵守相关法律义务。

提示

通常情况下,所有放置于 Yunzai 的 plugins 目录下的插件都被视为其衍生插件,都应当使用 GPL-3.0 协议并开源

只有当你的插件与Yunzai完全分离才可以自行选择协议,比如使用OneBot协议通信等。

换句话说,只要你编写的是传统意义上的Yunzai插件,就必须遵循GPL-3.0协议,不论是单js插件还是plugins,都必须使用此协议开源。

拓展:为什么 In-process 插件需要沿用 GPL-3.0?

Yunzai采用的 GPL-3.0 许可证,其中一个重要特性是其“传染性(Copyleft)”。

什么是 GPL 的传染性?

简单来说,当你的代码不是独立运行,而是:

  • 直接引用(import / require)了 GPL 项目的代码

  • 与 GPL 项目在同一进程中运行

  • 使用了 GPL 项目提供的内部 API、数据结构或全局对象

那么从法律角度,这部分代码通常会被视为对 GPL 项目的衍生作品(Derivative Work)。
根据 GPL-3.0 的要求,衍生作品在分发时需要使用 GPL-3.0 或与其兼容的许可证。

为什么插件会被视为衍生作品?

在本框架中,大多数插件:

  • 以模块形式被加载进 Yunzai 的运行进程

  • 依赖 Yunzai 提供的事件对象、上下文对象和运行环境

  • 与 Yunzai 的内部实现存在紧密耦合

这类插件在技术和功能上都难以被视为“独立程序”,因此通常需要沿用 GPL-3.0。

这样做的目的是什么?

  • 保障 Yunzai 与插件生态的自由与开放

  • 防止在核心能力之上构建闭源、不可审计的扩展

  • 确保社区贡献的代码可以被持续维护、改进与回馈

是否存在不受 GPL 传染性的插件形式?

有。如果插件通过独立进程、外部服务或明确的 IPC / 网络协议与 Yunzai 通信,并且不直接引用 Yunzai 的源码或内部对象,这类插件通常可以被视为独立程序,其许可证可以不受 GPL-3.0 约束。

本项目会在文档中明确区分不同插件类型,并说明各自的许可要求,帮助开发者在合规的前提下自由选择实现方式。


插件在 package.json 中应声明 license 字段并在 README 中明确许可条款,便于用户与审核。

禁止行为

Yunzai 在项目README中写到 “项目仅供学习交流使用,严禁用于任何商业用途和非法行为” ,因此首先便是:

  • 禁止用于商业用途。
  • 禁止触犯法律法规的行为。

其次便是开源社区的禁止行为:

太长了,展开看看
  1. 违反许可(license)条款

    • 例:将未授权的闭源代码合并到 GPL 项目中,或在提交中替换/移除版权声明。
    • 原因/后果:导致项目面临版权诉讼或必须回滚/重写代码。
  2. 发布或传播侵权内容(未经授权的第三方版权、专利侵权)

    • 例:上传盗版库、复制粘贴他人闭源实现并声称为己有。
  3. 提交含有机构/个人敏感信息(侵犯隐私或泄露商业机密)

    • 例:在 PR 中误提交客户数据、包含第三方未授权的私人信息。
  4. 提交恶意代码 / 后门 / 恶意脚本

    • 例:植入远程控制、键盘记录、矿工等。
    • 原因/后果:会被立即移除并封禁贡献者账号,可能需法律处理。
  5. 提交或上传明文凭证、私钥、令牌等敏感凭据

    • 例:把 AWS 密钥、数据库密码写进代码或示例配置。
  6. 公开未授权的安全漏洞(不按负责披露流程)

    • 例:直接在 Issues 或公开渠道公布可被滥用的漏洞细节。
    • 建议:设立 SECURITY.md 与负责披露流程(给时间窗口),鼓励私下报告。
  7. 骚扰、歧视或仇恨言论

    • 包括基于性别、性取向、种族、宗教、国籍等的人身攻击
    • 不论发生在 Issue、PR Review 还是讨论区,均不被允许
  8. 人身攻击、造谣或人肉搜索

    • 禁止公开或暗示他人的私人信息
    • 禁止威胁、恐吓或引导他人实施攻击行为
  9. 垃圾信息与广告行为

    • 在 Issue、PR、讨论区发布广告、推广链接、无关内容
    • 恶意刷屏或重复发布相同内容
  10. 伪造贡献、篡改作者信息

    • 包括冒充他人身份提交代码
    • 篡改 commit 作者、署名或贡献记录
  11. 绕过项目协作流程

    • 强行向受保护分支 push
    • 绕过 Code Review、CI 检查合并代码
  12. 发布误导性插件或仓库

    • 冒充官方插件、使用极其相似的名称误导用户
    • 在插件中隐藏恶意或未声明行为
  13. 滥用仓库存储

    • 提交大型二进制文件、构建产物、数据库 dump
    • 明显不符合源码仓库用途的内容
  14. 滥用自动化工具或机器人

    • 使用 Bot 批量刷 Issue / PR
    • 自动合并未经审查的代码
  15. 违反法律法规或平台规则

    • 包括传播违法内容、非法工具、受管制信息等
  16. 传播危险或高风险内容

    • 提供制造、获取危险物品的详细步骤或教程
    • 鼓励或协助高风险、违法行为

然后就是 Yunzai 社区的约定俗成

  1. 禁止倒卖行为(以任何形式售卖Yunzai或插件)
  2. 禁止未经允许抄袭/照搬他人代码
  3. 禁止未经允许抄袭他人的创意
  4. 禁止未经允许将他人的插件上传至开源平台
  5. 禁止将敏感功能或闭源代码写入插件并开源
  6. 禁止利用Yunzai及其插件违法犯罪黑灰产业等行为

为什么遵守这些规范

以下内容摘自karin文档

这些规范的核心在于倡导 君子协议,建立信任和合作的基础。通过遵守这些规范,我们可以:

  • 创建一个良好的社区环境
  • 增强用户与开发者的信心。
  • 推动社区在透明、安全与创新的环境中发展。
  • 维护 karin Yunzai 生态的健康与稳定。

插件目录结构

每个插件应作为一个独立目录存在,其基本结构如下:

name-plugin/
├─ package.json
├─ apps/
│  └─ xxx.js
├─ config/
│  └─ default.yaml
├─ resources/
├─ index.js
└─ README.md

说明:

名称描述
package.json用于声明插件的基本信息与依赖
apps用于存放具体的功能实现
config插件内部的配置目录,通常有default_config
resources插件静态资源存放目录
index.js作为插件入口文件,集中导出apps的功能模块

插件不得导入或引用其他插件的功能及模块

插件命名参考

插件命名应当采用统一且方便记忆不容易造成混淆的形式

推荐的命名格式:

  • Yunzai-XXX-Plugin: 字母大写 + Yunzai前缀风格,如: Yunzai-TRSS-Plugin、Yunzai-DF-Plugin等
  • XXX-Plugin: 字母大写风格,如: TRSS-Plugin、DF-Plugin 等
  • xxx-plugin: 小写风格, 如: miao-plugin、yenai-plugin 等

不推荐:

  • abc-abc-xxx
  • aaabbc-aa
  • abc-12345
  • abc_123
  • abc_123@plugin

插件元信息规范

我们推荐每个插件都有一个 package.json 并声明以下字段:

{
  "name": "example-plugin",
  "version": "1.0.0",
  "description": "示例插件",
  "author": "作者名称",
  "dependencies": {
    "axios": "^x.x.x"
  },
  "devDependencies": {
    "eslint": "^x.x.x"
  }
}

字段说明:

字段名称说明
name插件名称,不得与其他插件重复,采用纯小写
version插件版本号,必须遵循语义化版本规范
description插件描述,简要描述一下插件
author作者名称,需是字符串但可用英文逗号分隔
dependencies插件所需的依赖,不得与Yunzai已有的依赖项重复
devDependencies开发环境依赖,非常不建议携带进用户的生产环境中

插件生命周期

插件在运行过程中将经历以下生命周期阶段:

  1. 启动时加载模块,用于注册监听事件与定时任务
  2. 初始化完成后调用方法

开发者应注意:

  • 在启动阶段不应执行阻塞性操作,如果一定要在启动时进行应当使用 异步立即执行函数(Async IIFE)
  • 插件应当在启动阶段就完整事件监听和定时任务加载

配置与数据管理

任何由插件产生的文件都应当遵守此规范

现在关于数据存放位置存在两种形式

  1. 数据与配置存放于插件私有目录下
  2. 数据与配置存放于Yunzai共有目录下

综合考量两者,1更偏向于用户卸载方便无残留,2更偏向于用户在生产环境中无需访问插件私有目录翻找文件。

TRSS推荐使用2,将配置等数据存放于Yunzai下的dataconfig目录下集中管理,以下详细说明。

开发者应做到让用户在生产环境中无需查找插件本身的任何目录或文件

  • 插件配置文件
    • 单个文件存放于 Yunzai/config/{PluginName}.yaml
    • 多个文件存放于 Yunzai/config/{PluginName}/xxx.yaml
  • 插件数据
    • 存放于 Yunzai/data/{PluginName}/*,所有数据都必须位于该文件夹下
  • 插件资源
    • 如果是随插件而来的静态资源通常放置于插件目录下
    • 如果是生成的或者是安装后下载的则放置于Yunzai/resources/{PluginName}/*
  • 临时文件
    • 放置于 Yunzai/temp/{PluginName}/*

错误处理与日志

  • 插件应自行捕获可预期的运行时异常
  • 未捕获异常可能导致影响其他插件及功能的正常响应
  • 插件日志应统一使用 Yunzai 提供的日志接口(Logger)
  • 不建议在正式环境中使用 console.log 进行调试输出
  • 日志输出应当进行分级
    • trace: 用于精确定位问题,比debug更细致
    • debug: 调试信息,给开发者看的细节信息
    • info: 正常运行的提示信息
    • mark: 插件的处理信息,指令或者功能处理的标记
    • warn:不严重但值得注意的问题
    • error:已经出错,需要修

跨框架兼容性要求

为了支持 Miao-Yunzai 与 TRSS-Yunzai 或其他框架,插件开发需遵循以下约定:

  • 插件不得直接引用具体框架的对象或 API
  • 插件仅能使用框架提供的上下文、消息与事件模型
  • 插件不应假设消息结构、用户模型的具体实现

具体表现为:在调用框架独有方法或属性前进行判断,使用简单兼容性工具兼容其他框架,不使用某个协议端特殊的方法或字段

更新日志

2026/1/21 00:11
查看所有更新日志
  • 8ef73-add development guidelines and plugin structure documentation

贡献者