
近两年 Telegram 上的付费社群和知识星球类生意越来越火很多做课程、带单、资源分享的朋友都开始用机器人来做付费入群自动化。但市面上的付费入群机器人源码鱼龙混杂直接拿别人打包好的源码部署轻则被留后门盗走用户数据重则 bot 被对方控制、群被接管。我这次接手一个客户的付费入群机器人项目对方提供了一套开源代码要求我做代码审计并在宝塔面板上完成部署。整个过程踩了不少坑也发现了很多值得写下来的细节今天完整复盘一遍。这套机器人方案的核心链路很简单用户私聊 bot 发起支付机器人校验付款成功后调用 Telegram API 把用户拉进目标群组。听起来功能不复杂但真正落地时涉及支付校验、会话管理、权限控制、API 调用频率限制、以及长期稳定运行等一整套问题。这篇文章适合想自己搭一套付费入群机器人、又担心代码安全性的人阅读也适合正在研究宝塔部署 Python 机器人项目的朋友参考。1. 付费入群机器人的核心链路与设计思路1.1 业务链路拆解从用户点击到进群一共几步在动手审计代码之前先把付费入群机器人完整的业务链路梳理清楚。标准流程是这样的用户通过群内置顶消息或者外部分享链接找到 bot 的 username点击 Start 打开私聊窗口。机器人收到/start命令后返回一段欢迎语和付费说明同时生成一个唯一的订单号或支付链接。用户点击支付链接后进入支付渠道完成付款。这里支付渠道可以是 Telegram Stars、加密货币、法币收款平台、或者国内常用的 USDT 收款不同渠道的校验方式差别很大。用户支付完成后回到 Telegram 私聊窗口发送/paid或者等待支付平台的回调通知。机器人后台通过主动查询支付平台 API 或解析回调数据确认订单状态为已支付后调用kickChatMember或banChatMember的反向操作把用户加入目标群或频道。入群后机器人还需要给用户打上标签或写入数据库记录该用户的付费状态和到期时间。如果做的是订阅制付费还需要定期检查用户是否到期到期后自动移出群组。整个链路看起来简单但每一环都有安全漏洞的可能性尤其是支付校验这一步最容易被人伪造请求绕过。1.2 机器人选型Telethon 还是 python-telegram-bot代码审计之前先看技术栈。市面上开源的 Telegram 付费机器人大多用 Python 写生态最成熟的是python-telegram-bot和Telethon两个库。这两个库的设计思路完全不同python-telegram-bot是官方 Bot API 的封装走 HTTPS 请求安全性高、逻辑清晰适合做纯 bot 功能的项目Telethon是 MTProto 协议的封装能模拟用户客户端登录能力更强但安全性风险也更高。我这次审计的源码用的就是python-telegram-bot搭配sqlite3数据库整体选型比较稳妥。如果是基于 Telethon 的项目需要特别留意 session 文件的管理——Telethon 的 session 文件一旦泄露等于把账号完全交给了别人这种项目审计时风险等级要上调一档。另外现在很多新版机器人也开始用aiogram异步框架写法上更现代但底层逻辑没有本质区别。1.3 方案取舍为什么不等“开箱即用”的现成 SaaS市面上也有不少现成的 SaaS 付费入群机器人配置好就能用。客户为什么坚持自建核心原因有三个一是 SaaS 每单抽成比例不低社群规模大以后支付出去的抽成是一笔不小的钱二是用户数据全部存在第三方平台上客户无法掌控自己的会员数据和订单明细三是部分付费社群卖的内容比较敏感不希望被第三方平台看见内容和用户关系。自建的代价就是上述所有事情都要自己负责服务器、部署、安全、维护、升级。这其实是典型的“省钱但费事”的路径适合社群月流水较高、有基本技术能力的人。如果你只是月入几百块的小社群直接用现成的 SaaS 反而更划算时间成本远比那点抽成高。这个决策逻辑放在代码审计之前想清楚才不会做到一半觉得不划算。2. 代码审计实录不要相信任何人的“开源”2.1 审计目标与方法论到底要查什么接到这套源码后我没有急着部署而是先花了一整天做代码审计。很多人在这一步直接跳过说实话是非常危险的。开源代码安全的先决条件是你信任作者但“付费入群机器人”这个赛道上有大量匿名开发者源码里埋后门的情况并不少见。我审计时主要关注四个方向后门与恶意代码查找隐藏的管理命令、远程指令执行、可疑的外联请求、硬编码的 token 或密钥。支付校验逻辑确认支付状态的验证是否真实可靠能否被伪造请求绕过。越权与权限控制检查管理命令是否有身份校验普通用户能否触发管理员操作。数据安全与隐私检查用户数据是否被非法上传、日志是否记录了敏感信息、数据库是否未加密。工具上我主要用了grep、ripgrep做快速全库搜索配合trufflehog扫描硬编码密钥再用semgrep跑了一遍通用的 Python 安全规则。这套组合打底基本能覆盖 80% 的常见问题。剩下的 20% 需要靠人工读代码尤其是支付回调相关的逻辑机器扫不出来业务层面的漏洞。2.2 真实发现几个典型的代码风险点这套代码表面上看结构清晰但深入读下来发现了几个值得警惕的问题。第一个问题是管理命令的鉴权漏洞。主文件里定义了一个/admin命令用于向指定用户发送通知消息但代码只在入口处校验了user_id是否等于预设的管理员 ID。问题在于这个校验发生在收到命令的handler里而该 handler 注册的是MessageHandler(filters.COMMAND)意味着任何私聊这个 bot 的人都可以尝试触发/admin命令。只要触发者的user_id等于配置里的ADMIN_ID就能执行管理操作。如果ADMIN_ID在配置文件中留空或设置错误攻击者甚至不需要猜 ID 就能直接接管 bot。审计时我第一件事就是把所有 handler 的权限校验梳理一遍确保每个管理命令都有独立的、不可绕过的鉴权装饰器。第二个问题是支付验证逻辑过于信任前端传参。源码中支付回调部分直接读取请求参数里的status字段作为支付成功的判断依据只要攻击者模拟请求把status改成paid就能伪造付款成功。更离谱的是对于 Telegram Stars 支付代码没有调用getStarTransactions或等价 API 去验证交易是否存在而是单纯依赖回调参数。这种处理方式在真实场景下会被人在公屏上免费进群刷到老板破产。审计时一定要检查支付状态的最终判定必须来自服务端主动向支付平台发起的查询请求绝对不能相信客户端或回调带来的任何参数。第三个问题相对隐蔽但影响很大——日志中明文记录了用户的支付地址和订单 ID。很多开发者为了排查方便会在日志中输出完整的订单信息这本身问题不大。但如果部署环境关闭了访问控制任何人都能通过某些信息泄露路径看到这些日志就等于把用户的隐私和交易行为暴露了。我在部署时把日志级别调到了INFO并且过滤了敏感字段只保留订单尾号方便排查这个细节值得所有类似项目借鉴。2.3 审计结论与处理方案审计完成后我把发现的问题分成三类处理必须重写支付验证逻辑、管理命令鉴权逻辑这两块不修改绝对不能上线。建议加固数据库字段加密、日志脱敏、管理操作二次验证。可选优化代码结构重构、数据库连接池、异步处理能力提升。这里必须强调一个观点代码审计不是找茬是为了保证业务安全运行。很多项目所有者会担心“代码是别人写的我不敢动”但如果你连基本的鉴权和支付校验都不修就上线那出事只是迟早问题。宁可多花三天修代码也不要等用户数据泄露或者机器人被人接管了再来补救。3. 宝塔面板部署实战把机器人跑起来3.1 环境准备宝塔安装与 Python 版本选择代码审计修改完成之后开始真正的部署环节。我选择了腾讯云轻量服务器系统镜像选了 Ubuntu 22.04 LTS2核4G 的配置跑这种小项目绰绰有余。宝塔面板的安装命令官方文档有一行脚本搞定这里不赘述。一个关键点宝塔面板默认的 Python 环境是系统自带的但很多项目需要指定版本的 Python。我遇到的情况是代码里用了 Python 3.10 的语法特性而宝塔面板的 Python 项目管理器默认提供的可能是 3.7 或 3.9导致直接部署报语法错误。解决方法是先在服务器上安装目标版本的 Python或者使用宝塔的 Python 项目管理器在创建项目时明确指定 Python 版本为 3.10 以上。还有一个容易踩坑的地方宝塔自带的 Python 项目管理器会把项目运行在虚拟环境中但不同版本界面差别比较大。新版面板在“网站”-“Python 项目”中可以创建项目并自动创建虚拟环境。我在实际操作中更倾向于直接用命令行创建虚拟环境并在 supervisor 中管理进程这样更可控排查问题也更直接。3.2 项目部署流程从上传代码到运行成功环境就绪后部署流程如下通过宝塔文件管理器把修改后的源码上传到/www/wwwroot/telegram-bot目录。在项目目录下创建虚拟环境python3.10 -m venv venv。激活虚拟环境source venv/bin/activate。安装依赖pip install -r requirements.txt。如果项目没有requirements.txt需要手动安装python-telegram-bot、requests、apscheduler等核心库。创建.env配置文件填入 BOT_TOKEN、ADMIN_ID、支付平台密钥等敏感信息。宝塔面板可以直接在文件管理里新建文件非常方便。运行测试先在前台执行python main.py观察日志是否正常启动、bot 是否能响应/start指令。这一步如果直接放后台运行出了问题很难排查。实测下来第 4 步最容易卡住很多开源项目没有把依赖列全运行时会报ModuleNotFoundError。我踩过的一个具体例子是项目依赖了python-telegram-bot[job-queue]这个可选扩展但requirements.txt里写的是python-telegram-bot导致定时任务模块导入失败。这种情况下先看报错缺哪个模块再手动 pip install 补上就行不必非要把所有依赖一次性弄全。3.3 进程守护与自动重启supervisor 的正确配置前台运行确认没问题后需要把进程放到后台并保证崩溃后能自动重启。宝塔面板自带“进程守护管理器”插件可以直接把 Python 脚本托管起来但我自己在生产环境更推荐直接用supervisor。原因很简单supervisor 的配置非常直观日志管理清晰而且不依赖于宝塔的面板进程是否存在。宝塔的进程守护管理器在某些版本下有 bug进程退出后不会自动拉起或者重启面板后守护进程丢失配置。supervisor 的配置文件放在/etc/supervisor/conf.d/bot.conf内容大致如下[program:tg-pay-bot] directory/www/wwwroot/telegram-bot command/www/wwwroot/telegram-bot/venv/bin/python main.py autostarttrue autorestarttrue stderr_logfile/www/wwwroot/telegram-bot/logs/err.log stdout_logfile/www/wwwroot/telegram-bot/logs/out.log userroot配置好以后执行supervisorctl update和supervisorctl restart tg-pay-bot然后去 Telegram 里给 bot 发一条消息测试响应。日志文件建议用宝塔的日志切割功能不然长时间运行后日志文件会膨胀到几个 GB那时候排查问题都打不开文件。3.4 域名与 Webhook 的配置细节如果支付方式是依赖回调通知的比如某些法币收款平台会向服务器 URL 发送支付结果通知那么需要配置一个公网可访问的 HTTPS 回调地址。这里有几个细节值得注意首先Telegram Bot API 的 setWebhook 和 getUpdates 不能同时使用。如果代码里用了getUpdates长轮询方式就不要设置 Webhook反之亦然。很多人在宝塔里配置了 Nginx 反向代理后忘了把 Webhook 地址配置正确导致 bot 消息一直收不到。调试时可以通过https://api.telegram.org/botTOKEN/getWebhookInfo查看 Webhook 是否设置成功。其次如果不用 Webhook 而用长轮询模式不需要配置域名和 SSL 证书bot 会主动通过长连接从 Telegram 服务器拉取更新。这也是最省事的部署方式我就是用的长轮询因为项目本身没有复杂的回调需求。最后如果支付平台确实需要回调地址在宝塔上需要创建一条 Nginx 反向代理规则把/callback路径转发到本机的 Python 进程端口再申请免费的 Let‘s Encrypt 证书。这里有一个天坑宝塔默认的 Nginx 配置会把所有请求转发给默认站点如果需要特殊路径转发一定要在站点配置文件中单独添加 location 规则否则回调请求会被 404 拒掉。4. 常见问题与排查技巧实录4.1 机器人不响应命令的排查顺序我在部署过程中遇到的最常见问题是“机器人完全没反应”。这种问题出现后不要急着去改代码按下面的顺序排查效率最高第一步查看进程是否存在。执行ps aux | grep main.py如果进程不在看 supervisor 日志或重新启动。第二步查看日志。重点看有没有ERROR、HTTPError、Timeout等关键词。第三步确认服务器到 Telegram API 的网络连通性。Telegram 的 API 域名api.telegram.org在某些网络环境下访问不稳定可以执行curl -I https://api.telegram.org测试连通性如果是超时或连接被重置说明是网络问题。第四步确认 BOT_TOKEN 是否正确。从 BotFather 复制的 token 有时会带空格或换行复制到配置文件时必须仔细检查。第五步检查代码里是否正确注册了 command handler。很多人新加一个/pay命令后忘记重启进程导致新命令一直不生效。按这个顺序排查90% 的“没反应”问题能在操作上解决真正代码层面的问题反而是少数。4.2 数据库锁死与并发处理付费入群机器人是典型的高并发写入场景多个用户同时付款、同时被拉群、同时写数据库。如果用的是 SQLite很容易遇到database is locked错误。这个报错的原因很简单SQLite 同一时刻只允许一个写入操作多个写请求并发时后面的请求会等待默认等待时间一过就报错。解决办法有几个一是把sqlite3连接的超时时间调长比如timeout30二是强制每次操作后都提交并关闭连接三是升级到 PostgreSQL 或 MySQL。对于付费入群这种规模的项目SQLite 勉强能用但长期运行后数据量增长查询和写入都会变慢。如果客户预算允许我会直接换 MySQL宝塔自带 MySQL 管理部署成本也不高。我这次为了稳妥起见在代码里把 SQLite 的PRAGMA journal_modeWAL开启了写入并发能力提升了不少。4.3 用户重复付款与订单幂等处理这是付费入群机器人最容易被忽视的坑。用户因为网络卡顿或者在 Telegram 里连点两次支付按钮可能发起两个相同内容的订单。如果代码里对订单号没有做唯一性约束用户可能支