一个部署在 Cloudflare Workers 上的智能 Telegram Bot,提供 AI 驱动的垃圾信息过滤和管理员消息转发功能。
Telegram Watchdog 是一个功能强大的 Telegram 机器人,主要用于:
- AI 垃圾信息检测:使用 LLM(大语言模型)自动识别和过滤垃圾信息、广告、诈骗等不良内容
- 智能白名单系统:自动识别可信用户,减少 AI 检测成本并提升用户体验
- 管理员消息中继:自动将用户私聊消息转发给管理员,并支持管理员回复功能
- 实时监控:检测到垃圾信息时自动转发到管理群组,提供详细的分析报告
- 🤖 AI 智能过滤:基于 LLM 的智能垃圾信息识别
- ✅ 自动白名单:用户连续通过 3 次检测后自动加入白名单,跳过后续 AI 检测
- 👮 管理员命令:支持
/trust、/untrust和/getid命令 - 💬 双向消息转发:用户消息转发给管理员,管理员可直接回复
- 🧵 Forum Topic 管理:自动为每个用户创建独立 Topic,垃圾消息集中到 Spam Topic
- 🗄️ 持久化存储:使用 Cloudflare D1 数据库存储消息映射和用户信任度
- ⚡ 边缘计算:部署在 Cloudflare Workers,全球低延迟响应
- 🔒 安全验证:Webhook 请求使用密钥验证,确保安全性
- Hono - 轻量级 Web 框架,专为 Cloudflare Workers 优化
- Grammy - 现代化的 Telegram Bot 框架
- OpenAI SDK - 用于调用 LLM API 进行垃圾信息检测
- Cloudflare Workers - Serverless 计算平台
- Cloudflare D1 - 边缘 SQLite 数据库
- TypeScript - 类型安全的开发语言
- Wrangler - Cloudflare Workers CLI 工具
-
Telegram Bot Token
- 通过 @BotFather 创建 Bot 并获取 Token
-
Cloudflare 账户
- Workers 服务(免费版即可开始)
- D1 数据库(免费版提供 5GB 存储)
- 自定义域名(用于 Webhook,Workers 默认域名也可用)
-
LLM API 服务
- OpenAI API 或兼容的 API 服务
- 需要 API Key 和 Base URL
- 管理员 Telegram 账户:用于接收转发消息
- 管理群组:用于接收垃圾信息警报
telegram-watchdog/
├── src/
│ ├── index.ts # 主入口文件,Hono 应用和 Bot 初始化
│ ├── env.ts # TypeScript 环境变量类型定义
│ ├── config.ts # 白名单系统配置常量
│ ├── bot/
│ │ ├── command.ts # Bot 命令处理器(/start 等)
│ │ ├── commands.ts # 管理员命令(/trust、/untrust、/getid)
│ │ ├── middleware.ts # 垃圾信息过滤和白名单检查中间件
│ │ ├── message.ts # 消息转发处理器
│ │ └── forum.ts # Forum Topic 管理
│ ├── llm/
│ │ ├── client.ts # LLM API 客户端和垃圾信息检测
│ │ └── prompt.ts # LLM 提示词模板
│ └── db/
│ ├── init.ts # D1 数据库初始化和清理
│ ├── trust.ts # 用户信任度数据库操作
│ └── topics.ts # Forum Topic 数据库操作
├── package.json # 项目依赖配置
├── wrangler.jsonc # Cloudflare Workers 配置
├── tsconfig.json # TypeScript 配置
└── README.md # 项目说明文档
- src/index.ts:应用入口,配置 Hono 路由和 Grammy Bot,实现懒加载初始化
- src/config.ts:白名单系统配置,包括自动晋升阈值等参数
- src/bot/middleware.ts:拦截所有消息,检查白名单状态并调用 LLM 进行垃圾信息检测
- src/bot/commands.ts:处理管理员命令(
/trust、/untrust、/getid) - src/bot/message.ts:处理用户与管理员之间的消息转发逻辑
- src/bot/forum.ts:Forum Topic 创建和管理,支持用户 Topic 名称自动更新
- src/llm/client.ts:封装 OpenAI SDK,提供统一的 LLM 调用接口
- src/db/init.ts:创建和维护 D1 数据库表结构
- src/db/trust.ts:用户信任度相关的数据库操作
- src/db/topics.ts:Forum Topic 映射相关的数据库操作
graph TD
A[用户发送消息到 Bot] --> B{是否为命令?}
B -->|是| C[跳过过滤]
B -->|否| D[查询用户信任状态]
D --> E{是否为白名单用户?}
E -->|是| F[直接转发,跳过 AI 检测]
E -->|否| G[垃圾信息检测中间件]
G --> H[调用 LLM API 分析]
H --> I{是否为垃圾信息?}
I -->|是| J[记录垃圾信息]
J --> K[转发到管理群组]
K --> L[警告发送者]
L --> M[阻止消息继续传递]
I -->|否| N[增加连续通过次数]
N --> O{是否达到白名单条件?}
O -->|是| P[自动加入白名单]
P --> Q[可选通知管理员]
O -->|否| R[继续监控]
Q --> S[进入消息处理器]
R --> S
F --> S
S --> T{是否为私聊?}
T -->|是| U[转发消息给管理员]
U --> V[保存消息映射到 D1]
T -->|否| W[忽略群组消息]
C --> S
graph TD
A[管理员回复转发的消息] --> B{是否在回复消息?}
B -->|否| C[提示需要回复消息]
B -->|是| D[从 D1 查询原始用户 ID]
D --> E{找到映射?}
E -->|否| F[提示未找到映射]
E -->|是| G[发送回复给原始用户]
G --> H[回复成功]
用户消息 → 提取发送者姓名和消息内容
↓
填充提示词模板
↓
调用 LLM API 判断
↓
解析返回结果
↓
┌─────────────┬─────────────┐
│ SPAM:原因 │ CLEAN │
↓ ↓
垃圾信息 正常消息
白名单系统通过追踪用户的历史行为,自动识别可信用户并跳过 AI 检测,从而降低 API 成本并提升用户体验。
系统为每个用户维护以下状态:
new(新用户):首次发送消息或曾被标记为垃圾的用户,每条消息都需要 AI 检测trusted(白名单用户):已通过验证的可信用户,消息直接转发,完全跳过 AI 检测monitoring(监控中):曾被标记为垃圾但正在重新积累信任的用户
用户满足以下条件后会自动加入白名单:
- 连续通过 3 次 AI 垃圾信息检测
- 从未被标记为垃圾信息(
total_spam_count = 0)
加入白名单后:
- 用户的所有后续消息直接转发,不再消耗 AI API 配额
- 可选择通知管理员(可在
src/config.ts中配置)
管理员可以通过以下命令手动管理用户信任度:
使用方法:
- 在转发的用户消息下回复
- 输入
/trust - 该用户立即加入白名单,无需等待自动验证
示例:
[转发的用户消息]
↓ 回复
/trust
↓ Bot 响应
✅ 用户已手动加入白名单
使用方法:
- 在转发的用户消息下回复
- 输入
/untrust - 该用户被移出白名单,重新进入监控状态
效果:
- 用户的
trust_status变为new consecutive_clean_count重置为 0total_spam_count增加 1(防止短期内再次自动加白)- 后续消息需重新通过 AI 检测
示例:
[转发的用户消息]
↓ 回复
/untrust
↓ Bot 响应
⚠️ 用户已移除白名单,重新进入监控
使用方法:
在任意聊天中发送 /getid
返回信息:
- 你的用户 ID
- 当前聊天 ID
- 聊天类型
- Topic ID(如果在 Forum Topic 内)
示例:
/getid
↓ Bot 响应
📋 ID 信息
👤 你的用户 ID: `123456789`
💬 当前聊天 ID: `-1001234567890`
📝 聊天类型: supergroup
🧵 Topic ID: `123`
可以在 src/config.ts 中调整白名单系统的行为:
export const WHITELIST_CONFIG = {
// 自动加白所需的连续通过次数(默认 3)
REQUIRED_CLEAN_COUNT: 3,
// 允许的垃圾消息次数(默认 0 = 从未被标记)
MAX_ALLOWED_SPAM_COUNT: 0,
// 自动加白时是否通知管理员(默认 true)
NOTIFY_ADMIN_ON_AUTO_WHITELIST: true,
};白名单系统使用 user_trust 表存储用户信任度信息:
| 字段 | 类型 | 说明 |
|---|---|---|
user_id |
TEXT | Telegram 用户 ID(主键) |
username |
TEXT | 用户名(可选) |
trust_status |
TEXT | 信任状态(new/trusted/monitoring) |
consecutive_clean_count |
INTEGER | 连续通过 AI 检测的次数 |
total_spam_count |
INTEGER | 累计垃圾消息次数 |
whitelisted_at |
INTEGER | 加入白名单的时间戳 |
whitelisted_by |
TEXT | 加白来源(auto/admin) |
last_message_at |
INTEGER | 最后一条消息的时间戳 |
created_at |
INTEGER | 记录创建时间 |
1. 用户第一次发消息 → AI 检测通过 ✅
状态:consecutive_clean_count = 1
2. 用户第二次发消息 → AI 检测通过 ✅
状态:consecutive_clean_count = 2
3. 用户第三次发消息 → AI 检测通过 ✅
状态:自动升级为 trusted
管理员收到通知:"✅ 用户 xxx 已自动加入白名单"
4. 用户第四次发消息 → 直接转发 🚀
不再调用 AI API
1. 用户发送 2 条正常消息 → consecutive_clean_count = 2
2. 用户发送垃圾消息 → AI 检测为 SPAM ⚠️
状态:consecutive_clean_count = 0(重置)
total_spam_count = 1
trust_status = monitoring
3. 用户重新发送正常消息 → 从 1 开始重新计数
需要再连续通过 3 次才能加白
1. 用户发送第一条消息
2. 管理员认为用户可信,回复 /trust
→ 用户立即加入白名单,无需等待
3. 后续消息直接转发
4. 管理员发现用户发送问题内容,回复 /untrust
→ 用户被移出白名单
5. 用户下次发消息 → 重新进入 AI 检测
当配置了 ADMIN_GID(管理群组)且该群组启用了 Forum 功能时,Bot 会自动使用 Topic 来组织消息:
- Spam Topic:所有垃圾消息集中在
🚨 SpamTopic 中 - 用户 Topic:每个用户拥有独立的
👤 用户名Topic
-
创建 Forum 群组:
- 创建一个超级群组
- 在群组设置中启用 "Topics"(话题)功能
-
Bot 权限:
- 将 Bot 添加为群组管理员
- 确保 Bot 拥有
can_manage_topics权限
用户发送垃圾消息
↓
AI 检测为 SPAM
↓
检查/创建 "🚨 Spam" Topic
↓
将消息转发到 Spam Topic
↓
发送警告信息到同一 Topic
用户发送正常消息
↓
检查用户是否已有 Topic
↓
├─ 无 → 创建 "👤 用户名" Topic
└─ 有 → 检查用户名是否变更,自动更新 Topic 名称
↓
将消息转发到用户的 Topic
管理员在用户 Topic 内发送消息
↓
Bot 自动识别 Topic 对应的用户
↓
将消息发送给该用户
- 直接发消息:在用户 Topic 内直接打字即可发送给用户,无需回复特定消息
- 用户名自动更新:当用户修改昵称后,Topic 名称会自动同步更新
- 回退机制:如果 Topic 创建失败(权限不足等),自动回退到普通消息发送
| 字段 | 类型 | 说明 |
|---|---|---|
topic_type |
TEXT | Topic 类型(如 spam)(主键) |
topic_id |
INTEGER | Telegram Topic ID |
created_at |
INTEGER | 创建时间戳 |
| 字段 | 类型 | 说明 |
|---|---|---|
user_id |
TEXT | 用户 Telegram ID(主键) |
topic_id |
INTEGER | 用户专属 Topic ID |
topic_name |
TEXT | Topic 名称 |
created_at |
INTEGER | 创建时间戳 |
安装 Node.js 和 npm
# 检查是否已安装
node --version
npm --version
# 如未安装,请访问 https://nodejs.org/ 下载安装
# 推荐使用 Node.js 18.x 或更高版本# 克隆项目(或下载源码)
git clone <your-repo-url>
cd telegram-watchdog
# 安装项目依赖
npm install# 部署到 Cloudflare Workers
# 第一次运行会出现登录链接,浏览器打开后授权登录,再重新运行命令
npm run deploy
# 部署成功后,会输出 Worker 的 URL
# 例如:https://telegram-watchdog.your-account.workers.dev- 在 Telegram 中找到 @BotFather
- 发送
/newbot命令创建新 Bot - 按提示设置 Bot 名称和用户名
- 保存 BotFather 返回的 Bot Token(格式如:
123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11)
-
获取管理员用户 ID:
- 在 Telegram 中找到 @userinfobot
- 发送任意消息,Bot 会返回你的用户 ID
-
获取管理群组 ID(可选,推荐启用 Forum Topic 功能):
- 创建一个超级群组
- 在群组设置中启用 "Topics"(话题)功能
- 将 Bot 添加到群组并设为管理员(需要
can_manage_topics权限) - 在群组内发送
/getid,Bot 会返回群组 ID(负数,如:-1001234567890)
- 在 Cloudflare 控制面板中,导航至 D1 SQL 数据库页面
- 选择“创建数据库”
- 数据库命名为
watchdog - 点击创建
- 在 Cloudflare 仪表板中,转到 Workers & Pages 页面
- 在“概览”中,选择您的 Worker
- 选择"设置"
- 在"变量和机密"下,选择"添加"
- 选择"密钥"类型,输入一个变量名,并输入其值
| 变量名 | 必需 | 说明 | 示例 |
|---|---|---|---|
DOMAIN |
✅ | Worker 部署域名 | https://bot.example.com |
BOT_TOKEN |
✅ | Telegram Bot Token | 123456:ABC-DEF... |
BOT_SECRET |
✅ | Webhook 验证密钥 | 任意随机字符串 |
ADMIN_UID |
✅ | 管理员 Telegram 用户 ID | 123456789 |
ADMIN_GID |
❌ | 管理群组 ID(启用 Forum 功能可使用 Topic) | -1001234567890 |
LLM_API |
✅ | LLM API Base URL | https://api.openai.com/v1 |
LLM_MODEL |
✅ | LLM 模型名称 | gpt-3.5-turbo |
LLM_KEY |
✅ | LLM API Key | sk-... |
-
检查 Webhook 是否设置成功:
- 访问:
https://api.telegram.org/bot<你的BOT_TOKEN>/getWebhookInfo - 检查
url字段是否为你的 Worker URL +/webhook
- 访问:
-
测试 Bot 功能:
- 在 Telegram 中向 Bot 发送消息
- 检查是否收到管理员转发
- 尝试回复转发的消息,检查是否发送给原始用户
-
测试垃圾信息检测:
- 发送明显的广告或垃圾信息
- 检查管理群组是否收到警报
- 检查 Webhook 设置:访问
https://api.telegram.org/bot<TOKEN>/getWebhookInfo - 查看 Cloudflare Workers 日志:
wrangler tail - 确认环境变量配置正确
- 检查 LLM API 配置(URL、Key、Model)
- 查看 Worker 日志确认 API 调用是否成功
- 测试 API 是否可访问:
curl -H "Authorization: Bearer $LLM_KEY" $LLM_API/models
- 确认消息映射已保存到 D1(检查数据库)
- 确认管理员在回复转发的消息,而不是直接发送新消息
- 检查原始用户是否屏蔽了 Bot