nonebot-plugin-fanqie-verify 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nonebot_plugin_fanqie_verify-0.4.0/PKG-INFO +242 -0
- nonebot_plugin_fanqie_verify-0.4.0/README.md +212 -0
- nonebot_plugin_fanqie_verify-0.4.0/pyproject.toml +351 -0
- nonebot_plugin_fanqie_verify-0.4.0/pyproject.toml.orig +363 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/__init__.py +49 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/config.py +136 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/core/async_utils.py +89 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/core/config.py +14 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/database/__init__.py +7 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/database/models/__init__.py +15 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/database/models/message.py +130 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/database/models/session.py +94 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/database/models/time_utils.py +10 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/database/orm_crud/__init__.py +45 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/database/orm_crud/_base.py +182 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/database/orm_crud/_bulk.py +205 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/database/orm_crud/_single.py +497 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/database/toml_store/__init__.py +35 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/database/toml_store/_helpers.py +83 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/database/toml_store/_sync.py +242 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/database/toml_store/exceptions.py +45 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/handle/__init__.py +10 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/handle/qq/__init__.py +7 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/handle/qq/adapters/__init__.py +7 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/handle/qq/adapters/onebot11/__init__.py +7 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/handle/qq/adapters/onebot11/default/__init__.py +7 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/handle/qq/adapters/onebot11/default/verification.py +1016 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/handle/qq/commands/__init__.py +7 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/handle/qq/commands/verification.py +235 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/hooks/__init__.py +14 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/hooks/adapters.py +297 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/hooks/handlers/__init__.py +15 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/hooks/handlers/api_audit.py +45 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/hooks/handlers/bot_connection.py +57 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/hooks/handlers/lifecycle.py +55 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/hooks/handlers/message_store.py +80 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/hooks/interfaces.py +49 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/migrations/1f2e3d4c5b6a_initial_schema.py +574 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/migrations/a1b2c3d4e5f6_add_review_count.py +53 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/migrations/b7c8d9e0f1a2_add_trace_id.py +82 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/repositories/__init__.py +7 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/repositories/message_store.py +362 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/services/message_store.py +199 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/services/ocr/__init__.py +49 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/services/ocr/client.py +541 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/services/ocr/errors.py +58 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/services/ocr/models.py +61 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/services/ocr/service.py +113 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/services/verification/__init__.py +105 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/services/verification/actions.py +493 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/services/verification/backfill.py +300 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/services/verification/extractor.py +571 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/services/verification/flow.py +1470 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/services/verification/fusion.py +177 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/services/verification/judgment.py +107 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/services/verification/models.py +75 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/services/verification/policy.py +457 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/services/verification/session.py +652 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/services/verification/vision.py +264 -0
- nonebot_plugin_fanqie_verify-0.4.0/src/plugins/nonebot_plugin_fanqie_verify/start/startup.py +37 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: nonebot-plugin-fanqie-verify
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: 番茄读书群入群验证插件:新成员入群后要求发送自己发布的番茄小说书评详情页截图,OCR 识别后自动放行或通知管理员决策
|
|
5
|
+
Keywords: nonebot2,nonebot,bot,ocr,paddleocr,group-management
|
|
6
|
+
Author: xinvxueyuan
|
|
7
|
+
Author-email: xinvxueyuan <xinvxueyuan@yeah.net>
|
|
8
|
+
License: MIT
|
|
9
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
10
|
+
Classifier: Environment :: Plugins
|
|
11
|
+
Classifier: Framework :: AsyncIO
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Natural Language :: Chinese (Simplified)
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Communications :: Chat
|
|
19
|
+
Requires-Dist: nonebot2[fastapi,httpx,websockets]>=2.5.0
|
|
20
|
+
Requires-Dist: nonebot-adapter-onebot>=2.4.6
|
|
21
|
+
Requires-Dist: nonebot-plugin-localstore>=0.7.4
|
|
22
|
+
Requires-Dist: nonebot-plugin-orm[aiosqlite]>=0.8.3
|
|
23
|
+
Requires-Dist: aiofiles>=25.1.0
|
|
24
|
+
Requires-Dist: openai>=1.0.0
|
|
25
|
+
Requires-Dist: rtoml>=0.13.0
|
|
26
|
+
Requires-Python: >=3.13, <3.14
|
|
27
|
+
Project-URL: Homepage, https://github.com/xinvxueyuan/nonebot-plugin-fanqie-verify
|
|
28
|
+
Project-URL: Repository, https://github.com/xinvxueyuan/nonebot-plugin-fanqie-verify
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
|
|
31
|
+
# nonebot-plugin-fanqie-verify
|
|
32
|
+
|
|
33
|
+
番茄读书群入群验证插件:新成员入群后要求发送**自己发布的番茄小说书评详情页截图**,
|
|
34
|
+
通过 PaddleOCR(PP-OCRv6)云端 API 识别书评信息,校验「我」徽章、书名、作者后
|
|
35
|
+
自动放行;验证失败则私信管理员决定通过或踢出。
|
|
36
|
+
|
|
37
|
+
## 功能
|
|
38
|
+
|
|
39
|
+
- **FR1 入群触发**:监听 OneBot V11 `group_increase` 事件,对新成员发送验证提示并开启超时计时
|
|
40
|
+
- **FR2 图片识别**:接收新成员发送的图片,调用 PaddleOCR 云端 API **多模型并行识别并按字段融合**(PaddleOCR-VL-1.6 / PP-OCRv6 / PP-StructureV3,置信度阈值可配);OCR 失败时回退**视觉模型看图判定**(支持**群聊发送**或**私聊机器人发送**两种方式验证)
|
|
41
|
+
- **FR3 信息提取**:检测「我」徽章(书评为本人发布)、「书评详情」标题与五角星评分组件,提取读者名、发布日期、评分、阅读时长、书评正文、书名与作者
|
|
42
|
+
- **FR4 综合判断**:本人书评 + 书名/作者合理性校验 + 可配置的放行策略(按群配置作者白名单);区分**书评 vs 短评/段评/章评/想法**(后者一律判无效);OCR 通过后**视觉模型二次复核**(持否决权,确保高准确率)
|
|
43
|
+
- **FR5 通过放行**:发送欢迎消息
|
|
44
|
+
- **FR6 拒绝处理**:不执行禁言,转入"待管理员决策"并私信通知管理员决定通过或踢出
|
|
45
|
+
- **FR7/FR8 超时/重试**:超时未响应或连续识别失败达到上限,转入"待管理员决策"并通知管理员;响应超时后还会在群内 @ 成员提示已超时、可发送「重审」重试
|
|
46
|
+
- **私聊验证**:新成员可直接私聊机器人发送书评详情页截图完成验证;多群待验证时用「验证 群号」指定目标群
|
|
47
|
+
- **管理决策超时**:通知管理员后超过 16 小时(可配置)未处理,自动在群内通报并移出成员;被移出前最后 1 小时、5 分钟(可配置)会再次 @ 提醒该成员及时重审
|
|
48
|
+
- **FR9 管理员命令**:`/kick`、`/keep`、`/通过` 决定踢出/保留/直接批准;`待处理列表`、`处理中列表` 查询本群待决策/待提交成员;`查看白名单` 查看本群作者与作品配置
|
|
49
|
+
- **状态持久化**:验证会话(等待提交 / 待管理员决策)持久化到数据库,重启后自动恢复并重建超时,不会把验证中的成员误当作已通过
|
|
50
|
+
- **追踪 ID**:每次验证流程携带全局唯一 trace ID,贯穿日志、落库(会话/事件/审计三表)与管理员通知,可回溯完整判定链路
|
|
51
|
+
- **运行时重载**:`重载番茄OCR配置` 命令热更新放行策略
|
|
52
|
+
- **边界守卫**:监听退群/管理员变动/禁言事件,操作前查询群成员状态,避免对已退出成员执行无效动作
|
|
53
|
+
- **漏验补验**:机器人(LLBot)掉线期间入群的成员不会收到入群事件,`补验` 命令可按「入群时间在最近 N 小时内 + 无验证记录」扫描并补进验证流程,也支持直接指定成员;机器人重连时可配置为自动补验或仅提醒管理员
|
|
54
|
+
- **延期审核**:管理员可用 `延期` 命令推迟「待管理员决策」成员的自动移出时间(默认 6 小时、单次上限 48 小时,均可配置),用于暂时无法处理时保住成员;可指定成员(`延期 @成员 12`)或对本群全部待审成员生效(`延期`),不限制累计次数
|
|
55
|
+
- **引用回复**:群内各项回复(提交反馈、命令回复、验证通过欢迎、超时通报、移出前提醒)均**引用原消息**发送,便于成员对照上下文;超时类通报引用该成员最后提交的图片消息。私聊消息与入群引导(系统事件,无原消息)保持普通发送
|
|
56
|
+
|
|
57
|
+
## 如何开始
|
|
58
|
+
|
|
59
|
+
前置要求:Python 3.13、[uv](https://docs.astral.sh/uv/)、一个 OneBot V11 实现(如
|
|
60
|
+
[NapCat](https://napneko.github.io/) / [go-cqhttp](https://docs.go-cqhttp.org/))。
|
|
61
|
+
|
|
62
|
+
1. 安装依赖:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
uv sync --all-groups
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
2. 配置环境变量:复制 `.env.example` 为 `.env` 并填写:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
cp .env.example .env
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
至少需要配置:
|
|
75
|
+
- `FANQIE_OCR_API_TOKEN`:PaddleOCR 云端 API 令牌
|
|
76
|
+
- `SUPERUSERS` / `FANQIE_ADMIN_IDS`:管理员 QQ 号(`/kick`、`/keep`、
|
|
77
|
+
`重载番茄OCR配置` 命令权限,NoneBot 要求 SUPERUSER)
|
|
78
|
+
- 群范围:放行策略 TOML 中配置群节点(配置了节点的群才验证)
|
|
79
|
+
|
|
80
|
+
3. 配置 OneBot V11 反向 WebSocket:
|
|
81
|
+
|
|
82
|
+
在 NapCat / go-cqhttp 中添加反向 WebSocket 连接,地址指向本插件的
|
|
83
|
+
`ws://<HOST>:<PORT>/onebot/v11/ws`(默认 `ws://127.0.0.1:8080/onebot/v11/ws`)。
|
|
84
|
+
HOST / PORT 由 `.env` 中的 `HOST` / `PORT` 决定。
|
|
85
|
+
|
|
86
|
+
4. 首次运行生成放行策略配置,然后按需编辑(见下文):
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
uv run nb run
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
5. 运行机器人(开发热重载):
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
uv run nb run --reload
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## 验证目标与判定
|
|
99
|
+
|
|
100
|
+
新成员需发送**自己发布的番茄小说书评详情页截图**。页面关键标识:
|
|
101
|
+
|
|
102
|
+
- 「**我**」徽章:书评为自己发布(他人书评无此徽章,将被拒绝)
|
|
103
|
+
- 读者名、发布日期、评分(★)、阅读时长、书评正文
|
|
104
|
+
- 书名(如 `综漫:吉他雇佣兵无法找到归宿?`)、作者
|
|
105
|
+
|
|
106
|
+
判定标准:**必须检测到「我」徽章 + 提取到书名与作者**。
|
|
107
|
+
|
|
108
|
+
## 配置
|
|
109
|
+
|
|
110
|
+
### 环境变量
|
|
111
|
+
|
|
112
|
+
以下变量通过 `.env`(或 `.env.dev` / `.env.prod`)配置,环境变量名大小写不敏感。
|
|
113
|
+
|
|
114
|
+
| 变量 | 说明 | 默认值 |
|
|
115
|
+
| --- | --- | --- |
|
|
116
|
+
| `FANQIE_VERIFY_GROUPS` | 需要验证的群号集合,`[]` 表示全部群(与策略群节点取交集) | `[]` |
|
|
117
|
+
| `FANQIE_ADMIN_IDS` | 管理员 QQ 号集合,可接收通知并执行 `/kick` `/keep` | `[]` |
|
|
118
|
+
| `FANQIE_WELCOME_MESSAGE` | 入群提示消息 | 内置默认文案 |
|
|
119
|
+
| `FANQIE_RESPONSE_TIMEOUT` | 等待新成员发送截图的超时(秒),超时按验证失败处理并通知管理员决策 | `600` |
|
|
120
|
+
| `FANQIE_MAX_ATTEMPTS` | 识别失败允许尝试次数,达上限按验证失败处理并通知管理员决策 | `3` |
|
|
121
|
+
| `FANQIE_ADMIN_DECISION_TIMEOUT` | 通知管理员后等待其决策的超时(秒),超时群内通报并移出成员 | `57600`(16 小时) |
|
|
122
|
+
| `FANQIE_REMIND_BEFORE_KICK` | 待管理员决策成员被移出前提前提醒的秒数列表(升序),如 `[3600, 300]` 表示最后 1 小时、5 分钟各提醒一次 | `[3600, 300]` |
|
|
123
|
+
| `FANQIE_REVIEW_MAX_TIMES` | 普通成员通过「重审」命令重新验证的最大次数 | `2` |
|
|
124
|
+
| `FANQIE_ALLOW_GROUP_ADMIN_COMMANDS` | 是否允许群内管理员(admin/群主)使用 `/keep` `/kick` 等命令 | `true` |
|
|
125
|
+
| `FANQIE_PRIVATE_VERIFY_ENABLED` | 是否启用「私聊发图完成验证」通道 | `true` |
|
|
126
|
+
| `FANQIE_BACKFILL_ENABLED` | 是否启用「补验」(补进错过入群事件的成员) | `true` |
|
|
127
|
+
| `FANQIE_BACKFILL_DEFAULT_HOURS` | 补验默认扫描窗口(小时) | `24` |
|
|
128
|
+
| `FANQIE_BACKFILL_RECONNECT_MODE` | 机器人重连时的补验行为:`notify` 仅提醒 / `auto` 自动补验 / `off` 不处理 | `notify` |
|
|
129
|
+
| `FANQIE_BACKFILL_CONFIRM_FIRST` | 补验是否先列候选名单等确认 | `false` |
|
|
130
|
+
| `FANQIE_BACKFILL_MAX_BATCH` | 单次补验人数上限 | `20` |
|
|
131
|
+
| `FANQIE_EXTEND_ENABLED` | 是否启用「延期」命令 | `true` |
|
|
132
|
+
| `FANQIE_EXTEND_DEFAULT_HOURS` | 延期不带时长参数时的默认小时数 | `6` |
|
|
133
|
+
| `FANQIE_EXTEND_MAX_HOURS` | 单次延期的最大小时数(不限制累计次数) | `48` |
|
|
134
|
+
| `FANQIE_KICK_RETRY_TIMES` | 踢出失败后的重试轮数;用尽则记为「待补踢」,机器人重连时自动补偿 | `3` |
|
|
135
|
+
| `FANQIE_KICK_RETRY_DELAY` | 踢人重试间隔(秒) | `60` |
|
|
136
|
+
| `FANQIE_NOTIFY_CHANNEL` | 验证失败通知管理员的渠道:`group`(群内一条消息并 @ 全部管理员,可引用原消息)/ `private`(逐个私聊,失败回退群内)/ `none`(不通知) | `group` |
|
|
137
|
+
| `FANQIE_BOOK_NAME_MAX_LEN` | FR4 有效书名最大字符数 | `100` |
|
|
138
|
+
| `FANQIE_OCR_API_URL` | OCR 任务提交地址,留空用官方默认 | 官方默认 |
|
|
139
|
+
| `FANQIE_OCR_API_TOKEN` | OCR API 认证令牌(必填) | 空 |
|
|
140
|
+
| `FANQIE_OCR_TIMEOUT` | 单次 HTTP 请求超时(秒) | `15` |
|
|
141
|
+
| `FANQIE_OCR_POLL_TIMEOUT` | 等待 OCR 任务完成总超时(秒) | `120` |
|
|
142
|
+
| `FANQIE_OCR_ENABLED` | 是否启用 PaddleOCR 识别;`false` 时跳过 OCR 直接走视觉模型判定(仅视觉模式) | `true` |
|
|
143
|
+
| `FANQIE_OCR_MODEL` | PaddleOCR 模型名 | `PaddleOCR-VL-1.6` |
|
|
144
|
+
| `FANQIE_OCR_MODELS` | 多模型并行识别的模型集合(JSON 数组),结果按字段融合 | `["PaddleOCR-VL-1.6", "PP-OCRv6", "PP-StructureV3"]` |
|
|
145
|
+
| `FANQIE_SIMILARITY_THRESHOLD` | 多模型字段融合的置信度阈值(0~1) | `0.9` |
|
|
146
|
+
| `FANQIE_VISION_ENABLED` | 是否启用视觉模型兜底/复核 | `true` |
|
|
147
|
+
| `FANQIE_VISION_API_BASE` | 视觉模型 OpenAI 兼容 API 地址 | `https://api.deepseek.com` |
|
|
148
|
+
| `FANQIE_VISION_API_KEY` | 视觉模型 API 密钥 | 空 |
|
|
149
|
+
| `FANQIE_VISION_MODEL` | 视觉模型名称 | `deepseek-v4-flash-vision-exp` |
|
|
150
|
+
| `FANQIE_VISION_TIMEOUT` | 视觉模型单次请求超时(秒) | `60` |
|
|
151
|
+
| `FANQIE_VERIFICATION_POLICY_PATH` | 放行策略 TOML 路径,空用 localstore 配置目录 | 空 |
|
|
152
|
+
| `FANQIE_MESSAGE_STORE_ENABLED` | 是否启用消息/审计存储 | `true` |
|
|
153
|
+
| `FANQIE_MESSAGE_STORE_SUMMARY_LIMIT` | 文本摘要最大字符数 | `500` |
|
|
154
|
+
| `FANQIE_MESSAGE_STORE_CLEANUP_ENABLED` | 关闭时是否清理过期记录 | `true` |
|
|
155
|
+
| `FANQIE_MESSAGE_STORE_RETENTION_DAYS` | 记录保留天数 | `7` |
|
|
156
|
+
| `FANQIE_MESSAGE_STORE_RECORD_API_CALLS` | 是否记录平台 API 调用审计 | `false` |
|
|
157
|
+
|
|
158
|
+
完整模板见 `.env.example`。
|
|
159
|
+
|
|
160
|
+
### 放行策略 TOML(FR4)
|
|
161
|
+
|
|
162
|
+
首次运行后生成在 `config/nonebot_plugin_fanqie_verify/verification_policy.toml`。
|
|
163
|
+
策略**以群为节点**组织:每个群下可配置多个作者,每个作者下可配置多个作品(书名)。
|
|
164
|
+
|
|
165
|
+
```toml
|
|
166
|
+
[verification]
|
|
167
|
+
require_all = false # true 要求全部受支持元素匹配;false 按 required_elements
|
|
168
|
+
required_elements = ["book_name", "author"] # require_all=false 时必配元素
|
|
169
|
+
|
|
170
|
+
# 群节点:群号 → 作者列表。配置了节点的群才执行验证。
|
|
171
|
+
[verification.groups]
|
|
172
|
+
|
|
173
|
+
[[verification.groups.868258211.authors]]
|
|
174
|
+
name = "阿百川大鬼"
|
|
175
|
+
books = ["综漫:吉他雇佣兵无法找到归宿?", "另一部作品"]
|
|
176
|
+
|
|
177
|
+
[[verification.groups.868258211.authors]]
|
|
178
|
+
name = "刘慈欣"
|
|
179
|
+
books = ["三体", "球状闪电"]
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
判定规则(按群):
|
|
183
|
+
- **群未配置任何作者节点**:放行(宽松模式,仅校验必配元素存在)。
|
|
184
|
+
- **群配置了作者节点**:提取到的**作者必须命中其中一个作者名**(只校验作者,
|
|
185
|
+
`books` 作品列表仅作配置参考与审计展示,不参与判定)。
|
|
186
|
+
- 群节点本身即**监控范围**:只有配置了节点的群才会执行入群验证。
|
|
187
|
+
|
|
188
|
+
受支持的元素名:`reader_name`、`publish_time`、`rating`、`read_duration`、
|
|
189
|
+
`book_name`、`author`、`review_text`。
|
|
190
|
+
|
|
191
|
+
## 管理员命令
|
|
192
|
+
|
|
193
|
+
| 命令 | 权限 | 说明 |
|
|
194
|
+
| --- | --- | --- |
|
|
195
|
+
| `/kick <user_id>` | 超级用户 / 配置管理员 | 将指定成员移出群聊 |
|
|
196
|
+
| `/keep <user_id>` | 超级用户 / 配置管理员 | 通过并保留成员(仅限处于验证流程中的成员) |
|
|
197
|
+
| `/通过 <user_id>` | 超级用户 / 配置管理员 | **插入直接批准**:对新入群且仍在验证流程(等待截图 / 待管理员决策)的成员直接放行并欢迎,无需等待提交截图或超时 |
|
|
198
|
+
| `待处理列表` | 超级用户 / 配置管理员 | 查询本群等待管理员决策的成员及剩余时间 |
|
|
199
|
+
| `处理中列表` | 超级用户 / 配置管理员 | 查询本群正在等待截图提交(验证中)的成员 |
|
|
200
|
+
| `补验 [小时数] [@成员/QQ号]` | 超级用户 / 配置管理员 | 把错过入群事件的成员补进验证流程:无参数按默认窗口扫描,可带小时数(如 `补验 48`)或指定成员;`FANQIE_BACKFILL_CONFIRM_FIRST=true` 时先列名单 |
|
|
201
|
+
| `补验确认` | 超级用户 / 配置管理员 | 执行 `补验` 列出的候选名单(仅 `CONFIRM_FIRST=true` 时用到) |
|
|
202
|
+
| `延期 [@成员/QQ号] [小时数]` | 超级用户 / 配置管理员 | 推迟「待管理员决策」成员的自动移出时间(新截止 = 当前时间 + 延期时长):不带成员时作用于本群全部待审成员;不带时长时用 `FANQIE_EXTEND_DEFAULT_HOURS`(默认 6 小时),单次上限 `FANQIE_EXTEND_MAX_HOURS`(默认 48 小时,超出按上限处理) |
|
|
203
|
+
| `查看白名单` | 所有群成员 | 展示当前群配置的作者与作品列表 |
|
|
204
|
+
| `重载番茄OCR配置` | 超级用户 / 配置管理员 | 热重载放行策略 TOML |
|
|
205
|
+
| `重审 [@成员]` | 所有群成员 | 普通成员重审**自己**(限 `FANQIE_REVIEW_MAX_TIMES` 次,默认 2);管理员 `@成员` 可重审任意普通成员(不限次数)。重审复用完整验证流程:重置识别重试、重新发送引导、重排超时窗口 |
|
|
206
|
+
|
|
207
|
+
`<user_id>` 也可用 `@成员` 代替。命令前缀由 `COMMAND_START` 决定(默认 `/`)。「重审」命令不受前缀限制(`重审` 与 `/重审` 均可用)。
|
|
208
|
+
|
|
209
|
+
### 成员命令(私聊验证)
|
|
210
|
+
|
|
211
|
+
| 命令 | 说明 |
|
|
212
|
+
| --- | --- |
|
|
213
|
+
| `验证 <群号>` | 多群待验证时,指定在哪个群验证(私聊机器人发送) |
|
|
214
|
+
| (直接私聊发书评截图) | 若恰有一个待验证群则直接验证;多群则先提示用 `验证 群号` 选择 |
|
|
215
|
+
|
|
216
|
+
## 验证流程
|
|
217
|
+
|
|
218
|
+
1. 新成员入群 → 机器人 @ 成员发送验证提示并开始超时计时
|
|
219
|
+
2. 成员发送**自己发布的书评详情页截图** → OCR 识别 → 提取「我」徽章、书名、作者、读者名等
|
|
220
|
+
3. 综合判断:本人书评(「我」徽章)+ 信息足够 + 放行策略满足 + 合理性通过 → **放行**(欢迎)
|
|
221
|
+
4. 否则(他人书评 / 缺少书名作者 / 白名单不命中 / 超时未发图 / 识别失败达上限)→ 转入**待管理员决策**并私信通知管理员,同时响应超时会在群内 @ 成员提示已超时、可发「重审」;管理员用 `/kick` 或 `/keep` 决策
|
|
222
|
+
5. 管理员超过 `FANQIE_ADMIN_DECISION_TIMEOUT`(默认 16 小时)未处理 → 被移出前最后 1 小时、5 分钟各在群内 @ 提醒该成员;仍未处理则群内通报并移出该成员
|
|
223
|
+
6. 所有进行中的会话(等待提交 / 待管理员决策)持久化到数据库,重启后自动恢复,不会把验证中的成员误当作已通过
|
|
224
|
+
|
|
225
|
+
## 开发
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
task check # ruff + pyright
|
|
229
|
+
task test # pytest
|
|
230
|
+
task fix # 自动修复 lint/格式
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
插件源码位于 `src/plugins/nonebot_plugin_fanqie_verify/`。
|
|
234
|
+
|
|
235
|
+
## 更新日志
|
|
236
|
+
|
|
237
|
+
各版本的重要变更见 [CHANGELOG.md](./CHANGELOG.md)。
|
|
238
|
+
|
|
239
|
+
## 文档
|
|
240
|
+
|
|
241
|
+
- [NoneBot2 文档](https://nonebot.dev/)
|
|
242
|
+
- [PaddleOCR / PP-OCRv6](https://www.paddleocr.ai/)
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# nonebot-plugin-fanqie-verify
|
|
2
|
+
|
|
3
|
+
番茄读书群入群验证插件:新成员入群后要求发送**自己发布的番茄小说书评详情页截图**,
|
|
4
|
+
通过 PaddleOCR(PP-OCRv6)云端 API 识别书评信息,校验「我」徽章、书名、作者后
|
|
5
|
+
自动放行;验证失败则私信管理员决定通过或踢出。
|
|
6
|
+
|
|
7
|
+
## 功能
|
|
8
|
+
|
|
9
|
+
- **FR1 入群触发**:监听 OneBot V11 `group_increase` 事件,对新成员发送验证提示并开启超时计时
|
|
10
|
+
- **FR2 图片识别**:接收新成员发送的图片,调用 PaddleOCR 云端 API **多模型并行识别并按字段融合**(PaddleOCR-VL-1.6 / PP-OCRv6 / PP-StructureV3,置信度阈值可配);OCR 失败时回退**视觉模型看图判定**(支持**群聊发送**或**私聊机器人发送**两种方式验证)
|
|
11
|
+
- **FR3 信息提取**:检测「我」徽章(书评为本人发布)、「书评详情」标题与五角星评分组件,提取读者名、发布日期、评分、阅读时长、书评正文、书名与作者
|
|
12
|
+
- **FR4 综合判断**:本人书评 + 书名/作者合理性校验 + 可配置的放行策略(按群配置作者白名单);区分**书评 vs 短评/段评/章评/想法**(后者一律判无效);OCR 通过后**视觉模型二次复核**(持否决权,确保高准确率)
|
|
13
|
+
- **FR5 通过放行**:发送欢迎消息
|
|
14
|
+
- **FR6 拒绝处理**:不执行禁言,转入"待管理员决策"并私信通知管理员决定通过或踢出
|
|
15
|
+
- **FR7/FR8 超时/重试**:超时未响应或连续识别失败达到上限,转入"待管理员决策"并通知管理员;响应超时后还会在群内 @ 成员提示已超时、可发送「重审」重试
|
|
16
|
+
- **私聊验证**:新成员可直接私聊机器人发送书评详情页截图完成验证;多群待验证时用「验证 群号」指定目标群
|
|
17
|
+
- **管理决策超时**:通知管理员后超过 16 小时(可配置)未处理,自动在群内通报并移出成员;被移出前最后 1 小时、5 分钟(可配置)会再次 @ 提醒该成员及时重审
|
|
18
|
+
- **FR9 管理员命令**:`/kick`、`/keep`、`/通过` 决定踢出/保留/直接批准;`待处理列表`、`处理中列表` 查询本群待决策/待提交成员;`查看白名单` 查看本群作者与作品配置
|
|
19
|
+
- **状态持久化**:验证会话(等待提交 / 待管理员决策)持久化到数据库,重启后自动恢复并重建超时,不会把验证中的成员误当作已通过
|
|
20
|
+
- **追踪 ID**:每次验证流程携带全局唯一 trace ID,贯穿日志、落库(会话/事件/审计三表)与管理员通知,可回溯完整判定链路
|
|
21
|
+
- **运行时重载**:`重载番茄OCR配置` 命令热更新放行策略
|
|
22
|
+
- **边界守卫**:监听退群/管理员变动/禁言事件,操作前查询群成员状态,避免对已退出成员执行无效动作
|
|
23
|
+
- **漏验补验**:机器人(LLBot)掉线期间入群的成员不会收到入群事件,`补验` 命令可按「入群时间在最近 N 小时内 + 无验证记录」扫描并补进验证流程,也支持直接指定成员;机器人重连时可配置为自动补验或仅提醒管理员
|
|
24
|
+
- **延期审核**:管理员可用 `延期` 命令推迟「待管理员决策」成员的自动移出时间(默认 6 小时、单次上限 48 小时,均可配置),用于暂时无法处理时保住成员;可指定成员(`延期 @成员 12`)或对本群全部待审成员生效(`延期`),不限制累计次数
|
|
25
|
+
- **引用回复**:群内各项回复(提交反馈、命令回复、验证通过欢迎、超时通报、移出前提醒)均**引用原消息**发送,便于成员对照上下文;超时类通报引用该成员最后提交的图片消息。私聊消息与入群引导(系统事件,无原消息)保持普通发送
|
|
26
|
+
|
|
27
|
+
## 如何开始
|
|
28
|
+
|
|
29
|
+
前置要求:Python 3.13、[uv](https://docs.astral.sh/uv/)、一个 OneBot V11 实现(如
|
|
30
|
+
[NapCat](https://napneko.github.io/) / [go-cqhttp](https://docs.go-cqhttp.org/))。
|
|
31
|
+
|
|
32
|
+
1. 安装依赖:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
uv sync --all-groups
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
2. 配置环境变量:复制 `.env.example` 为 `.env` 并填写:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
cp .env.example .env
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
至少需要配置:
|
|
45
|
+
- `FANQIE_OCR_API_TOKEN`:PaddleOCR 云端 API 令牌
|
|
46
|
+
- `SUPERUSERS` / `FANQIE_ADMIN_IDS`:管理员 QQ 号(`/kick`、`/keep`、
|
|
47
|
+
`重载番茄OCR配置` 命令权限,NoneBot 要求 SUPERUSER)
|
|
48
|
+
- 群范围:放行策略 TOML 中配置群节点(配置了节点的群才验证)
|
|
49
|
+
|
|
50
|
+
3. 配置 OneBot V11 反向 WebSocket:
|
|
51
|
+
|
|
52
|
+
在 NapCat / go-cqhttp 中添加反向 WebSocket 连接,地址指向本插件的
|
|
53
|
+
`ws://<HOST>:<PORT>/onebot/v11/ws`(默认 `ws://127.0.0.1:8080/onebot/v11/ws`)。
|
|
54
|
+
HOST / PORT 由 `.env` 中的 `HOST` / `PORT` 决定。
|
|
55
|
+
|
|
56
|
+
4. 首次运行生成放行策略配置,然后按需编辑(见下文):
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
uv run nb run
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
5. 运行机器人(开发热重载):
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
uv run nb run --reload
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## 验证目标与判定
|
|
69
|
+
|
|
70
|
+
新成员需发送**自己发布的番茄小说书评详情页截图**。页面关键标识:
|
|
71
|
+
|
|
72
|
+
- 「**我**」徽章:书评为自己发布(他人书评无此徽章,将被拒绝)
|
|
73
|
+
- 读者名、发布日期、评分(★)、阅读时长、书评正文
|
|
74
|
+
- 书名(如 `综漫:吉他雇佣兵无法找到归宿?`)、作者
|
|
75
|
+
|
|
76
|
+
判定标准:**必须检测到「我」徽章 + 提取到书名与作者**。
|
|
77
|
+
|
|
78
|
+
## 配置
|
|
79
|
+
|
|
80
|
+
### 环境变量
|
|
81
|
+
|
|
82
|
+
以下变量通过 `.env`(或 `.env.dev` / `.env.prod`)配置,环境变量名大小写不敏感。
|
|
83
|
+
|
|
84
|
+
| 变量 | 说明 | 默认值 |
|
|
85
|
+
| --- | --- | --- |
|
|
86
|
+
| `FANQIE_VERIFY_GROUPS` | 需要验证的群号集合,`[]` 表示全部群(与策略群节点取交集) | `[]` |
|
|
87
|
+
| `FANQIE_ADMIN_IDS` | 管理员 QQ 号集合,可接收通知并执行 `/kick` `/keep` | `[]` |
|
|
88
|
+
| `FANQIE_WELCOME_MESSAGE` | 入群提示消息 | 内置默认文案 |
|
|
89
|
+
| `FANQIE_RESPONSE_TIMEOUT` | 等待新成员发送截图的超时(秒),超时按验证失败处理并通知管理员决策 | `600` |
|
|
90
|
+
| `FANQIE_MAX_ATTEMPTS` | 识别失败允许尝试次数,达上限按验证失败处理并通知管理员决策 | `3` |
|
|
91
|
+
| `FANQIE_ADMIN_DECISION_TIMEOUT` | 通知管理员后等待其决策的超时(秒),超时群内通报并移出成员 | `57600`(16 小时) |
|
|
92
|
+
| `FANQIE_REMIND_BEFORE_KICK` | 待管理员决策成员被移出前提前提醒的秒数列表(升序),如 `[3600, 300]` 表示最后 1 小时、5 分钟各提醒一次 | `[3600, 300]` |
|
|
93
|
+
| `FANQIE_REVIEW_MAX_TIMES` | 普通成员通过「重审」命令重新验证的最大次数 | `2` |
|
|
94
|
+
| `FANQIE_ALLOW_GROUP_ADMIN_COMMANDS` | 是否允许群内管理员(admin/群主)使用 `/keep` `/kick` 等命令 | `true` |
|
|
95
|
+
| `FANQIE_PRIVATE_VERIFY_ENABLED` | 是否启用「私聊发图完成验证」通道 | `true` |
|
|
96
|
+
| `FANQIE_BACKFILL_ENABLED` | 是否启用「补验」(补进错过入群事件的成员) | `true` |
|
|
97
|
+
| `FANQIE_BACKFILL_DEFAULT_HOURS` | 补验默认扫描窗口(小时) | `24` |
|
|
98
|
+
| `FANQIE_BACKFILL_RECONNECT_MODE` | 机器人重连时的补验行为:`notify` 仅提醒 / `auto` 自动补验 / `off` 不处理 | `notify` |
|
|
99
|
+
| `FANQIE_BACKFILL_CONFIRM_FIRST` | 补验是否先列候选名单等确认 | `false` |
|
|
100
|
+
| `FANQIE_BACKFILL_MAX_BATCH` | 单次补验人数上限 | `20` |
|
|
101
|
+
| `FANQIE_EXTEND_ENABLED` | 是否启用「延期」命令 | `true` |
|
|
102
|
+
| `FANQIE_EXTEND_DEFAULT_HOURS` | 延期不带时长参数时的默认小时数 | `6` |
|
|
103
|
+
| `FANQIE_EXTEND_MAX_HOURS` | 单次延期的最大小时数(不限制累计次数) | `48` |
|
|
104
|
+
| `FANQIE_KICK_RETRY_TIMES` | 踢出失败后的重试轮数;用尽则记为「待补踢」,机器人重连时自动补偿 | `3` |
|
|
105
|
+
| `FANQIE_KICK_RETRY_DELAY` | 踢人重试间隔(秒) | `60` |
|
|
106
|
+
| `FANQIE_NOTIFY_CHANNEL` | 验证失败通知管理员的渠道:`group`(群内一条消息并 @ 全部管理员,可引用原消息)/ `private`(逐个私聊,失败回退群内)/ `none`(不通知) | `group` |
|
|
107
|
+
| `FANQIE_BOOK_NAME_MAX_LEN` | FR4 有效书名最大字符数 | `100` |
|
|
108
|
+
| `FANQIE_OCR_API_URL` | OCR 任务提交地址,留空用官方默认 | 官方默认 |
|
|
109
|
+
| `FANQIE_OCR_API_TOKEN` | OCR API 认证令牌(必填) | 空 |
|
|
110
|
+
| `FANQIE_OCR_TIMEOUT` | 单次 HTTP 请求超时(秒) | `15` |
|
|
111
|
+
| `FANQIE_OCR_POLL_TIMEOUT` | 等待 OCR 任务完成总超时(秒) | `120` |
|
|
112
|
+
| `FANQIE_OCR_ENABLED` | 是否启用 PaddleOCR 识别;`false` 时跳过 OCR 直接走视觉模型判定(仅视觉模式) | `true` |
|
|
113
|
+
| `FANQIE_OCR_MODEL` | PaddleOCR 模型名 | `PaddleOCR-VL-1.6` |
|
|
114
|
+
| `FANQIE_OCR_MODELS` | 多模型并行识别的模型集合(JSON 数组),结果按字段融合 | `["PaddleOCR-VL-1.6", "PP-OCRv6", "PP-StructureV3"]` |
|
|
115
|
+
| `FANQIE_SIMILARITY_THRESHOLD` | 多模型字段融合的置信度阈值(0~1) | `0.9` |
|
|
116
|
+
| `FANQIE_VISION_ENABLED` | 是否启用视觉模型兜底/复核 | `true` |
|
|
117
|
+
| `FANQIE_VISION_API_BASE` | 视觉模型 OpenAI 兼容 API 地址 | `https://api.deepseek.com` |
|
|
118
|
+
| `FANQIE_VISION_API_KEY` | 视觉模型 API 密钥 | 空 |
|
|
119
|
+
| `FANQIE_VISION_MODEL` | 视觉模型名称 | `deepseek-v4-flash-vision-exp` |
|
|
120
|
+
| `FANQIE_VISION_TIMEOUT` | 视觉模型单次请求超时(秒) | `60` |
|
|
121
|
+
| `FANQIE_VERIFICATION_POLICY_PATH` | 放行策略 TOML 路径,空用 localstore 配置目录 | 空 |
|
|
122
|
+
| `FANQIE_MESSAGE_STORE_ENABLED` | 是否启用消息/审计存储 | `true` |
|
|
123
|
+
| `FANQIE_MESSAGE_STORE_SUMMARY_LIMIT` | 文本摘要最大字符数 | `500` |
|
|
124
|
+
| `FANQIE_MESSAGE_STORE_CLEANUP_ENABLED` | 关闭时是否清理过期记录 | `true` |
|
|
125
|
+
| `FANQIE_MESSAGE_STORE_RETENTION_DAYS` | 记录保留天数 | `7` |
|
|
126
|
+
| `FANQIE_MESSAGE_STORE_RECORD_API_CALLS` | 是否记录平台 API 调用审计 | `false` |
|
|
127
|
+
|
|
128
|
+
完整模板见 `.env.example`。
|
|
129
|
+
|
|
130
|
+
### 放行策略 TOML(FR4)
|
|
131
|
+
|
|
132
|
+
首次运行后生成在 `config/nonebot_plugin_fanqie_verify/verification_policy.toml`。
|
|
133
|
+
策略**以群为节点**组织:每个群下可配置多个作者,每个作者下可配置多个作品(书名)。
|
|
134
|
+
|
|
135
|
+
```toml
|
|
136
|
+
[verification]
|
|
137
|
+
require_all = false # true 要求全部受支持元素匹配;false 按 required_elements
|
|
138
|
+
required_elements = ["book_name", "author"] # require_all=false 时必配元素
|
|
139
|
+
|
|
140
|
+
# 群节点:群号 → 作者列表。配置了节点的群才执行验证。
|
|
141
|
+
[verification.groups]
|
|
142
|
+
|
|
143
|
+
[[verification.groups.868258211.authors]]
|
|
144
|
+
name = "阿百川大鬼"
|
|
145
|
+
books = ["综漫:吉他雇佣兵无法找到归宿?", "另一部作品"]
|
|
146
|
+
|
|
147
|
+
[[verification.groups.868258211.authors]]
|
|
148
|
+
name = "刘慈欣"
|
|
149
|
+
books = ["三体", "球状闪电"]
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
判定规则(按群):
|
|
153
|
+
- **群未配置任何作者节点**:放行(宽松模式,仅校验必配元素存在)。
|
|
154
|
+
- **群配置了作者节点**:提取到的**作者必须命中其中一个作者名**(只校验作者,
|
|
155
|
+
`books` 作品列表仅作配置参考与审计展示,不参与判定)。
|
|
156
|
+
- 群节点本身即**监控范围**:只有配置了节点的群才会执行入群验证。
|
|
157
|
+
|
|
158
|
+
受支持的元素名:`reader_name`、`publish_time`、`rating`、`read_duration`、
|
|
159
|
+
`book_name`、`author`、`review_text`。
|
|
160
|
+
|
|
161
|
+
## 管理员命令
|
|
162
|
+
|
|
163
|
+
| 命令 | 权限 | 说明 |
|
|
164
|
+
| --- | --- | --- |
|
|
165
|
+
| `/kick <user_id>` | 超级用户 / 配置管理员 | 将指定成员移出群聊 |
|
|
166
|
+
| `/keep <user_id>` | 超级用户 / 配置管理员 | 通过并保留成员(仅限处于验证流程中的成员) |
|
|
167
|
+
| `/通过 <user_id>` | 超级用户 / 配置管理员 | **插入直接批准**:对新入群且仍在验证流程(等待截图 / 待管理员决策)的成员直接放行并欢迎,无需等待提交截图或超时 |
|
|
168
|
+
| `待处理列表` | 超级用户 / 配置管理员 | 查询本群等待管理员决策的成员及剩余时间 |
|
|
169
|
+
| `处理中列表` | 超级用户 / 配置管理员 | 查询本群正在等待截图提交(验证中)的成员 |
|
|
170
|
+
| `补验 [小时数] [@成员/QQ号]` | 超级用户 / 配置管理员 | 把错过入群事件的成员补进验证流程:无参数按默认窗口扫描,可带小时数(如 `补验 48`)或指定成员;`FANQIE_BACKFILL_CONFIRM_FIRST=true` 时先列名单 |
|
|
171
|
+
| `补验确认` | 超级用户 / 配置管理员 | 执行 `补验` 列出的候选名单(仅 `CONFIRM_FIRST=true` 时用到) |
|
|
172
|
+
| `延期 [@成员/QQ号] [小时数]` | 超级用户 / 配置管理员 | 推迟「待管理员决策」成员的自动移出时间(新截止 = 当前时间 + 延期时长):不带成员时作用于本群全部待审成员;不带时长时用 `FANQIE_EXTEND_DEFAULT_HOURS`(默认 6 小时),单次上限 `FANQIE_EXTEND_MAX_HOURS`(默认 48 小时,超出按上限处理) |
|
|
173
|
+
| `查看白名单` | 所有群成员 | 展示当前群配置的作者与作品列表 |
|
|
174
|
+
| `重载番茄OCR配置` | 超级用户 / 配置管理员 | 热重载放行策略 TOML |
|
|
175
|
+
| `重审 [@成员]` | 所有群成员 | 普通成员重审**自己**(限 `FANQIE_REVIEW_MAX_TIMES` 次,默认 2);管理员 `@成员` 可重审任意普通成员(不限次数)。重审复用完整验证流程:重置识别重试、重新发送引导、重排超时窗口 |
|
|
176
|
+
|
|
177
|
+
`<user_id>` 也可用 `@成员` 代替。命令前缀由 `COMMAND_START` 决定(默认 `/`)。「重审」命令不受前缀限制(`重审` 与 `/重审` 均可用)。
|
|
178
|
+
|
|
179
|
+
### 成员命令(私聊验证)
|
|
180
|
+
|
|
181
|
+
| 命令 | 说明 |
|
|
182
|
+
| --- | --- |
|
|
183
|
+
| `验证 <群号>` | 多群待验证时,指定在哪个群验证(私聊机器人发送) |
|
|
184
|
+
| (直接私聊发书评截图) | 若恰有一个待验证群则直接验证;多群则先提示用 `验证 群号` 选择 |
|
|
185
|
+
|
|
186
|
+
## 验证流程
|
|
187
|
+
|
|
188
|
+
1. 新成员入群 → 机器人 @ 成员发送验证提示并开始超时计时
|
|
189
|
+
2. 成员发送**自己发布的书评详情页截图** → OCR 识别 → 提取「我」徽章、书名、作者、读者名等
|
|
190
|
+
3. 综合判断:本人书评(「我」徽章)+ 信息足够 + 放行策略满足 + 合理性通过 → **放行**(欢迎)
|
|
191
|
+
4. 否则(他人书评 / 缺少书名作者 / 白名单不命中 / 超时未发图 / 识别失败达上限)→ 转入**待管理员决策**并私信通知管理员,同时响应超时会在群内 @ 成员提示已超时、可发「重审」;管理员用 `/kick` 或 `/keep` 决策
|
|
192
|
+
5. 管理员超过 `FANQIE_ADMIN_DECISION_TIMEOUT`(默认 16 小时)未处理 → 被移出前最后 1 小时、5 分钟各在群内 @ 提醒该成员;仍未处理则群内通报并移出该成员
|
|
193
|
+
6. 所有进行中的会话(等待提交 / 待管理员决策)持久化到数据库,重启后自动恢复,不会把验证中的成员误当作已通过
|
|
194
|
+
|
|
195
|
+
## 开发
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
task check # ruff + pyright
|
|
199
|
+
task test # pytest
|
|
200
|
+
task fix # 自动修复 lint/格式
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
插件源码位于 `src/plugins/nonebot_plugin_fanqie_verify/`。
|
|
204
|
+
|
|
205
|
+
## 更新日志
|
|
206
|
+
|
|
207
|
+
各版本的重要变更见 [CHANGELOG.md](./CHANGELOG.md)。
|
|
208
|
+
|
|
209
|
+
## 文档
|
|
210
|
+
|
|
211
|
+
- [NoneBot2 文档](https://nonebot.dev/)
|
|
212
|
+
- [PaddleOCR / PP-OCRv6](https://www.paddleocr.ai/)
|