仰望星辰工作室

clearlove2.1

clearlove2.1/ docs/PLUGIN.md 9.5 KB · 256 行 原始文件
1# ClearLove 插件开发文档
2
3插件用于在不修改表白墙源码的前提下扩展功能。插件是**声明式**的:一个 zip 包 + 一份 `plugin.json`,
4无需编译、无需服务端代码,安装后由表白墙内核解释执行,因此可以安全地在插件市场分发。
5
6---
7
8## 1. 插件包结构
9
10```
11your-plugin.zip
12├── plugin.json # 必需:插件清单(放在根目录或任意子目录均可)
13└── (可选)其他静态资源
14```
15
16打包要求:
17
18- 必须是 zip 格式,`plugin.json` 需为 **UTF-8** 编码
19- 插件名(`name`)会被用作目录名,建议使用中文或英文短名,避免 `/`、`\` 等字符
20- 单包不超过 50MB
21
22安装方式:
23
24| 方式 | 操作 |
25|---|---|
26| 后台上传 | 后台「插件管理 → 安装插件」选择 zip → 上传并安装 |
27| 插件市场 | 后台「插件商店」中一键安装(自动下载并校验 SHA256) |
28| 手动部署 | 解压到 `data/plugins/<插件名>/` 后刷新后台插件列表 |
29
30安装后需在「插件管理」中点击**启用**才会生效。
31
32---
33
34## 2. plugin.json 完整字段
35
36```json
37{
38 "name": "插件名(必需,唯一)",
39 "version": "1.0.0",
40 "author": "作者",
41 "description": "一句话说明",
42 "requires": "2.0.0",
43 "config": [ ... ],
44 "hooks": [ ... ]
45}
46```
47
48| 字段 | 必填 | 说明 |
49|---|---|---|
50| `name` | ✅ | 插件名,同时作为安装目录名 |
51| `version` | | 版本号,展示用 |
52| `author` | | 作者名 |
53| `description` | | 简介,展示在插件列表与插件市场 |
54| `requires` | | 建议的最低表白墙版本(仅作展示提示) |
55| `config` | | 配置项声明,见第 3 节 |
56| `hooks` | ✅ | 钩子列表,见第 4 节 |
57
58---
59
60## 3. 配置项(config)
61
62插件可以声明若干配置项,表白墙会**自动在后台「插件管理 → 插件设置」渲染表单**,
63管理员填写后立即生效,无需重新安装插件。
64
65```json
66"config": [
67 { "key": "nicknames", "label": "专享昵称", "type": "textarea",
68 "default": "官方,公告", "help": "多个昵称用逗号或换行分隔" },
69 { "key": "badge", "label": "帖子标识", "type": "text", "default": "官方" },
70 { "key": "enable", "label": "启用提示", "type": "switch", "default": "1" },
71 { "key": "position", "label": "显示位置", "type": "select",
72 "default": "bottom", "options": ["top", "bottom"] }
73]
74```
75
76| 字段 | 说明 |
77|---|---|
78| `key` | 字段名,供 `{config:key}` 引用 |
79| `label` | 后台表单里显示的名称 |
80| `type` | `text`(单行)/ `textarea`(多行)/ `switch`(开关,值为 `1`/`0`)/ `select`(下拉)/ `number` |
81| `default` | 未配置时的默认值 |
82| `help` | 表单下方的说明文字 |
83| `options` | 仅 `select` 使用,候选项数组 |
84
85### 在钩子里引用配置
86
87任意字符串字段都支持 `{config:字段名}` 占位符,运行时会被替换为管理员填写的值:
88
89```json
90{ "hook": "compose_guard", "type": "guard",
91 "nicknames": "{config:nicknames}",
92 "label": "{config:badge}" }
93```
94
95配置值保存在数据库 `settings` 表(键名 `plugin.<插件名>.<字段名>`),随站点一起备份。
96
97---
98
99## 4. 钩子一览
100
101`hooks` 是一个数组,每个元素至少包含 `hook` 与 `type`:
102
103| type | hook | 作用 | 关键字段 |
104|---|---|---|---|
105| `html` | `header_html` | 前台页面 `<head>` 后注入 HTML | `html` |
106| `html` | `footer_html` | 前台页面底部注入 HTML | `html` |
107| `html` | `admin_plugins_top` | 后台「插件管理」页顶部注入 HTML | `html` |
108| `filter` | `content_filter` | 用正则改写帖子 / 评论内容 | `match`、`replace` |
109| `http` | `post_created` | 发帖成功后回调 Webhook | `url` |
110| `http` | `comment_created` | 评论后回调 Webhook | `url` |
111| `http` | `report_created` | 举报后回调 Webhook | `url` |
112| `guard` | `compose_guard` | **发帖前置守卫**:命中昵称时强制验证后台账号 | `nicknames`、`require`、`label`、`message` |
113| `badge` | `post_badge` | 给指定昵称的帖子打上标识 | `nicknames`、`label` |
114
115> Webhook 以 `POST` + JSON 发送,请求头带 `X-ClearLove-Event`,超时 10 秒,失败只记录日志、不影响发帖。
116
117### html 钩子示例
118
119```json
120{ "hook": "footer_html", "type": "html",
121 "html": "<div class='daily-quote'>今天也要加油鸭</div>" }
122```
123
124注入的 HTML 会被原样输出到页面,因此**可以包含 `<style>` 与 `<script>`** —— 这也是插件实现
125自定义交互(弹窗、动效、统计)的主要方式。请勿注入恶意代码。
126
127### filter 钩子示例
128
129```json
130{ "hook": "content_filter", "type": "filter", "match": "广告|加群|代刷", "replace": "***" }
131```
132
133`match` 是 Go 正则表达式,对所有发帖与评论内容生效(插件启用后 30 秒内自动热加载)。
134
135### http 钩子示例
136
137```json
138{ "hook": "post_created", "type": "http", "url": "https://example.com/hook" }
139```
140
141回调体包含事件名与业务字段,例如发帖回调:
142
143```json
144{ "event": "post_created", "post_id": 12, "nickname": "匿名", "content": "...", "time": "2026-09-12T15:00:00Z" }
145```
146
147---
148
149## 5. guard:发帖守卫(需要验证后台账号)
150
151`compose_guard` 用于**防止他人冒充官方身份**:当发帖昵称命中名单时,
152表白墙会在提交前弹出「管理员身份验证」弹窗,要求输入后台管理员账号与密码,
153**服务端校验通过后才会发布**(不通过直接拒绝,无法绕过),并可给帖子打上标识。
154
155| 字段 | 说明 |
156|---|---|
157| `nicknames` | 触发的昵称名单,逗号 / 分号 / 换行分隔,支持 `{config:key}` |
158| `require` | `admin` = 必须验证后台管理员账号密码;留空表示仅打标识、不校验 |
159| `label` | 校验通过后写入帖子的标识文字(前台显示为昵称后的彩色徽章) |
160| `message` | 校验失败时返回给用户的提示语 |
161
162```json
163{
164 "hook": "compose_guard",
165 "type": "guard",
166 "nicknames": "官方,公告板",
167 "require": "admin",
168 "label": "官方",
169 "message": "该昵称为官方专享,请验证管理员账号后发布"
170}
171```
172
173行为说明:
174
175- 前台发帖页会在昵称命中时**自动弹出验证弹窗**(昵称名单由插件配置实时提供)
176- 表单发帖(`/compose`)与 API 发帖(`POST /api/v1/posts`)都会强制校验
177- API 发帖需在 JSON 中额外提供 `admin_user` 与 `admin_pass`
178- 同一 IP 连续失败 5 次会被锁定 10 分钟,防止暴力破解后台密码
179- 多个插件同时命中时,标识会合并、校验要求取并集
180- 通过验证的帖子会同时带上内置的「**管理员**」标识(表示发布者已验证为管理员),
181 插件自定义的 `label` 会追加在后面,例如 `["管理员", "官方认证"]`
182
183### badge:帖子标识(无需验证)
184
185只想给某些昵称的帖子加个标记时使用,不涉及验证:
186
187```json
188{ "hook": "post_badge", "type": "badge", "nicknames": "小编,编辑", "label": "编辑" }
189```
190
191标识在发帖时写入帖子记录,**不随插件卸载而消失**(已发布的历史帖子仍保留标识)。
192
193---
194
195## 6. 完整示例:官方身份守卫插件
196
197`plugin.json`:
198
199```json
200{
201 "name": "官方身份守卫",
202 "version": "1.0.0",
203 "author": "yourname",
204 "description": "使用指定昵称发帖时必须验证后台管理员账号,帖子显示自定义标识,防止冒充官方身份",
205 "requires": "2.0.0",
206 "config": [
207 { "key": "nicknames", "label": "专享昵称", "type": "textarea", "default": "官方,公告",
208 "help": "使用这些昵称发帖时需验证后台账号,多个用逗号或换行分隔" },
209 { "key": "badge", "label": "帖子标识", "type": "text", "default": "官方",
210 "help": "验证通过的帖子在昵称后显示的徽章文字" },
211 { "key": "message", "label": "失败提示", "type": "text",
212 "default": "该昵称为官方专享,请验证管理员账号后发布" }
213 ],
214 "hooks": [
215 { "hook": "compose_guard", "type": "guard",
216 "nicknames": "{config:nicknames}",
217 "require": "admin",
218 "label": "{config:badge}",
219 "message": "{config:message}" },
220 { "hook": "footer_html", "type": "html",
221 "html": "<style>.post-badge{box-shadow:0 1px 6px rgba(255,123,169,.45)}</style>" }
222 ]
223}
224```
225
226打包与安装:
227
228```bash
229zip -r official-guard.zip plugin.json
230```
231
232上传到后台「插件管理 → 安装插件」→ 启用 → 在「插件设置」里填写专享昵称即可。
233
234> 表白墙内置了「管理员专享昵称」(网站设置),覆盖最常见的官方身份保护场景;
235> 这个插件演示的是如何用插件实现同类能力,并支持自定义标识文字与多插件组合。
236
237---
238
239## 7. 发布到插件市场
240
2411. 在插件社区注册开发者账号(邮箱验证):<https://clearlove.kazx.top/dev/register>
2422. 开发者后台「发布插件」上传 zip,填写分类、说明与标签
2433. 管理员审核上架后,所有站点都能在后台「插件商店」中一键安装
2444. 之后可在开发者后台查看下载量与安装量,并上传新版本
245
246---
247
248## 8. 调试建议
249
250| 场景 | 建议 |
251|---|---|
252| 改了 plugin.json 不生效 | 插件清单每次请求都会重新读取磁盘,但 `content_filter` 规则有 30 秒缓存 |
253| 配置改了没生效 | 配置存在 `settings` 表并带内存缓存,保存后立即刷新,无需重启 |
254| 钩子没触发 | 确认插件已在「插件管理」中**启用**(安装 ≠ 启用) |
255| 前台注入的 JS 报错 | 打开浏览器控制台查看;注入内容会在渲染时直接输出,注意转义引号 |
256| 想看当前插件与配置 | 后台「插件管理」页可查看全部插件、状态与配置表单 |