mia-cx/honeybot
GitHub: mia-cx/honeybot
Honeybot 是一个可自托管的 Discord 审核机器人,通过蜜罐频道、跨频道重复检测和 AI 辅助分类来识别并处理诈骗与垃圾信息突袭。
Stars: 0 | Forks: 0
# Honeybot
Honeybot 是一个基于 Discord.js 的审核机器人,旨在通过蜜罐频道、跨频道重复检测、已知诈骗证据、embeddings、分类器和审核审查来捕获诈骗和垃圾信息突袭。
它专为自行托管而构建:SQLite 用于持久化,文件系统用于存储证据,Docker 镜像和 Kubernetes/k3s 清单都是首选的部署路径。
## 目录
- [功能](#features)
- [Discord 应用要求](#discord-app-requirements)
- [快速开始](#quick-start)
- [Docker 使用](#docker-usage)
- [Docker Compose](#docker-compose)
- [Kubernetes / Helm](#kubernetes--helm)
- [配置](#configuration)
- [镜像标签](#image-tags)
- [开发](#development)
- [文档](#docs)
## 功能
- 蜜罐频道触发。
- 具有可配置 S 型曲线时间窗口的跨频道重复内容检测。
- 用于精确、模糊和基于 embedding 的诈骗查找的已知证据库。
- 通过兼容 OpenRouter 的模型配置实现的文本和多模态图像分类器。
- 用于预防和最终处罚的每个服务器策略。
- Components V2 `/settings`、案件审查、证据库列表和处罚 DM UI。
- 带有独立案件审核员和 Honeybot 配置访问权限的审核审查按钮。
- 用于已知诈骗证据库和全局封禁的可选全局管理员工作流。
- 位于 `/app/data` 下的持久化 SQLite 状态。
- 默认位于 `/app/data/images` 下的文件系统证据/图像存储。
## Discord 应用要求
在 Discord 开发者门户中启用这些特权网关意图:
- 服务器成员意图
- 消息内容意图
默认安装作用域:
| 安装类型 | 作用域 |
| --- | --- |
| 用户安装 | `applications.commands` |
| 服务器安装 | `applications.commands`, `bot` |
默认服务器安装权限:
- 附加文件
- 封禁成员
- 嵌入链接
- 踢出成员
- 管理频道
- 管理消息
- 管理角色
- 审核成员
- 发送消息
- 在串接中发送消息
- 使用外部表情符号
- 使用斜杠命令
- 查看审计日志
- 查看频道
某些权限仅在启用了相应的审核策略时才需要,但默认安装集允许每个 Honeybot 功能正常工作,而无需重新生成邀请。
## 快速开始
```
pnpm install
cp .env.example .env
```
填写 `.env`:
```
DISCORD_TOKEN=your-bot-token
OPENROUTER_API_KEY=optional-default-key
API_KEY_ENCRYPTION_KEY=base64-encoded-32-byte-key
```
使用以下命令生成加密密钥:
```
openssl rand -base64 32
```
本地运行:
```
pnpm dev
```
机器人启动后使用 `/settings` 配置服务器。
## Docker 使用
已发布的镜像:
- Docker Hub: `miacx/honeybot`
- GHCR: `ghcr.io/mia-cx/honeybot`
使用 Docker Hub 运行:
```
docker run -d \
--name honeybot \
--restart unless-stopped \
-e DISCORD_TOKEN='your-bot-token' \
-e OPENROUTER_API_KEY='optional-default-key' \
-e API_KEY_ENCRYPTION_KEY='base64-encoded-32-byte-key' \
-e GLOBAL_AUTH_MODE='team' \
-e GLOBAL_AUTH_TEAM_ID='your-discord-app-team-id' \
-v honeybot-data:/app/data \
miacx/honeybot:latest
```
使用 GHCR 运行:
```
docker run -d \
--name honeybot \
--restart unless-stopped \
-e DISCORD_TOKEN='your-bot-token' \
-e API_KEY_ENCRYPTION_KEY='base64-encoded-32-byte-key' \
-v honeybot-data:/app/data \
ghcr.io/mia-cx/honeybot:latest
```
没有需要发布的端口。Honeybot 仅向 Discord 和模型提供商建立出站连接。
### 数据卷
| 路径 | 用途 |
| --- | --- |
| `/app/data` | SQLite 数据库、存储的证据图像和运行时状态 |
如果没有持久化数据卷,重新部署可能会丢失配置、案件、详细日志模式状态和已知诈骗证据。
## Docker Compose
包含一个入门级的 [`compose.yaml`](compose.yaml)。
创建一个本地 `.env`;Compose 会通过 `env_file` 将其加载到容器中:
```
cp .env.example .env
```
然后至少填写:
```
DISCORD_TOKEN=your-bot-token
OPENROUTER_API_KEY=optional-default-key
API_KEY_ENCRYPTION_KEY=base64-encoded-32-byte-key
GLOBAL_AUTH_MODE=team
GLOBAL_AUTH_TEAM_ID=your-discord-app-team-id
```
启动机器人:
```
docker compose up -d
```
查看日志:
```
docker compose logs -f honeybot
```
更新:
```
docker compose pull
docker compose up -d
```
## Kubernetes / Helm
本节特意写得足够简短,以便也能在 Docker Hub 上很好地展示:镜像用户无需深入挖掘代码库即可看到 Helm 安装路径。完整的 chart 文档位于 [`charts/honeybot/README.md`](charts/honeybot/README.md)。
使用 Helm 安装:
```
helm upgrade --install honeybot ./charts/honeybot \
--namespace honeybot --create-namespace \
--set image.repository=miacx/honeybot \
--set image.tag=latest \
--set secrets.discordToken='your-bot-token' \
--set secrets.openrouterApiKey='optional-default-key' \
--set secrets.apiKeyEncryptionKey='base64-encoded-32-byte-key' \
--set env.GLOBAL_AUTH_TEAM_ID='your-discord-app-team-id'
```
原始 k3s 入门清单:
```
kubectl apply -f k8s/honeybot.yaml
```
Kubernetes 注意事项:
- 保持 `replicaCount: 1`;Honeybot 在单写入器卷上使用 SQLite。
- Helm chart 使用 `Recreate` 滚动更新策略,以避免在升级期间出现两个 pod 同时写入 SQLite 的情况。
- Pod 以 UID/GID `10001` 运行,并且 chart 设置了 `fsGroup: 10001` 以确保 PVC 的可写性。
## 配置
Honeybot 从 `process.env` 读取普通的环境变量。Docker、Compose、Kubernetes ConfigMaps 和 Kubernetes Secrets 都可以在没有任何特殊适配器的情况下工作。
注意事项:
- `DISCORD_TOKEN` 是唯一必需的变量。
- 对于可选值,空字符串被视为省略。
- 逗号分隔的变量会忽略空白条目。
- 布尔值接受 `true/false`、`1/0`、`yes/no` 和 `on/off`。
- 部署服务器默认值仅影响新初始化的服务器配置。现有的 SQLite 服务器设置不会被覆盖。
### 核心运行时
| 变量 | 省略时的默认值 | 作用 |
| --- | --- | --- |
| `DISCORD_TOKEN` | **必需** | 来自开发者门户的 Discord 机器人 token。 |
| `LOG_LEVEL` | `info` | 日志详细程度:`debug`、`info`、`warn` 或 `error`。 |
| `DATABASE_URL` | `file:data/honeybot.sqlite` | 用于持久化机器人状态的 SQLite 数据库 URL。 |
| `IMAGE_STORAGE_DRIVER` | `filesystem` | 证据/图像存储后端。目前仅支持 `filesystem`。 |
| `IMAGE_STORAGE_DIR` | `data/images` | 使用文件系统存储时存放证据图像的目录。 |
| `API_KEY_ENCRYPTION_KEY` | 未设置 | 用于加密服务器 BYOK 模型 API key 的 Base64 32 字节密钥。丢失它将导致存储的密钥无法恢复。 |
| `OPENROUTER_API_KEY` | 未设置 | 部署默认的 OpenRouter API key。服务器 BYOK 密钥可以针对不同用途覆盖此项。 |
| `EVAL_CORPUS_DIR` | 未设置 | 用于评估脚本的可选本地/私有测试用例库目录。 |
### 模型默认值
| 变量 | 省略时的默认值 | 作用 |
| --- | --- | --- |
| `DEFAULT_TEXT_PRIMARY_PROVIDER` | `openrouter` | 主纯文本诈骗分类器使用的提供商。 |
| `DEFAULT_TEXT_PRIMARY_MODEL` | `google/gemma-4-31b-it` | 主纯文本诈骗分类器使用的模型 ID。 |
| `DEFAULT_IMAGE_PRIMARY_PROVIDER` | `openrouter` | 主多模态图像分类器使用的提供商。 |
| `DEFAULT_IMAGE_PRIMARY_MODEL` | `google/gemma-4-31b-it` | 主多模态图像分类器使用的模型 ID。 |
| `ADDITIONAL_TEXT_SIGNAL_PROVIDER` | `openrouter` | 可选的参考性文本分类器提供商。 |
| `ADDITIONAL_TEXT_SIGNAL_MODELS` | 空列表 | 以逗号分隔的参考性文本分类器模型 ID。参考性信号不会独立触发自动处罚。 |
| `ADDITIONAL_IMAGE_SIGNAL_PROVIDER` | `openrouter` | 可选的参考性图像分类器提供商。 |
| `ADDITIONAL_IMAGE_SIGNAL_MODELS` | 空列表 | 以逗号分隔的参考性图像分类器模型 ID。参考性信号不会独立触发自动处罚。 |
| `DEFAULT_TEXT_EMBEDDINGS_PROVIDER` | `openrouter` | 用于文本 embedding 的提供商。 |
| `DEFAULT_TEXT_EMBEDDINGS_MODEL` | `nvidia/llama-nemotron-embed-vl-1b-v2:free` | 用于文本 embedding 和文本语料库向量的模型 ID。 |
| `DEFAULT_IMAGE_EMBEDDINGS_PROVIDER` | `openrouter` | 用于图像 embedding 的提供商。 |
| `DEFAULT_IMAGE_EMBEDDINGS_MODEL` | `nvidia/llama-nemotron-embed-vl-1b-v2:free` | 用于图像 embedding 和图像语料库向量的模型 ID。 |
| `DEFAULT_EMBEDDINGS_DIMENSIONS` | `2048` | 预期的 embedding 向量大小。Nemotron 返回固定的 2048 维向量。 |
### 速率限制和重试
| 变量 | 省略时的默认值 | 作用 |
| --- | --- | --- |
| `MODEL_CALL_LIMIT` | `6000` | 部署级别的模型/提供商调用滚动窗口限制。 |
| `MODEL_CALL_LIMIT_PER_GUILD` | `20` | 每服务器模型/提供商调用滚动窗口限制。 |
| `MODEL_CALL_WINDOW_SECONDS` | `60` | 模型调用限制的滚动窗口持续时间。 |
| `MODEL_RETRY_MAX_ATTEMPTS` | `3` | 针对瞬时模型/提供商故障的最大重试次数。 |
| `MODEL_RETRY_INITIAL_DELAY_MS` | `300` | 模型重试的初始指数退避延迟。 |
| `MODEL_RETRY_MAX_DELAY_MS` | `15000` | 模型重试的最大指数退避延迟。 |
| `MODERATION_ACTION_LIMIT` | `30` | 部署级别的 Discord 审核操作滚动窗口限制。 |
| `MODERATION_ACTION_LIMIT_PER_GUILD` | `10` | 每服务器 Discord 审核操作滚动窗口限制。 |
| `MODERATION_ACTION_WINDOW_SECONDS` | `60` | 审核操作限制的滚动窗口持续时间。 |
### 全局管理员授权
| 变量 | 省略时的默认值 | 作用 |
| --- | --- | --- |
| `GLOBAL_AUTH_MODE` | `team` | 全局管理模式:`team` 检查 Discord 开发者团队成员资格;`users` 检查 `GLOBAL_AUTH_USER_IDS`。 |
| `GLOBAL_AUTH_TEAM_ID` | 未设置 | 当 `GLOBAL_AUTH_MODE=team` 时使用的 Discord 开发者团队 ID。 |
| `GLOBAL_AUTH_USER_IDS` | 空字符串 | 当 `GLOBAL_AUTH_MODE=users` 时,被授予全局权限的以逗号分隔的 Discord 用户 ID。 |
### 新服务器的部署默认值
| 变量 | 省略时的默认值 | 作用 |
| --- | --- | --- |
| `HONEYBOT_DEFAULT_MODERATION_CHANNEL_ID` | 未设置 | 默认的审核/案件推送频道 ID。 |
| `HONEYBOT_DEFAULT_HONEYPOT_CHANNEL_IDS` | 空列表 | 以逗号分隔的默认蜜罐频道 ID。 |
| `HONEYBOT_DEFAULT_MODERATOR_USER_IDS` | 空列表 | 以逗号分隔的默认案件审核员用户 ID。 |
| `HONEYBOT_DEFAULT_MODERATOR_ROLE_IDS` | 空列表 | 以逗号分隔的默认案件审核员角色 ID。 |
| `HONEYBOT_DEFAULT_CROSSCHANNEL_ENABLED` | `true` | 为新初始化的服务器启用跨频道重复内容触发。 |
| `HONEYBOT_DEFAULT_CROSSCHANNEL_MINIMUM_WINDOW_SECONDS` | `5` | 2 个频道阈值下的最小跨频道匹配窗口。 |
| `HONEYBOT_DEFAULT_CROSSCHANNEL_WINDOW_SECONDS` | `3600` | 最大/渐近跨频道匹配窗口。 |
| `HONEYBOT_DEFAULT_CROSSCHANNEL_WINDOW_STEEPNESS` | `0.49` | 归一化逻辑跨频道窗口曲线的陡度。 |
| `HONEYBOT_DEFAULT_CROSSCHANNEL_WINDOW_MIDPOINT_CHANNELS` | `13` | 跨频道窗口曲线中点处的频道数量。 |
| `HONEYBOT_DEFAULT_CROSSCHANNEL_CHANNEL_THRESHOLD` | `2` | 触发跨频道检测所需的频道数量。 |
| `HONEYBOT_DEFAULT_KNOWN_IMAGE_SIMILARITY_THRESHOLD` | `0.92` | 已知图像证据匹配的相似度阈值。 |
| `HONEYBOT_DEFAULT_KNOWN_TEXT_SIMILARITY_THRESHOLD` | `0.82` | 已知文本证据匹配的相似度阈值。 |
| `HONEYBOT_DEFAULT_EVIDENCE_CONFIDENCE_THRESHOLD` | `0.90` | 跳过审查自动处罚使用的置信度阈值。 |
| `HONEYBOT_DEFAULT_AUTO_PUNISH_ENABLED` | `false` | 为新初始化的服务器启用跳过审查自动处罚。 |
| `HONEYBOT_DEFAULT_PUNISHMENT_DM_NOTIFY` | `true` | 在应用非日志操作前要求确认处罚 DM。 |
| `HONEYBOT_DEFAULT_RETENTION_CASE_DAYS` | `180` | 以天为单位的案件/证据保留持续时间。 |
| `HONEYBOT_DEFAULT_CROSSCHANNEL_MAX_ENTRIES_PER_GUILD` | `10000` | 每个服务器缓存的最大跨频道检测器条目数。 |
| `HONEYBOT_DEFAULT_CROSSCHANNEL_MAX_ENTRIES_PER_USER` | `200` | 每个用户缓存的最大跨频道检测器条目数。 |
| `HONEYBOT_DEFAULT_GLOBAL_BANS_ENABLED` | `false` | 让新初始化的服务器参与全局封禁执行。 |
### 新服务器的策略默认值
操作:
- 预防操作:`log`、`timeout`、`role`、`kick`、`ban`
处罚操作:`timeout`、`role`、`kick`、`ban`
- 持续时间以秒为单位;对于无持续时间,请使用 `null` 或 `none`。
| 变量 | 省略时的默认值 | 作用 |
| --- | --- | --- |
| `HONEYBOT_DEFAULT_HONEYPOT_PREVENTION_ACTION` | `timeout` | 蜜罐触发后的即时预防操作。 |
| `HONEYBOT_DEFAULT_HONEYPOT_PREVENTION_DURATION_SECONDS` | `21600` | 蜜罐禁言/临时角色操作的持续时间。 |
| `HONEYBOT_DEFAULT_HONEYPOT_PREVENTION_ROLE_ID` | 未设置 | 当蜜罐预防操作为 `role` 时使用的角色 ID。 |
| `HONEYBOT_DEFAULT_HONEYPOT_PREVENTION_DELETE_MESSAGES` | `true` | 在蜜罐预防后删除触发消息。 |
| `HONEYBOT_DEFAULT_CROSSCHANNEL_PREVENTION_ACTION` | `timeout` | 跨频道触发后的即时预防操作。 |
| `HONEYBOT_DEFAULT_CROSSCHANNEL_PREVENTION_DURATION_SECONDS` | `1800` | 跨频道禁言/临时角色操作的持续时间。 |
| `HONEYBOT_DEFAULT_CROSSCHANNEL_PREVENTION_ROLE_ID` | 未设置 | 当跨频道预防操作为 `role` 时使用的角色 ID。 |
| `HONEYBOT_DEFAULT_CROSSCHANNEL_PREVENTION_DELETE_MESSAGES` | `true` | 在跨频道预防后删除重复的触发消息。 |
| `HONEYBOT_DEFAULT_PUNISHMENT_ACTION` | `ban` | 审核员批准或跳过审查后的最终处罚操作。 |
| `HONEYBOT_DEFAULT_PUNISHMENT_DURATION_SECONDS` | `null` | 最终禁言/临时角色处罚的持续时间。 |
| `HONEYBOT_DEFAULT_PUNISHMENT_ROLE_ID` | 未设置 | 当最终处罚操作为 `role` 时使用的角色 ID。 |
| `HONEYBOT_DEFAULT_PUNISHMENT_DELETE_MESSAGES` | `true` | 在执行最终处罚时删除保留的案件消息。 |
## 镜像标签
镜像版本号源自 `package.json`。
稳定版本 `1.2.3` 发布:
- `v1.2.3`
- `v1.2`
- `v1`
- `latest`
- `sha-...`
Beta 版本 `1.2.3-beta` 发布:
- `v1.2.3-beta`
- `v1.2-beta`
- `v1-beta`
- `beta`
- `sha-...`
本地构建:
```
docker build -f docker/Dockerfile -t honeybot:local .
```
## 开发
```
pnpm dev # run with tsx watch
pnpm typecheck # type-check only
pnpm build # emit dist/
pnpm start # run dist/src/index.js
pnpm lint # lint source
pnpm test # unit tests
pnpm eval:fixtures # run classifier fixture evals
pnpm seed:fixtures # seed fixture evidence corpus
```
GitHub Actions 会在 PR 和推送到 `main` 分支时运行 CI。容器构建在推送到 `main` 分支时,会将多架构的 `linux/amd64` 和 `linux/arm64` 镜像发布到 GHCR 和 Docker Hub。
## 文档
- [`docs/SPEC.md`](docs/SPEC.md) — 产品和架构说明
- [`docs/PLAN.md`](docs/PLAN.md) — 实施计划和 schema 说明
- [`PRIVACY.md`](PRIVACY.md) — 隐私政策
- [`TERMS.md`](TERMS.md) — 服务条款
标签:Discord, GNU通用公共许可证, Naabu, Node.js, SQLite, 内容安全, 反欺诈, 多模态AI, 子域名突变, 自动化攻击, 请求拦截