一个基于 Node.js 的 Telegram Bot,配合验证服务使用,为 Telegram 群组提供自动化的入群验证功能。当新成员加入群组时,Bot 会自动限制其权限并发送验证链接,验证通过后自动恢复权限。
本项目是 Telegram 群组入群验证系统的 Bot 端实现,负责:
- 🔍 监听群组成员变化
- 🔒 限制新成员权限
- 📨 发送验证链接
- ✅ 验证通过后恢复权限
- ⏰ 超时自动踢出
- 👮 管理员快速通过/拒绝
-
自动化验证流程
- 新成员加入时自动触发
- 限制权限防止垃圾消息
- 发送验证链接到私聊
- 支持验证链接续期
-
管理员功能
- 直接通过验证
- 封禁/踢出选项
- 操作确认机制
-
用户体验
- 清晰的中文提示
- 步骤式引导
- 超时提醒
- 结果消息自动清理
-
安全特性
- 防止验证链接被盗用
- 账号身份一致性验证
- 会话过期保护
- 限流保护
- 语言: Node.js 20+
- Bot 框架: Telegraf 4.16+
- HTTP 客户端: Node.js 原生 http/https
- 存储: 内存(Map)
tg_bot/
├── index.js # 程序入口
├── package.json # 依赖配置
├── .env.example # 环境变量示例
├── src/
│ ├── bot.js # Bot 实例和路由配置
│ ├── config.js # 配置加载
│ ├── http.js # HTTP 客户端
│ └── verification/
│ ├── api.js # 验证服务 API 客户端
│ ├── flow.js # 验证流程逻辑
│ ├── store.js # 内存存储
│ ├── messages.js # 消息文本和键盘
│ └── permissions.js # 权限配置
└── test/ # 测试文件
- Node.js 20 或更高版本
- npm 或 yarn
- Telegram Bot Token(从 @BotFather 获取)
- 已部署的验证服务(verification_go)
- 克隆项目
git clone <repository-url>
cd tg_bot- 安装依赖
npm install- 配置环境变量
复制 .env.example 为 .env 并填写配置:
cp .env.example .env编辑 .env 文件:
# Bot Token(从 @BotFather 获取)
BOT_TOKEN=123456789:ABCdefGHIjklMNOpqrsTUVwxyz
# 验证服务地址(不带末尾斜杠)
VERIFY_API_BASE_URL=https://verify.example.com
# 验证服务客户端密钥(与验证服务 TRUSTED_CLIENT_KEYS 中的一项匹配)
VERIFY_CLIENT_KEY=your-client-key-here
# 启用验证的群组 ID(逗号分隔,必须是 supergroup)
# 可以通过 @userinfobot 或 @getidsbot 获取群组 ID
ENABLED_CHAT_IDS=-1001234567890,-1001234567891
# 验证超时秒数(超时未验证则踢出,默认 300 秒)
VERIFY_TIMEOUT_SECONDS=300
# 结果消息保留时间(秒,0 表示永久保留,默认 120 秒)
VERIFY_RESULT_TTL_SECONDS=120- 配置 Bot 权限
在 @BotFather 中配置:
/mybots -> 选择你的 Bot -> Bot Settings
设置以下权限:
- Allow Groups? -> Enable(允许加入群组)
- Group Privacy -> Disable(关闭隐私模式,让 Bot 能接收消息)
- 将 Bot 添加到群组
- 将 Bot 添加为群组管理员
- 必需权限:
- ✅ 删除消息
- ✅ 封禁用户
- ✅ 限制成员
- 运行 Bot
npm start成功启动后会看到:
Bot 已启动: @YourBotUsername
-
新成员加入
- Bot 检测到
chat_member事件 - 立即限制新成员所有权限(禁言)
- 在群里发送欢迎消息(@提及新成员)
- 设置超时计时器
- Bot 检测到
-
用户点击验证按钮
- 打开与 Bot 的私聊
- Bot 调用验证服务创建会话
- 发送验证页面链接
- 用户在页面完成验证
-
用户确认验证完成
- 用户在私聊点击"我已完成验证"
- Bot 查询验证服务获取状态
- 验证通过:恢复权限,删除欢迎消息
- 验证失败:提示错误原因
-
超时处理
- 计时器到期,用户仍未验证
- Bot 踢出该用户(可重新加入)
- 删除欢迎消息
- 私聊通知用户超时
👋 欢迎 [用户名] 加入!
本群开启了入群验证,你当前无法发言。请点击下方按钮完成验证
(限时 5 分钟,超时将被移出本群)。
[🔐 点此完成入群验证] [✅ 直接通过] [❌ 拒绝该用户]
请按顺序完成验证:
1️⃣ 点「打开验证页面」,在页面上完成人机校验与 Telegram 登录
2️⃣ 回到这里点「我已完成验证」
会话异常、链接过期或验证账号不对时,点「重新获取链接」(每分钟最多一次)。
⚠️ 页面登录必须使用当前这个账号,否则验证不会通过。
⏳ 请在 5 分钟内完成。
[🌐 打开验证页面] [✅ 我已完成验证]
[🔄 重新获取链接]
管理员可以在群组欢迎消息上直接操作:
- ✅ 直接通过:跳过验证,立即恢复权限
- ❌ 拒绝该用户:显示确认菜单
- 🚫 封禁:永久禁止加入本群
- 👢 踢出:移出本群,之后可以重新加入
- ↩️ 取消:取消操作
用户可以在私聊中点击"🔄 重新获取链接":
- 显示确认提示(说明当前链接会失效)
- 用户确认后,获取新的会话和链接
- 更新私聊消息,显示新链接
- 限流:每分钟最多获取一次
Bot 通过 HTTP API 与验证服务通信。
const response = await api.createSession();
// 返回: { sessionId, verifyUrl, expiresAt }const status = await api.getSessionStatus(sessionId);
// 返回: { status: 'pending' | 'verified' | 'expired', userId?, userName? }try {
await api.createSession();
} catch (error) {
if (error.code === 'UNAVAILABLE') {
// 验证服务不可用
} else if (error.code === 'RATE_LIMITED') {
// 请求过于频繁
}
}| 变量名 | 说明 | 默认值 | 必填 |
|---|---|---|---|
BOT_TOKEN |
Telegram Bot Token | - | 是 |
VERIFY_API_BASE_URL |
验证服务地址 | - | 是 |
VERIFY_CLIENT_KEY |
客户端密钥 | - | 是 |
ENABLED_CHAT_IDS |
启用验证的群组 ID(逗号分隔) | - | 是 |
VERIFY_TIMEOUT_SECONDS |
验证超时时间(秒) | 300 |
否 |
VERIFY_RESULT_TTL_SECONDS |
结果消息保留时间(秒,0=永久) | 120 |
否 |
有几种方式获取群组 ID:
-
使用机器人
- 将 @userinfobot 或 @getidsbot 加入群组
- 发送任意消息,Bot 会返回群组 ID
-
通过 Telegram Web
- 在浏览器打开群组
- URL 中的数字即为群组 ID(加上
-100前缀)
-
通过 Bot 日志
- 将 Bot 加入群组
- 查看日志中的
chat_member事件
注意:群组 ID 必须是负数(如 -1001234567890),且必须是 supergroup 类型。
-
快速验证:180-300 秒(3-5 分钟)
- 适合活跃群组,要求用户快速响应
- 优点:减少机器人停留时间
- 缺点:部分真实用户可能超时
-
标准验证:300-600 秒(5-10 分钟)
- 平衡用户体验和防护效果
- 适合大多数场景
-
宽松验证:600-900 秒(10-15 分钟)
- 给用户更多时间
- 适合面向新手或国际用户的群组
-
自动清理(推荐):60-180 秒
- 验证完成后短暂显示结果,然后自动删除
- 保持群组整洁
- 避免垃圾消息积累
-
永久保留:0 秒
- 不删除结果消息
- 适合需要审计记录的群组
- 缺点:群组消息较多
详细的部署说明请参考 DEPLOYMENT.md。
- 创建 Dockerfile:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
USER node
CMD ["node", "index.js"]- 构建并运行:
docker build -t telegram-bot .
docker run -d --env-file .env --name tg-bot telegram-bot# 安装 PM2
npm install -g pm2
# 启动 Bot
pm2 start index.js --name telegram-bot
# 查看状态
pm2 status
# 查看日志
pm2 logs telegram-bot
# 设置开机自启
pm2 startup
pm2 save创建 /etc/systemd/system/telegram-bot.service:
[Unit]
Description=Telegram Verification Bot
After=network.target
[Service]
Type=simple
User=telegram
WorkingDirectory=/opt/telegram-bot
EnvironmentFile=/opt/telegram-bot/.env
ExecStart=/usr/bin/node index.js
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target启动服务:
sudo systemctl daemon-reload
sudo systemctl enable telegram-bot
sudo systemctl start telegram-botBot 输出结构化日志到 stdout:
[verify][join] pending verification for user 123456789 in chat -1001234567890
[verify][start] issued session abc123 to user 123456789
[verify][done] user 123456789 verified in chat -1001234567890
[verify][timeout] kicking user 123456789 from chat -1001234567890
[verify][approve] admin 111111 approved user 123456789 in chat -1001234567890
[verify][join]- 新成员加入[verify][leave]- 成员离开[verify][start]- 开始验证[verify][done]- 验证完成[verify][timeout]- 验证超时[verify][approve]- 管理员通过[verify][reject]- 管理员拒绝[verify][renew]- 续期链接[verify][error]- 错误信息
可以从日志中提取以下指标:
- 每日加入人数
- 验证通过率
- 超时率
- 管理员操作次数
- 平均验证时长
设置以下告警:
-
Bot 离线
- 检查进程是否运行
- 检查网络连接
-
大量超时
- 可能是验证服务故障
- 可能是超时时间设置过短
-
大量拒绝
- 可能遭遇机器人攻击
- 考虑临时关闭群组邀请链接
症状:启动后立即退出
检查清单:
# 1. 检查 Node.js 版本
node --version # 应该 >= 20
# 2. 检查依赖
npm install
# 3. 检查配置文件
cat .env
# 4. 测试 Bot Token
curl "https://api.telegram.org/bot<YOUR_TOKEN>/getMe"症状:新成员加入时没有任何反应
检查清单:
-
确认群组 ID 正确
# .env 中的 ENABLED_CHAT_IDS echo $ENABLED_CHAT_IDS
-
确认 Bot 是管理员
- 在群组中检查 Bot 的权限
- 必须有"封禁用户"和"删除消息"权限
-
确认群组类型
- 必须是 supergroup(超级群组)
- 普通群组升级为超级群组:群组设置 > 转换为超级群组
-
检查隐私模式
- 在 @BotFather 中关闭隐私模式
/mybots> 选择 Bot >Bot Settings>Group Privacy>Turn off
症状:Bot 日志显示 create session failed: UNAVAILABLE
检查清单:
# 1. 测试验证服务可达性
curl https://verify.example.com/api/status
# 2. 检查客户端密钥
# 确认 .env 中的 VERIFY_CLIENT_KEY 与验证服务 TRUSTED_CLIENT_KEYS 匹配
# 3. 测试完整 API 调用
curl -X POST https://verify.example.com/api/sessions \
-H "X-Client-Key: your-client-key"症状:用户完成验证但仍然无法发言
可能原因:
-
Bot 权限不足
- 确认 Bot 有"限制成员"权限
- 尝试手动恢复权限测试
-
群组权限设置
- 检查群组是否有特殊的权限限制
- 尝试在测试群组中重现
-
Telegram API 延迟
- 有时需要等待几秒钟
- 让用户尝试退出重进
症状:用户点击验证按钮后没有收到私聊消息
可能原因:
-
用户未启动 Bot
- 用户必须先在私聊中向 Bot 发送
/start - 引导用户点击群消息中的按钮(会自动打开私聊)
- 用户必须先在私聊中向 Bot 发送
-
用户隐私设置
- 用户可能设置了不接收陌生人消息
- 无解,建议提示用户调整隐私设置
症状:用户反馈链接刚打开就过期
解决方案:
-
增加会话 TTL
- 在验证服务的
.env中增加SESSION_TTL_SECONDS - 建议至少 600 秒(10 分钟)
- 在验证服务的
-
使用续期功能
- 引导用户使用"重新获取链接"按钮
-
检查服务器时间
- 确认验证服务和 Bot 服务器时间同步
date timedatectl status
-
密钥管理
- 使用强随机字符串作为
VERIFY_CLIENT_KEY - 不要将
.env文件提交到版本控制 - 定期轮换密钥
- 使用强随机字符串作为
-
访问控制
- 仅在需要的群组中启用验证
- 定期审查
ENABLED_CHAT_IDS
-
监控异常
- 监控大量失败的验证尝试
- 监控异常的 API 错误率
- 设置告警通知
-
防止滥用
- 验证服务端已有限流保护
- Bot 端也有续期限流(每分钟一次)
-
用户隐私
- 验证完成后删除欢迎消息
- 不要记录敏感的用户信息
- 遵守 GDPR 等隐私法规
npm test项目使用 ES Modules("type": "module"),确保:
- 使用
import/export而不是require/module.exports - 文件扩展名必须是
.js且在 import 时包含扩展名
-
修改消息文本
- 编辑
src/verification/messages.js
- 编辑
-
调整验证流程
- 编辑
src/verification/flow.js
- 编辑
-
添加新的 API 端点
- 编辑
src/verification/api.js
- 编辑
-
修改存储逻辑
- 编辑
src/verification/store.js
- 编辑
- telegraf: Telegram Bot 框架,提供事件处理和 API 封装
- 无其他外部依赖: 使用 Node.js 原生模块(http, https, crypto)
- 每个待验证的成员占用约 1KB 内存
- 1000 个并发验证 ≈ 1MB 内存
- 对于大型群组,考虑使用外部存储(Redis)
- Bot 使用单进程架构
- Telegram 限制:每秒 30 条消息
- 对于超大群组(10000+ 成员),考虑使用多 Bot 负载均衡
-
减少 API 调用
- 批量处理事件
- 使用缓存减少重复查询
-
异步处理
- 所有 Telegram API 调用已异步
- 不要阻塞事件循环
-
及时清理
- 验证完成立即删除记录
- 定期清理过期的会话
本 Bot 需要配合验证服务使用:
-
部署顺序
- 先部署验证服务(verification_go)
- 获取服务地址和客户端密钥
- 再配置并启动 Bot
-
网络要求
- Bot 需要能访问验证服务(出站 HTTPS)
- 验证服务不需要能访问 Bot
-
配置同步
VERIFY_CLIENT_KEY必须在验证服务的TRUSTED_CLIENT_KEYS中VERIFY_TIMEOUT_SECONDS应与用户体验预期匹配
欢迎提交 Issue 和 Pull Request!
- verification_go - 验证服务后端
- Telegraf - Telegram Bot 框架
如有问题,请提交 Issue。
祝使用愉快! 🤖