Telegram 群组管理机器人,基于 Telethon。
仓库:https://github.com/SCys/GoalKeepr
翻译感谢 77 老师。
将机器人加入群组并设为管理员(授予相应权限)后,可使用入群验证及以下命令。
- 新成员入群后,机器人会限制其发言权限并发送验证消息(含随机图标验证码)。
- 验证消息包含欢迎文案、5 个验证按钮、管理员操作按钮:
- 点击正确图标 → 通过验证,恢复发言权限
- 点击错误图标 → 刷新验证码重试
- 30 秒内未操作 → 踢出群组,60 秒后解封允许重新加入
- ✔️ 管理员直接通过(跳过验证)
- ❌ 管理员踢出并加入黑名单(默认 30 天)
- 群组处理方式可在群内通过
/group_setting配置(需配置 Redis):认证剔除(默认)、手动解封、无作为、静默 1/2 周等。 - 验证过程中会通过 LLM 对用户资料进行垃圾广告检测,命中则自动踢出。
- 支持频率控制:24 小时内反复进出超过阈值将自动踢出。
| 命令 | 说明 |
|---|---|
/k |
踢掉发消息的人。 |
/sb |
将发消息的人加入黑名单。 |
/id |
获取用户信息(回复某人或自己),返回 ID、昵称、分享链接等。 |
/image |
根据文本生成图片。支持英文;中文会先翻译为英文。可配置允许的用户/群组及图床(imgproxy)(需在代码中启用)。 |
/shorturl |
将消息中的 URL 转为短链接(需在代码中启用)。 |
/tr |
将输入文本翻译为中文(需在代码中启用)。 |
/tts |
文本转语音(需在代码中启用)。 |
/asr |
识别语音消息中的文本,依赖配置的 ASR 服务端点(需在代码中启用)。 |
/sdxl |
使用 SDXL 接口根据文本生成图片(需在代码中启用)。 |
/chat |
基础 AI 会话(30 分钟 TTL 上下文)。/chat <问题> 或回复消息后加 /chat 继续;/chat reset 重置会话。需配置 [ai] + Redis(默认已启用)。 |
/group_setting |
群组设置:新成员入群处理方式等(需配置 Redis)。 |
部分命令(如 /image、/shorturl 等)在 handlers/commands/__init__.py 中默认未导入,需取消注释后重启方可使用。/chat 为简化后的基础会话功能,已默认启用。
┌─────────────────────────────────────┐
│ Telegram ChatAction │
│ (user_joined / user_added) │
└─────────────────┬───────────────────┘
│
▼
┌─────────────────────────────────────┐
│ member_captcha() [ChatMember事件] │
│ 1. 获取 chat, user │
│ 2. 删除入群消息 │
└─────────────────┬───────────────────┘
│
▼
┌─────────────────────────────────────┐
│ validate_basic_conditions() │
│ • 群组类型检查 (supergroup/group) │
│ • 用户存在检查 │
│ • 事件过期检查 (60s) │
└─────────────────┬───────────────────┘
│
▼
┌─────────────────────────────────────┐
│ CaptchaSession.check_and_record() │
│ ★ 频率控制 + 去重检查 │
│ • SETNX 原子锁防重复 │
│ • 24h内入群次数统计 │
└─────────────────┬───────────────────┘
│
┌───────┴───────┐
▼ ▼
state=throttled state=duplicate 正常通过
(入群≥30次) (事件重复)
│ │
▼ ▼
Kick 60s + 静默跳过
调度 unban
│
└───────────────┘
│
▼
┌─────────────────────────────────────┐
│ get_verification_method() │
│ 从 Redis 读取群组验证模式 │
└─────────────────┬───────────────────┘
│
┌─────────────┼─────────────┐
▼ ▼ ▼
NONE SILENCE BAN
(无作为) (静默模式) (验证码)
│ │ │
▼ ▼ ▼
放行 限制权限+ restrict_permissions()
通知管理员 禁止发送消息
│ │
▼ ▼
handle_silence_mode() ┌─────────┐
• 通知管理员 │ 创建Session│
• 限制1/2周自动解封 └────┬────┘
│ │
│ (失败) ▼
└──────────────────► sleep(3s)
│
▼
┌─────────────────┐
│ 安全检查(LLM+广告)│
│ 返回原因标记 │
└────────┬─────────┘
│
▼
┌─────────────────┐
│ build_captcha_msg│
│ 随机图标验证码 │
│ MD5加密callback │
└────────┬─────────┘
│
▼
┌─────────────────┐
│ send_message() │
│ 发送验证消息 │
└────────┬─────────┘
│
▼
┌─────────────────┐
│ • 记录答案到Redis│
│ • 调度超时检查 │
│ • 30s后自动删除 │
└─────────────────┘
┌─────────────────────────────────────┐
│ 用户点击按钮 (callback_query) │
└─────────────────┬───────────────────┘
▼
┌─────────────────────────────────────┐
│ validate_callback_conditions() │
│ • 消息存在/群组类型/bot消息检查 │
│ • 按钮布局验证 (5+2) │
└─────────────────┬───────────────────┘
▼
┌─────────────────────────────────────┐
│ 解码 callback_data (MD5→Redis) │
└─────────────────┬───────────────────┘
▼
┌─────────────────────────────────────┐
│ 权限判断 │
│ • is_admin → handle_admin_operation │
│ • is_self → handle_self_verification│
└─────────────────┬───────────────────┘
│
┌───────────┴───────────┐
▼ ▼
┌───────────────────┐ ┌─────────────────────────┐
│ handle_admin_op │ │ handle_self_verification │
│ │ │ │
│ • O (Accept) │ │ • 正确 → accepted_member │
│ • X (Reject) │ │ • 错误 → 重试+1 │
└───────────────────┘ │ • 超过3次 → Kick 60s │
│ └─────────────────────────┘
└───────────┬───────────┘
▼
┌───────────────────┐
│ accepted_member() │
│ • 恢复用户权限 │
│ • 发送欢迎消息 │
│ • 清理 session │
└───────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ Worker Loop (0.25s/1s) │
└─────────────────────────────┬───────────────────────────────┘
│
┌───────────────────┼───────────────────┐
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│new_member_check │ │ unban_member │ │safety_timeout │
│ (30s超时) │ │ (60s解封) │ │ (180s兜底) │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ _kick_member() │ │ edit_permissions│ │ _kick_member() │
│ • 广告→30天封禁 │ │ 恢复所有权限 │ │ 同 new_member │
│ • LLM/默认 │ │ │ │ │
│ → 60s封禁 │ │ │ │ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
- Python 3.10+(当前使用 3.14 开发)
- 依赖由 uv 管理(见
pyproject.toml)
参考 example/main.ini,在项目根目录创建 main.ini,按需填写以下节。
[default]
debug = false
[telegram]
token = <你的 BOT TOKEN>
api_id = <Telegram API ID>
api_hash = <Telegram API Hash>
proxy = socks5://127.0.0.1:1080 ; 可选,连接代理(socks5/http)从 my.telegram.org 可获取 api_id 与 api_hash。
[telegram]
admin = <管理员 TG 用户 ID,用于限制部分管理能力>
[redis]
dsn = redis://localhost:6379/0配置 Redis 后,会使用 Redis 处理延迟删消息、入群验证会话等;未配置则使用内置 SQLite。
[asr]
endpoint = <语音识别服务 URL,供 /asr 使用>[sd_api]
endpoint = https://api.snowdusk.me供 /image、/sdxl 等文生图使用。
[image]
users = 123,456
groups = -100xxx允许使用图片生成命令的 TG 用户 ID 与群组 ID,逗号分隔;不填则按代码默认策略。
[imgproxy]
domain = https://img.example.com
imgproxy_key = <key>
imgproxy_salt = <salt>
imgproxy_source_url_encryption_key = <key>图床代理,用于图片生成后的访问与裁剪(可选)。
[ai]
proxy_host = <AI 代理地址>
proxy_token = <代理 token>
# administrator / manage_group 为旧版 /chat 高级权限管理遗留(基础版 /chat 已不再使用)
chat_model = deepseek-r1
spam_models = openai/gpt-oss-120b;gemini-3.1-flash-lite-preview;openai/gpt-oss-20b;gemma-4-31b-it
image_optimize_models = deepseek-r1;gemini-flash
# chat_model 用于 /chat 基础会话(30min 上下文)。可使用任意后端支持的模型名;
# SUPPORTED_MODELS 中的 key 会获得精确的上下文长度和友好显示名,否则使用 128k 默认长度 + 原始模型名作为 "Powered by"。
# spam_models 用于新成员入群的 LLM 垃圾检测(handlers/member_captcha/security.py + utils/llm.py),支持多模型 ; 分隔 fallback
# image_optimize_models 用于 /image 命令的提示词 LLM 自动优化所有 LLM 相关功能(/chat、入群 captcha 的 LLM spam 检查、 /image 提示词优化)共享 [ai] 下的 proxy_host/proxy_token 配置,仅模型不同。模型名均可在 main.ini 中配置(不配置则使用代码内置默认值)。chat_model 不再强制要求必须是 SUPPORTED_MODELS 的 key。
[advertising]
enabled = false
words = 词1,词2
regex_patterns = 名称1:正则1;名称2:正则2广告/关键词检测(可选)。
# 安装依赖(需已安装 uv)
uv sync --group dev
# 前台运行
uv run python main.py镜像使用项目内 docker/Dockerfile 构建,入口为 startup.sh(会创建 log 目录并执行 python main.py)。
# 在包含 docker-compose 的目录中
docker compose build gk
docker compose up -d gk构建使用 Python 3.14 Alpine,已包含 ffmpeg 等运行时依赖。
适合把源码和配置/数据分离的场景:
推荐目录结构:
/data/goalkeepr/
├── main.ini # 配置文件(含 token 等敏感信息)
├── src/ # git 仓库克隆位置
│ ├── main.py
│ ├── pyproject.toml
│ ├── uv.lock
│ └── ...
├── data/ # 运行时数据(main.db + bot.session),代码会自动创建
└── log/ # 可选(非 systemd 方式时使用)
- 支持环境变量
GOALKEEPR_CONFIG和GOALKEEPR_DATA_DIR - 支持命令行参数
--config/--data-dir - Telethon session 和 SQLite 数据库会放在
GOALKEEPR_DATA_DIR下 - 向后兼容:不设环境变量时行为与原来完全一致(相对路径)
# 克隆代码到 src
mkdir -p /data/goalkeepr
cd /data/goalkeepr
git clone https://github.com/your/repo.git src
# 准备配置文件
cp src/example/main.ini main.ini
# 编辑 main.ini,填入真实 token 等
# 创建数据目录(权限给运行 bot 的用户)
mkdir -p /data/goalkeepr/data
chown -R $USER:$USER /data/goalkeepr
cd src
uv sync --frozen --no-dev
# 安装 systemd user service
mkdir -p ~/.config/systemd/user
cp systemd/goalkeepr.service ~/.config/systemd/user/goalkeepr.service
# 根据实际情况编辑 ~/.config/systemd/user/goalkeepr.service 中的路径和 uv 位置
systemctl --user daemon-reload
systemctl --user enable --now goalkeepr查看日志:
journalctl --user -u goalkeepr -fcd /data/goalkeepr/src
git pull
uv sync --frozen --no-dev
systemctl --user restart goalkeepr仓库提供 .github/workflows/deploy.yml 示例。
默认使用 src + uv + systemd user service 流程(与上面目录结构匹配):
- 触发:push 到 master
- 通过 SSH 在服务器执行
cd /data/goalkeepr/src; git pull; uv sync --frozen --no-dev; systemctl --user restart goalkeepr
配置 Secrets:
DEPLOY_HOSTDEPLOY_USER(必须是启用了 user service 的那个 Linux 用户)DEPLOY_KEY(SSH private key)
如果仍使用旧的 Docker + docker-compose 布局,可以在 workflow 里注释切换或维护两个 job。
详细的 service 文件模板见 systemd/goalkeepr.service(内有注释)。