拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Telegram普号隐身监控:MTProto协议实现关键词监听与人工响应

Telegram普号隐身监控:MTProto协议实现关键词监听与人工响应 简介这是一套面向即时通讯安全研究与个人学习场景的群组关键词监听机器人源码基于PHP实现可对群聊与频道内容进行自动化监控在命中预设关键词时触发提示便于理解多账户潜伏与实时人工响应的技术链路。资源包共57个文件约94KB以36个php源码文件为核心涵盖事件观察者、控制器、会话迁移与API扩展等模块另有9个zbak备份、2个json配置、yml与docker编排、sh启动脚本及docx说明文档整体结构清晰便于按模块阅读与二次调试。目前已有128人学习。读者可从中获取完整的关键词监听实现思路、事件驱动架构与配置样例适合具备一定PHP基础、希望研究消息监控机制与自动化响应流程的学习者参考仅限学习交流请勿用于商业用途。1. 电报群关键词监听机器人普号隐身监控到底怎么落地做社群运营的同行大概率都遇到过这种场景群里有人发了一句“tg机器人怎么接”“tg api接码使用方法”等运营看到时已经过去两小时用户早跑去别家问了。人工盯群不现实用 Bot API 又有个硬伤——机器人账号进群会显示“已加入”用户一看就知道有机器人在监听敏感话题立刻转移。这就是“普号隐身监控”要解决的问题用一个普通用户账号非 Bot挂在群里不显示机器人标识实时抓取消息里的关键词命中后推送给人工客服去响应。这套方案的核心不是“监听”本身而是三件事的组合普号如何稳定在线、关键词如何高效匹配、命中后如何把上下文完整交给人工。适合做私域社群运营、售后客服、线索收集的团队也适合想研究 Telegram MTProto 协议的技术人。下面从协议选型一路讲到部署排错都是能直接抄的配置。2. 协议选型与账号准备为什么 Bot API 干不了这活2.1 Bot API 和 MTProto 的本质差别Telegram 对外提供两套接口。Bot API 是官方封装好的 HTTP 接口简单、稳定、有官方文档但它的身份就是“机器人”——进群有系统提示无法读取进群前的历史消息也无法伪装成真人。MTProto 是 Telegram 客户端使用的底层协议普通用户账号走的就是这条路。用 MTProto 登录一个普号它在服务器眼里就是一个正常的手机客户端进群不留痕能收全量消息。这就是“普号隐身监控”的技术底座。你要监听的是群里的自然对话用户不会对着一个机器人账号说真话所以必须用普号。常见做法是用 TelethonPython或 GramJSNode.js这类 MTProto 客户端库它们把协议细节封装好了你只需要处理登录、事件回调和消息解析。选型上Python 生态的 Telethon 文档最全、社区案例最多适合快速起步如果你整个后端是 Node.jsGramJS 更顺手。两者在关键词监听这个场景下能力对等差别主要在异步模型和部署习惯。2.2 普号登录与会话持久化普号登录需要手机号 验证码首次登录后必须把 session 持久化否则每次重启都要重新验证频繁登录还会触发风控。Telethon 的StringSession或SQLiteSession都能做到生产环境建议用文件型 session 并做好备份。# 首次登录并导出 session 字符串之后复用即可 from telethon import TelegramClient from telethon.sessions import StringSession API_ID 1234567 # 从 my.telegram.org 申请 API_HASH your_api_hash with TelegramClient(StringSession(), API_ID, API_HASH) as client: # 首次运行会要求输入手机号和验证码 print(client.session.save()) # 把输出保存到环境变量后续直接复用这段代码的逻辑是用空的 StringSession 启动客户端Telethon 会走完整的登录流程登录成功后session.save()返回一个可复用的字符串。参数说明API_ID和API_HASH是应用级凭证一个应用可以登录多个账号session 字符串等同于账号的登录态泄露等于账号被盗必须放在环境变量或密钥管理服务里不要硬编码进仓库。注意一个 API_ID 下登录的账号数量过多会被限制团队规模大时建议按账号分组申请多个应用凭证。2.3 账号养号与风控边界新注册的普号直接拉进十几个群开始监听大概率几天内就被限制甚至封禁。血泪经验是新号先正常使用一到两周加几个群、发几条消息、有正常的在线时长再逐步接入监听。单个账号建议同时监听的群不超过 20 个消息频率高的群要单独评估。如果业务量大正确做法是横向扩账号而不是让一个号硬扛。3. 关键词监听的核心实现从收消息到命中判定3.1 事件监听与消息过滤Telethon 的事件系统可以监听指定群的新消息。核心是把NewMessage事件绑定到处理函数在处理函数里做关键词匹配。要注意区分群消息、频道消息和私聊event.is_group和event.is_channel能帮你过滤。from telethon import TelegramClient, events from telethon.sessions import StringSession import os client TelegramClient( StringSession(os.environ[TG_SESSION]), int(os.environ[TG_API_ID]), os.environ[TG_API_HASH] ) # 监听所有群组的新消息 client.on(events.NewMessage(incomingTrue)) async def handler(event): if not event.is_group: return text event.raw_text or if not text: return # 交给关键词引擎判定 hit match_keywords(text) if hit: await push_to_agent(event, hit) client.start() client.run_until_disconnected()逻辑说明incomingTrue只处理收到的消息避免自己发的消息触发event.is_group过滤掉私聊和频道event.raw_text拿到纯文本图片、语音等非文本消息这里为空需要单独处理。参数上events.NewMessage还支持chats参数限定只监听特定群群多的时候用这个减少无效回调。3.2 关键词匹配引擎别用 in 硬匹配最朴素的写法是if keyword in text但实际群里的话术千变万化“tg机器人”和“TG 机器人”“电报机器人”都得命中还有全角半角、大小写、中间插表情的情况。直接in匹配会大量漏判。常见做法是三层匹配先做文本归一化去空格、转小写、全角转半角再用正则做模糊匹配最后对高价值词做同义词扩展。下面是一个可用的匹配函数import re import unicodedata def normalize(text: str) - str: # 全角转半角 转小写 去多余空白 text unicodedata.normalize(NFKC, text) text text.lower() text re.sub(r\s, , text) return text # 关键词配置主词 同义词列表 KEYWORD_MAP { 机器人: [机器人, bot, 机械人], 接码: [接码, 验证码, api接码], 客服: [客服, 售后, 人工], } def match_keywords(text: str): norm normalize(text) hits [] for main_word, synonyms in KEYWORD_MAP.items(): for syn in synonyms: if normalize(syn) in norm: hits.append(main_word) break return hits逻辑说明unicodedata.normalize(NFKC, text)把全角字符统一成半角这一步能解决“”和“tg”匹配不上的问题去空白是为了应对“t g 机 器 人”这种故意拆字的规避同义词表让“bot”和“机器人”归到同一个业务标签。参数上KEYWORD_MAP的 key 是业务标签value 是同义词命中后返回标签列表方便后续按标签路由到不同的人工客服。注意正则匹配高并发时是性能瓶颈群消息量大时建议把关键词预编译成re.Pattern对象或者用 Aho-Corasick 算法做多模式匹配几千个关键词也能做到毫秒级。3.3 命中后的上下文打包只推一句“有人提到机器人”给客服是没用的客服需要知道谁在哪个群、说了什么、前后文是什么。所以命中后要抓取消息上下文通常取命中消息的前后各 3 到 5 条连同发送者信息、群名称、消息链接一起打包。async def push_to_agent(event, hits): # 抓取上下文命中消息前后各 3 条 context_msgs [] async for msg in client.iter_messages( event.chat_id, offset_idevent.message.id 3, reverseTrue, limit7 ): context_msgs.append(f{msg.sender_id}: {msg.raw_text}) payload { group: event.chat.title, group_id: event.chat_id, sender: event.sender_id, hits: hits, text: event.raw_text, context: context_msgs, msg_link: fhttps://t.me/c/{event.chat_id}/{event.message.id}, } await send_to_agent_system(payload)逻辑说明iter_messages用offset_id定位到命中消息附近reverseTrue保证按时间正序排列limit7取前后各 3 条加命中本身。msg_link用t.me/c/格式生成群内消息直达链接客服点一下就能跳到原消息。参数上上下文条数不是越多越好7 条是实践下来信息量和可读性的平衡点太多客服反而不看。4. 实时人工响应系统从命中到客服接单4.1 推送通道与消息队列命中消息不能直接塞给客服中间要有一个队列做缓冲和分发。常见架构是监听服务把命中事件丢进 Redis 队列客服端从队列消费。这样做的好处是监听和响应解耦客服下班时消息不会丢第二天还能看到积压。import redis import json r redis.Redis(hostlocalhost, port6379, db0) async def send_to_agent_system(payload): # 按业务标签路由到不同队列 for tag in payload[hits]: queue_name fagent_queue:{tag} r.lpush(queue_name, json.dumps(payload, ensure_asciiFalse)) # 同时写一份全量日志便于回溯 r.lpush(agent_queue:all, json.dumps(payload, ensure_asciiFalse))逻辑说明按标签路由让不同业务线的客服只看自己相关的消息比如“接码”标签的队列给技术支持“客服”标签的给售后。ensure_asciiFalse保证中文正常存储。参数上Redis 的lpush是左进右出客服端用brpop阻塞消费天然支持多客服竞争消费不会重复处理。4.2 客服端接单与状态回写客服端可以是一个简单的 Web 面板也可以是 Telegram 上的一个内部群。轻量做法是建一个内部客服群监听服务把命中消息格式化后发到群里客服直接在群里回复回复内容通过普号转发到原群。这样客服不用切换工具响应速度最快。# 客服在内部群回复后转发到原群 client.on(events.NewMessage(chatsAGENT_GROUP_ID)) async def agent_reply(event): reply_to event.message.reply_to_msg_id if not reply_to: return # 从缓存里取出原消息的映射关系 origin r.get(fmsg_map:{reply_to}) if not origin: return origin json.loads(origin) await client.send_message( origin[group_id], event.raw_text, reply_toorigin[msg_id] )逻辑说明客服在内部群回复某条推送时reply_to_msg_id指向推送消息通过msg_map找到对应的原群和原消息 ID再用普号把回复发到原群并引用原消息。参数上msg_map的 key 是内部群推送消息的 IDvalue 存原群 ID 和原消息 ID这个映射要在推送时写入 Redis 并设置合理的过期时间。4.3 响应时效与人工介入的边界实时人工响应不是所有命中都要人工处理。高频低价值的词比如“客服”这种日常词可以设置阈值比如同一用户短时间内多次命中才推送避免客服被淹没。高价值词比如“接码”“api”则要即时推送。这个阈值配置建议做成可热更新的运营随时调整不用重启服务。5. 避坑与排查普号监听最容易翻车的五个点5.1 账号突然掉线session 失效现象服务运行几天后突然收不到消息日志显示AuthKeyUnregisteredError。原因账号在别处登录、被官方风控、或者 session 文件损坏。解决做好 session 备份掉线时用备份恢复同时监控在线状态掉线立即告警。不要频繁重新登录会加重风控。5.2 消息收不全漏消息严重现象明明群里有人发了关键词但没触发推送。原因一是账号被限流消息延迟二是NewMessage事件在断线重连后丢失了断线期间的消息。解决启动时用iter_messages补拉最近一段时间的消息做去重比对账号分散到多个降低单号负载。5.3 关键词误判客服被垃圾消息淹没现象客服抱怨推送太多大部分是无关消息。原因关键词太宽泛比如“客服”这个词在群里被大量正常提及。解决引入白名单和黑名单对发送者做过滤设置命中频率阈值把宽泛词降级为“仅记录不推送”。5.4 回复发不出去提示权限不足现象客服回复后普号发到原群失败。原因普号被群管理员禁言、被踢出群、或者群设置了仅管理员可发言。解决监控普号在群内的状态被禁言立即告警重要群准备备用号。5.5 上下文抓取报错消息 ID 越界现象iter_messages在群消息很少时抛异常。原因offset_id加上了超出范围的偏移量。解决抓取前先判断消息 ID 范围或者用 try/except 包住失败时降级为只推命中消息本身。6. 进阶把监听系统做成可运营的资产跑通基础版之后真正拉开差距的是数据沉淀。我一般会做三件事第一把所有命中事件落库字段包括群、发送者、关键词、时间、是否已响应这样能算出每个群的活跃度和转化率第二给关键词做效果分析哪些词命中多但转化低就该调整第三把客服的响应话术沉淀成模板命中后自动推荐话术客服一键发送。验证系统是否可靠有个简单方法建一个测试群用另一个号按预设脚本发消息看从发送到客服收到推送的端到端延迟。正常应该在 2 秒以内超过 5 秒就要查网络和队列积压。下面是一个延迟打点的写法import time client.on(events.NewMessage(incomingTrue)) async def handler(event): recv_ts time.time() # ... 匹配逻辑 ... if hit: latency time.time() - recv_ts r.lpush(latency_log, f{event.chat_id}:{latency:.3f})参数上latency只统计处理耗时不含网络传输端到端延迟要加上推送和客服端消费的时间。建议把这两个指标分开监控出问题时能快速定位是监听慢还是推送慢。最后说个我踩过的坑一开始为了省事所有群共用一个关键词表结果做电商的群和做技术的群互相干扰推送噪音极大。后来改成按群分组配置关键词运营自己维护监听服务只负责执行效率立刻上来了。这套系统的价值不在于技术多复杂而在于把“人盯群”变成“系统筛、人来答”让客服的每一分钟都花在真正有意向的用户身上。希望帮到你。本文还有配套的精品资源点击获取
返回列表