Skip to content

About

Telegram 群组自助解封机器人 | 基于 Cloudflare Workers + D1 | 多群管理 / 广告检测 / 黑名单导出 / GKY联查 / 314条离线测试 | Fork of CF-Workers-TGUnbanBot【项目取用cmliu/TGUnbanBot】

Topics

Resources

Stars

7 stars

Watchers

0 watching

Forks

Latest commit

 

History

494 Commits

Folders and files

Repository files navigation

CF-Workers-TGUnbanBot-Plus

更新日志见 CHANGELOG.md:每次更新改了什么、新增了哪些环境变量、要不要手动操作。

全局来源的自动广告处置联动当前已配置的非独立治理群(环境、动态及杀手群);独立来源只处理本群,全局联动跳过独立群。自动名单按实际目标群保存,误判按本次真实处罚归属解除,保留后来有效处罚;手动命令沿用原权限和范围。演练与日常消息共用完整判定,演练开启时只学习、记录,关闭时统一收尾。其他机器人的消息及成员操作不进入业务记录、学习或处罚链。

🙏 致敬原作者

项目 信息
原作者 CMLiussss
原项目 CF-Workers-TGUnbanBot
二改作者 匿名

本项目所有核心思想、架构设计与初始实现,100% 归功于原作者 CMLiussss。

没有原作者无私的开源分享,就没有本项目存在的可能。本项目仅是站在原作者打下的坚实基础之上,做了一些小幅度的功能扩展与代码加固,绝不敢居功。原作者的设计思路与代码质量是本项目的根基。

特别鸣谢原作者 CMLiussss 设计的源代码支持 🌟

本项目沿用原项目 MIT License,原作者的版权声明完整保留在 LICENSE 文件中。如果你认可这套自助解封机器人,请优先访问并 Star 原项目:github.com/cmliu/CF-Workers-TGUnbanBot 🌟


基于 Cloudflare Workers 的 Telegram 群组自助解封与反广告机器人:用户私聊自助解封(GKY + 本地 D1 双库查询、解封命令复制、群内举报投票、新机器人风控),广告号由四层检测自动识别并封禁。

主程序 _worker.js,附带 TGS 动态贴纸解码模块,D1 一个绑定跑全部存储,34 条命令。

📖 目录

章节 看这里能了解什么
与原项目的差异 本项目相对原项目改了什么、为什么这么改
功能 每个命令怎么用:普通用户 / 群管理员 / 第一主人各自能用哪些指令,以及配置群内的回执规则与自动化行为
Telegram 管理小程序 私聊菜单里的群务台:群组、黑名单、广告复核和用户查询
广告检测 四层判定 + 头像识别怎么工作、12 条管理命令怎么用、阈值怎么调、误判怎么纠
项目结构 各文件的职责与测试覆盖范围
前置条件 部署前需要准备什么
环境变量 每个配置项填什么、不填的后果,以及源码顶部 =可修改= 区段怎么改
存储绑定 D1 数据库、Queue 与 Workers AI 的绑定名和用途
部署 从零到跑起来的完整步骤:建库、建队列、绑 AI、填变量、部署、初始化 Webhook
使用方法 用户自助解封的实际流程与二次审核流程
HTTP 接口 封禁查询、黑名单导出、黑名单清扫三个接口怎么调
常见问题 出问题先查这里,按现象定位原因与解决办法
License 授权信息

💡 想快速上手:先看 前置条件 → 部署 → 回头翻 功能 查命令用法。 遇到异常直接跳 常见问题。

与原项目的差异

  • D1 唯一存储后端 —— 黑名单 / 清扫缓存 / 批量任务 / 投票 / 指纹全存 D1(无 KV 依赖,免费层 10 万次/天写入不溢出);黑名单结构 ["123"] → [{id, reason, by, at}],旧裸数组自动归一化,零迁移
  • 多群组 + 动态群组 —— GROUP_ID 逗号分隔(第一条为主群);/addgroup /delgroup /listgroups 存 D1 可改,三道硬校验,动态群永不顶替主群
  • 批量任务 —— 四条命令支持多 TGID(半角/全角逗号、空格、换行、[123,456]),超出同步预算自动转 D1 + Queues 分片续接,单次 ≤50
  • 加黑即执行(原项目只写库不踢人)—— /ban /spam 加黑后立即遍历全部群禁言、/sban 立即全群踢出;黑名单用户发言实时拦截删消息 + 踢人,复入群立即踢回
  • 黑名单来源收紧 —— 写入来源只有真人执行的管理命令,原生按钮与第三方机器人一律不写;永不自助解封,只能 /unban 移除。chat_member 事件订阅另使群内手动封禁不写黑名单(仅审计通知)、手动解封时封不回黑名单用户
  • 通知与回执 —— OWNER_IDS[0] 收全部通知、其余副主人收加黑踢出,末尾标 📍 发起: 来源;解封回执改主群内联按钮(不再给点不动的假链接),SELF_UNBAN_CONTACT_GROUP 可指定;黑名单用户发 /start 给介绍、发 /unban 被闸门拒;重复举报预检在目标已封且已入 D1 时静默跳过
  • 素材指纹 —— 收集真实消息与资料中的头像、正文图片、会员标及自定义表情。实际内容识别与仅由其它通道带入的复用记录区分,不能把包标题或次数当成已确认的广告内容;主人纠错同步撤销对应学习。
  • 证据裁决 —— 已核实广告内容可直接处理,其余按独立位置组合判断;候选自动补查后证据不足即放行,不产生人工观察队列。
  • emoji 切断关键词 —— 「点⚔️查」骨架命中且有承诺/招揽语境才计分,只有骨架一律不计分(正常人也发「点👍看」)
  • 资料挂载的频道/群/bot —— 先判人再查链接,简介含招揽 +2、有案底 +3(案底含自举),查不到/简介空/正常社群/挂个人号一律 0 分
  • 新增命令与展示 —— /stats 统计面板、/search 关键词搜索、/profile 资料卡时间线、/health 两层自检、/menu 群设置菜单、/recent + /learnlast 捞回并学习已删广告;/ad 投票**通过后昵称脱敏为「首字***尾字」**防借卡片二次传播;/check 双库独立查询、/blacklist 竖排分条、/help 分区裸文本

功能

普通用户

  • /start —— 私聊欢迎语(START_WELCOME,支持 HTML 子集)
  • /unban —— 自助解封:返回检查清单,粘贴 SELF_UNBAN_KEYWORD 完整整句才触发(多/少标点即拒),走全部配置群,回执含主群「联系管理员」按钮
  • /start check_用户ID —— 二次审核入口(机器人自动生成的深链)

群管理员

  • /ban 用户ID [原因] —— 加 D1 黑名单 + 遍历全部群永久禁言(杀手 ON 群为踢出),支持批量;群内撤回命令、详情私聊第一主人;群内对单个 TGID 顺带清扫当前群
  • /sban 用户ID [原因] —— 加黑名单 + 遍历全部群踢出并撤回其发言;/ban 改禁言后要踢人就用这条;群里不留痕,逐群明细只走私聊
  • /spam [用户ID] [原因] —— 同上(reason=spam,全群禁言)+ 删除被回复的垃圾消息
  • /unban 用户ID —— 先删 D1 记录成功才解封;每群执行「恢复发言 + 解除封禁」两步(同一个人可能部分群被踢、部分群被禁言)
  • /check TGID —— 查 GKY + 本地黑名单,输出资料卡 + 时间线;群内不撤回命令、结果留群里并私聊第一主人
  • /stats [范围] —— 统计面板:活跃 / 增长 / 风控,带时间切换与 7/30 天趋势。范围支持 today week month 昨天 上周 近7天 2026-09-10 及日期区间。广告不计入发言统计
  • /ad [原因] —— 隐藏举报投票,赞成反对各 6 票(AD_VOTE_THRESHOLD),任一配置群管理员一票定音;发起人自动算 1 票、可改投去重;命令发出即删

主人/副主人专属(OWNER_IDS)— 隐藏指令

仅第一主人私聊

  • /help —— 分区列出全部命令,一条一行,权限写在分区标题
  • /notice —— 全体通知:发命令 → 下一条消息作内容 → 预览 + 确认 → copyMessage 群发(不带「转发自」),支持文本/图片/视频/文件,10 分钟未操作失效;不发杀手群和搜索群(KILLER_MODE_GROUPS / STAT_SEARCH_GROUPS 里的群,后台通知同口径;杀手群通知用杀手版 /notice),确认页逐个列出发往 / 不发的群名
  • /rm —— 回复消息后发送 → 删除该消息并秒撤回命令;群内 5 秒闪屏 + 完整审计走私聊;或私聊 /rm 消息链接(t.me/c/… 或 t.me/群用户名/…)直接删,群里不留痕迹
  • /profile TGID —— 资料卡 + 7 项时间线(申请/入群/退群/任命/最早发言/最后发言/总入群)+ 黑名单与 GKY
  • /admins —— 分节列出主人/副主人/超管的 TGID、昵称、用户名、群内身份、来源群(单次查询上限 40 次)
  • /learnlast 序号 —— 按冻结快照序号学习(列表会因新消息挤动而错位),同时加黑 + 全群封禁;判错用回执的 /unban 回滚
  • /addgroup /delgroup /listgroups —— 指令增删治理群(存 D1,三道硬校验,不改环境变量);/listgroups 用 getChat 拉群名并列出台账(10 分钟缓存),杀手群 / 搜索群标 🚫,仅第一主人可用,/delgroup 外两条仅私聊
  • /add_ad_admin TGID /del_ad_admin TGID —— 授权 / 取消某成员发起 /ad 投票
  • /pending [N] /ignore 序号 /ignore user TGID [页码] /rescreen [N] /adstats —— 广告检测复核、痕迹查询与状态,见 广告检测。独立群 Telegram 群主可纠正本群处罚;TGID 痕迹查询仍仅限第一主人本人私聊。
  • /words [页码] /addword /delword /addsample /clearsamples /warmup /whitelist —— 指纹库、语义样本与域名白名单维护
  • /leavegroup -100xxxx —— 私聊让 bot 退群;私聊 /delgroup 只停治理,群里直接发 /delgroup 则停治理 + 退群(仅动态群)

第一主人 · 群内或私聊

  • /health —— 运行检查两层:状态自检(bot 身份 / D1 / 统计活性 / AI 绑定)+ 逐群体检(在不在群、是否管理员、三权限),成本约 1+2N 次请求
  • /menu —— 群设置菜单页,三入口(群统计 / 资料卡 / 运行检查),点入口原地切换;返回键只在第一主人打开时挂
  • /search 关键词 TGID @用户名 —— 关键词搜索带分页,大小写不敏感、LIKE 走 ESCAPE 转义;普通管理员 / 副主人 / 超管不可用
  • 杀手群(KILLER_MODE_GROUPS,规则固定无开关)—— 自动检测永久禁言(退群再进重新禁言)、/ban /spam /sban 踢出(复入群踢回);同款直封 / 同款连带 / /ad 投票与杀手群完全隔离。非杀手群的 /ban /spam 恒为禁言,要踢人用 /sban
  • 杀手权限(KILLER_ADMIN_IDS)—— 只作用于杀手群:/ban /sban /spam /unban /rm /check /profile /search /stats /notice /health /job /jobrun /help,碰不到 GROUP_ID 的群;封的人进独立的杀手黑名单(只在杀手群拦截)、一律踢出、不学特征;按群分身份(杀手群里 = 杀手身份,私聊时 /ban /spam /unban /check 若他也是超管则走超管);每次封禁 / 解封 / 通知 / 删消息抄送第一主人;本人豁免广告自动检测
  • /dryrun [on|off|status] —— 全局演练:只有第一主人(OWNER_IDS[0])可在 Telegram 私聊或已验证的后台命令台开关;查看原素材、勾选位置、判定广告或正常,仅限第一主人本人在 Telegram 私聊操作。非独立的配置群、动态群、杀手群和辅助群收到的用户现场全部进入演练,包括正常、未知、白名单和管理员;独立群不参与。演练期间不处罚,判定后立即保存并后台学习;广告只学习勾选的广告位置,正常判定进入完整现场及资料反例池,另外勾选的正常素材才进入素材反例,避免把普通配图、头像连坐学黑。未判定不学不罚,不按用户 ID 永久免检。
  • /dryrun off 立即冻结本轮边界和非独立治理目标,恢复常规检测,历史收尾由队列自动执行。优先按原发送时间删除已确认广告:同群每次最多 100 条,最多 3 路群删除请求;批量失败缩小批次定位,限流遵守 Telegram retry_after。每批最多处理 8 条现场和 20 个群处罚目标,封禁请求最多 5 路并发;成功步骤持久记账,学习或报告故障不阻塞删除,队列中断由定时任务恢复。/dryrun retry 轮次ID 可主动提前登记重试,正常运行无需手动续接;独立群和原角色权限沿用原分工。
  • /dryrun status 查看状态与简要收尾进度。收尾结果只发第一主人,所有规模都附带 CSV 筛选表和 JSONL 完整证据,按记录数及字节数分片;包含原消息、资料卡、人工选择、模型参考、学习结果、冻结目标、逐群回执及失败原因。阶段报告和最终报告有独立版本号,失败重试不重置正在发送的大报告;全部完成后发送最终版本及分片总数。/dryrun report 轮次ID 重新导出最新结果,不重新处罚;下载任务入队不代表附件已经送达,失败自动续传。旧记录缺少原消息 ID 或边界不明确时如实记录,未完成流水持久保留。
  • 删除时间保护:Telegram 普通消息必须在原发送时间起不足 48 小时内删除,编辑不会延长期限(官方说明)。本轮演练最长 24 小时;记录的原消息到达 36 小时也会提前自动结束,通常预留 12 小时收尾,更旧的历史编辑触发立即收尾。自动结束私聊通知第一主人,关闭后不接受迟到判定。机器人必须保有删除与封禁权限;平台失败保留真实回执并重试,不能把未删除写成成功。批量 API 成功只标“已清除(含原本已不存在)”,不虚报新删除数量。
  • /recent [N] —— 捞回已被删的广告:按广告特征强度取最近 48 小时,冻结成快照私聊

主人 + 副主人

  • /blacklist —— 查 D1 黑名单,最多 30 条,竖排分条
  • /job 任务ID [页码] /jobrun 任务ID —— 查看与补跑批量任务(正常会自动续接到完成)

自动化

  • 黑名单实时拦截 —— 黑名单用户在配置群发言即删消息 + 踢出 + 通知主人(禁言模式群跳过)
  • 复入群踢回 —— 黑名单用户被拉回 / 自加回立即踢回;受保护角色(主/副/超管/任一群主管理员)不踢
  • 手动封禁不同步 —— 真人点 Telegram 封禁按钮不写 D1 黑名单,仅发审计通知;手动解封时对黑名单用户立即封回(无法绕过全局黑名单)
  • 通知带发起来源 —— 末尾一行 📍 发起:私聊 或 📍 发起:群名 -100xxx
  • 广告自动处置 —— 明确内容硬证据或独立位置的 6+3 组合定罪后,只在事发群封禁、删除该群触发及关联广告消息、记录本群自动名单并学习可靠特征。通知只带误封解除和关联学习纠错按钮;自动记录不加入全局黑名单或联合封杀数据源。
  • 管理员自动免检 —— 在任意一个配置群是管理员或群主的人,在所有配置群都不进广告检测链(包括他只在别的配置群当管理员、在本群只是普通成员的情形),不必手动加白名单;群内提权/撤职即时同步,撤职后下一句就恢复检测。手动 /ban /spam 不受此限制(那是主人口径)
  • 演练模式 —— 非独立群全部用户现场先采集,只有第一主人能判定,判定后学习、关闭后分批处罚;独立群继续本群自治。普通模式的 /spam、/ban、/sban 权限不变,演练不向其他角色授予判断或学习权限。
  • 入群判定 —— 不等发言:进群当场拉 bio + 查头像指纹,达线即封;每次检查都写 ad_join_checks 流水,正常号也记
  • 申请进群拦门 —— 开了「邀请链接需管理员批准」的群,在申请人还没进群时就判:零 AI 快筛(规则 / 指纹 / 评分 / 领导人姓名,一次模型都不调)命中即 decline,10 秒查询窗口内答完,广告号连验证机器人那一关都走不到。判不出来才交回 AI 链路,AI 慢了答 queue 交给原审批流程 —— 失败方向永远是放行。走的是与消息命中完全相同的处置链(写名单、登记入群后禁言、发拦门通知、分配 /ignore 序号),误判照样能回滚。
  • 资料挂载的频道/群/bot —— 先判人再查链接:资料卡与正文都没广告特征的正常人一个请求都不花;查的人按目标的简介与案底打分(简介含招揽 +2、有案底 +3,案底含自举),查不到/简介空/正常社群/挂个人号一律 0 分。每人最多查 5 个、按 handle 缓存 6 小时
  • 自动核实 —— 候选广告会自动补查资料、内容和模型证据,最终只输出封禁或放行。证据不足不生成观察记录或等待人工确认的任务;旧观察数据仅保留历史兼容与纠错用途。
  • 批量任务自动续接 —— 超出同步安全预算转 D1 批量任务 + Queues 分片续接
  • 定时滚动复查 —— cron 每天 2 次、日限 300 人,按进群时长分档复查简介(6 小时内每 2 小时一查,3 天封顶);bio 没改且判据库没更新则跳过
  • 统计剪枝 —— stat_speech / stat_member / stat_actions 按 180 天剪;入群/退群/申请明细永久不剪

广告检测

四层判定怎么工作

层 干什么 阈值
① 位置证据 交易动词、业务词、结构和变体证据分别归属真实位置,同一位置不重复累加 内容硬证据或独立位置 6+3
② 指纹层 关键词、域名、用户名、简介四类指纹匹配 AD_FINGERPRINT_MIN_CONFIDENCE = 0.6
③ AI 语义层 bge-m3 向量相似度,抓改写过表述的广告 AD_AI_SIMILARITY_THRESHOLD = 0.78
④ 金额招揽 金额与收益、招募动作同现,形成正文证据 与独立位置或已核实内容共同裁决,不发送观察通知
⑤ 资料形状 bio 归一化成形状哈希(换链接 / 换数字仍是同一形),被定罪过就记住 复用定罪 ≥ 2 次才 +3,只加分不定罪
⑥ 生成式深度判定 需要核实的候选交给模型结合资料和正文复评,检查引文与真实内容 受 AD_LLM_CONF 和每日额度约束;结论参与最终封禁或放行,不生成确认封禁任务
⑦ 形态 C 色情引流 色情指向词(色色 / 裸聊 / 约炮 / 楼凤 / 福利姬 …)与引流出口同现;词表刻意不含「影院」「完整版」「外围」这类高频中性词 单条即封(hardHit,只在正文与引用体通道生效)
⑧ 领导人资料冒用 昵称 / 用户名 / 简介里出现现任与历任国家领导人姓名(含拼音变体)与职务搭配,零成本、零 AI 单条即封(hardHit,只查资料不查正文 —— 群里讨论新闻是正常行为)
⑨ 前置号复核 进群 72 小时内第一条消息是 1~8 字纯招呼、无链接无 @:典型批量注册待投放号的特征。只在这一种形状上才花一次模型 模型结论 + 置信度过线才处置;没给置信度一律不采信(代码不补值)

三道闸:闸一 零成本评分定罪(含简介补查)、闸二 发言路径深度判定、闸三 定时滚动复查简介;入群即写名册,堵住「扫不到的号」的缺口。闸一、闸二、入群、复查四条线都挂了第 ⑥ 层 —— 它只在前五层没能定罪时才花钱,其中闸一要本次真拿到正分判据、或命中业务词 / 交易动词才调(普通技术讨论一个调用都不发,稳态零额外开销不变),且闸一到封禁线的照样不花这笔钱。命中理由照常进 /pending 快照、可用 /ignore 纠错。未绑 Workers AI 自动跳过第三层与第 ⑥ 层,未设 AD_LLM_DAILY 时第 ⑥ 层默认每天 1000 次,按消息 / 入群 / 定时扫描三个分池记账,谁也挤不掉谁。可疑信号还会把 bio 冷却期从 2 小时压到 10 分钟(AD_SUSPECT_BIO_COOLDOWN_SECONDS)—— 否则入群那次「简介还是空的」查询会把之后两小时的发言全挡在深判之外。

两种学习怎么分工 —— 参与学习:你用 /ban /spam /sban 处置一个号时,它资料卡上的广告特征(简介、域名、@handle、电话、头像、会员标、正文图)立刻写进真指纹库。AI 自我学习:第 ⑥ 层判为广告时,模型抽出的特征先进候选池 —— 候选池不参与任何判定;同一条特征被抽到 3 次且 ≥6 字就自动转正,或哪次人工处置的载荷命中它就立即转正。转正写入真指纹库的权重固定 0.5,低于 0.8 的定罪线 —— 只计分,永不单条定罪(「单特征不封」的永久规则)。抽出的特征都要过五道形态闸才准进池:逐字回原文核对(防模型幻觉)、长度 ≥4、类型限话术短语/域名/电话、域名不许是裸 t.me、通用词(「找我」「联系」)不收。

豁免词条件化(防广告拿豁免当挡箭牌):t.me、代理、h2 这类豁免只保护纯技术文案;文案里出现金额承诺、灰产词、强招揽构词之一时豁免整体失效(进群、cdn 这类日常词不触发,技术群主照旧放行)。失效只撤销 −3 减分、不加分,定罪仍要过原有形态门槛。

私有群邀请链接(t.me/+ 与 t.me/joinchat,公开频道链接与 @用户名 不在此列):写进简介 +7 直接定罪;发在正文里只记 +3、不单独定罪(在群里转发一条邀请链接是正常行为),但配上同一个招揽或行业词重复 ≥3 次则 +8 定罪。两种位置命中时都不吃 t.me 豁免 —— 那条豁免只保护公开账号链接。

头像识别:从资料取得头像,使用现有 Gemma/Qwen 读取文字与内容。实际确认广告、主人确定的素材或命中可靠广告文字的头像可以直接处理;旧复用记录或识别失败不是内容已确认。正常复核可纠正旧自动标签,主人确认干净的头像不再被自动学习覆盖。补学队列和 /ignore 使用同一套素材主键与纠错规则。

正文图片识别(同为并行的一路):图片、贴纸、动图和视频优先复用主人确认或已核验的具体素材指纹。clef-flash 只筛选候选,广告类别不能反转主问题的正常结论;候选再由现有 Gemma/Qwen 抄录实际招揽文字或画面证据,核验成功才可直接处理。旧视觉标签、未知来源和复用次数不再单独定罪。代理技术与服务、token、正常及官方域名、配置报错和普通技术截图不因这些词或链接被当成广告。相似素材以内容签名和 bge-m3 比对,同样需可靠内容证据;主人纠错优先于缓存。图片定罪不把旁边的正常求助文字、昵称和域名自动学成广告。AD_IMAGE_VISION_DAILY=0 关闭候选识图;二次内容核验和相似推理共用 AD_IMAGE_SIMILARITY_DAILY 上限,无法核验时不把图片升级为硬证据。

管理命令(默认仅第一主人私聊,独立群 /ignore 有例外)

复核与纠错

  • /pending [N] —— 待确认快照(得分、判据、资料)
  • /ignore user TGID [页码](也可用 /user TGID [页码])—— 仅第一主人本人私聊,只读查看机器人仍保存的消息缓存、演练和待核流水、关闭结果、处罚快照(含已复核)、各类名单、成员资料及事件,以及按已保存键关联的素材和学习条目。每类独立来源每页最多 20 条,显示真实总数和翻页指令;缺失的表或字段明确说明,不初始化新表、不调用模型、不执行解封、撤学习或删除消息。
  • 共享图片、头像、会员标、指纹、骨架、形状及正常反例的关联不代表用户独占;AI 样本仅显示本页冻结文字派生的匹配候选。未接收、已过期或已删除且没有保存的原文与原图无法恢复。纠正误判仍使用对应的 /ignore 处罚序号。
  • /ignore 处罚序号 —— 第一主人私聊可按原权限纠错。当前开启独立模式的 Telegram 群主可在本群或本人私聊中处理属于该群的自动处罚,并记录仅本群生效的负反馈;不改全局共享指纹、样本、素材或名单。普通管理员无此权限;跨群记录、已切回全局的群及身份校验失败均拒绝。本群旧名单没有处罚序号时,在该群使用 /unban 用户ID。
  • 全局自动误判按持久目标账本解除本次实际处罚,保留已有原生封禁、后来手动和新自动处罚;独立群主不能获得全局回滚权限。代码只主动核验删除原群原消息;Telegram 在超群/频道执行原生封禁时会自动撤回该用户历史消息,平台不返回其清理条数,不能承诺其他处罚群的历史消息保留。

独立群群主应先私聊机器人 /start,以便收到本群处罚的纠错通知。按钮每次重新验证真实群主身份和当前群模式;群主更换或切回全局后,旧通知不能继续授予权限。第一主人作出的有效全局处罚以及后来新增的处罚不会被群主的本群纠错撤销。全局演练、共享学习库和主后台权限仍只属于第一主人。

  • /rescreen [N] —— 仅第一主人私聊重新判定符合条件的已保存记录,群聊不执行,不是全部群的全量违规历史查询。默认 10 条、最多 30 条,待核和缓存分别最多读 500 条再过滤。默认本轮时间窗口,未开启时取最近轮次或 15 分钟;/rescreen user 用户ID [N] 使用普通缓存保留窗口(默认 7 天)。演练开启时采集现场,等待第一主人判定后学习;普通模式确认广告按当前自动范围处理:全局来源联动非独立群,独立来源仅本群。人工误判、已学习、非可疑或无法完整核验的记录不冒充已确认广告。
  • 演练保存本次可获取的 bio、昵称、用户名、头像、会员标及完整原始正文、媒体说明、文字/数字/字符和表情位置、图片/贴纸素材标识,不按单字段 4096 字符或 24 个关联项静默裁剪。自定义表情分批核验并保存进度,资料或素材获取失败逐项标为待补核;通知、痕迹查询和关闭报告区分完整与部分现场。贴纸标题和包名不作为判据,只核验实际发送的单张素材,同包其它正常图不连坐。TGS 动态贴纸分帧核验;只有缩略图的媒体不能据此宣称完整识别,音频等其他原始字段保存但不冒充已自动核验。超出安全存储大小时明确拒绝写入和学习,不保存截断现场。广告学习只使用第一主人明确选中的广告位置和素材,正常反例使用冻结的完整现场,不新增永久用户白名单。
  • 演练中的未知静态图及旧初筛正常缓存会核验实际画面与 OCR;高置信的可见广告招揽可以补回初筛漏判。完整保留 OCR 与证据引文,色情视频“点我/免费观看”等明确引流不要求标准网址;新闻、反诈、技术截图和缺乏真实证据的模型分歧不硬封。已核验结果按新版本缓存,主人同图正常反馈仍优先。
  • 手动学习只接受第一主人真实引用原消息的处置;仅按 TGID 封禁没有引用时不会学习素材。确认写入失败不报告成功。已确认同图再次出现,演练开启时仍先记录现场、由第一主人判定,不因旧素材命中而直接学习或处罚;普通模式全局来源联动非独立群,独立来源仅本群。普通联系号和“全天在线/官方认证/普通客服”等中性标识不单独定罪,不借同包其他素材或标题定罪。
  • /spam、/ban、/sban 的正文学习规则不变;附带图片、贴纸、自定义表情和资料头像须分别核实素材自身的广告内容,正常素材不因账号被封而进入广告学习。旧人工来源标签与复用次数不能替代内容证据;再次遇到时自动核验。同图和相似变体复用可核实的广告证据,未核实素材留在后台续查,素材正常纠错优先。
  • /adstats —— 独立位置规则、AI 使用与命中、指纹和样本规模、素材库、入群检查及演练实际学习情况。旧总分只作诊断兼容,不再作为自动处罚的最终裁决线。

指纹库与样本库维护

  • /words [页码] —— 列指纹(命中、误报、置信度);/addword 值 [类型] /delword 值 增删一条
  • /addsample 文本 /clearsamples —— 增删 AI 样本
  • /warmup —— 补向量,每次 8 条,补满第三层才生效
  • /whitelist [子命令] —— 域名白名单管理

阈值调优与运维

  • 平时一个都别填,用默认值
  • 误封多 → /ignore 纠错,别急着调低阈值;漏封多 → /adstats 先确认四层都在跑、向量已补满
  • 换 AI 模型 → 先 /clearsamples 清样本,旧向量维度不同会作废
  • 部署后发 /adstats 确认表与种子已建,绑了 AI 再发几次 /warmup 补满向量
  • 发现漏放:引用回复 /spam 最快;被抢先删的用 /recent + /learnlast
  • 校准效果:第一主人用 /dryrun on 采集现场,在演练通知中勾选实际广告位置,或确认正常并纳入反例池;/dryrun off 后用最终 CSV、JSONL 核对完整结果(离线测试不能代替实际素材的判定准确率)。

申请进群拦门(三个静默失效点)

开了「邀请链接需管理员批准」的群,申请人停在门外 —— 不会产生 chat_member 更新,也不会产生「已加入」服务消息,进群后的那几道门一层都触发不到。所以门前单独有一道判断,命中即 declineChatJoinRequest,人一次都没进过群。

1. allowed_updates 必须含 chat_join_request。 显式声明后 Telegram 的默认清单整体失效,漏了这一项就永远收不到任何申请,而 setWebhook 不报错。升级后要重新访问一次 webhook 初始化地址(或重启进程),清单才会重新下发。

2. bot 必须是群管理员且有「邀请用户」权限。 declineChatJoinRequest 缺它会失败(流水里写一条「拒绝失败:…」,不会假装成功)。

3. 快筛在 10 秒窗口内答 decline,答不出就答 queue。 Telegram 的守门查询(answerChatJoinRequestQuery)有 10 秒上限:超时只能答 queue,申请回到原审批流程,验证机器人接手 —— 那正是「广告号拿到进群验证机会」的那条路。零 AI 快筛存在的意义就是抢这个窗口:资料层面的广告(价目、私有邀请链接、招揽昵称、冒用领导人)全都不用模型就能判。判不出来的硬是交回 AI 链路,宁可多花一次调用,也不在门口猜。

失败方向:拿不到资料(getChat 失败 / bio 不可读)、豁免、白名单、管理员、演练群、AI 判定失败 —— 一律放行。门外误伤的代价比漏一条广告大得多:正常申请人被拒,他甚至不知道自己为什么进不来。

资料临时放行的语义:复判确认某个账号的资料不构成广告后,记 ad_profile_ok 到期时间。放行期内资料位置(昵称 / 用户名 / 简介)整体退出检测载荷 —— 评分、指纹、结构查杀三条路一起免,只留正文与引用照常判。改资料即失效;/ignore 解封不涉及这张表。

|

项目结构

.
├── _worker.js             # Worker 主程序,含广告检测与后台续接
├── ad-media.js            # TGS 解码与 PNG 帧输出
├── vendor/                # 固定版本 tlottie.wasm 及许可证
├── wrangler.toml          # Cloudflare Wrangler 配置(D1 / Queue / AI 绑定)
├── tests/                 # 离线测试(不参与部署,仅本地,不进仓库)
│   ├── test_*.mjs         # 70 个功能测试
│   └── miniapp_*.cjs      # 3 个页面检查(browser / drilldown 两个要本机 Chrome + playwright-core)
├── README.md
└── LICENSE
  • 测试 —— 70 个文件,只存本地(.gitignore 已排除),全绿才允许推送;node tests/test_xxx.mjs 单跑,退出码非 0 即失败;全跑:for f in tests/test_*.mjs; do node "$f" >/dev/null || echo "FAIL $f"; done
  • 运行要求 —— Node 22+(node:sqlite 内置模块要求)
  • 测试环境 —— 全部离线:Bot API 全 mock,D1 用 DatabaseSync(':memory:') 真实 SQLite 后端(ON CONFLICT、UNIQUE、batch 事务真跑),Workers AI 用固定向量函数模拟

⚠️ 离线测试覆盖不到:真实 Workers 子请求配额、Queue 实际投递、真实 AI 相似度分布、Telegram 真实错误码与限流、并发 D1 写竞争。广告判定准确率也验不了 —— 只能靠上线后用 /pending 复核校准。

前置条件

  • 一个 Telegram Bot Token,通过 @BotFather 创建
  • 一个启用了 Workers 的 Cloudflare 账号
  • 本地安装 Node.js 和 Wrangler,或直接使用 Cloudflare 控制台部署;跑离线测试需 Node 22+
  • 机器人已加入目标群组并设为管理员,权限要给到:封禁用户或解除封禁、限制成员、读取群成员状态、发送消息(chat_member 事件订阅也要求是管理员,本就满足)
  • Workers AI 可选 —— 绑定后启用第三层语义判定与第 ⑥ 层生成式深度判定,不绑自动降级两层,其余功能不受影响;bge-m3 是轻量嵌入模型(不是大语言模型),免费层每天的 Neurons 额度正常群规模不会超限

环境变量

必填

缺少前三项时配置加载返回 500;缺少有效的 WEBHOOK_SECRET 时,Telegram 更新入口和 Webhook 初始化返回 503。管理后台仍按原有配置和身份要求开放。

变量 说明
TOKEN 初始化入口密钥。访问 https://你的域名/{TOKEN} 注册 Webhook 与命令,并顺带同步一次配置群管理员表(改完群配置想立刻生效就重访一次,不必等 cron);/{TOKEN}/export 导出黑名单;/{TOKEN}/purge/run 分批清扫存量黑名单。不是 Bot Token,建议用随机长字符串
BOT_TOKEN Telegram Bot Token,从 @BotFather 取
GROUP_ID 目标群 ID,逗号分隔多群(半角 , 与全角 , 均可)。第一个群是主群
WEBHOOK_SECRET Telegram Webhook 来源校验密钥,仅允许 A-Z a-z 0-9 _ -,长度 1~256,建议使用至少 32 位随机字符串。初始化会下发 secret_token;更新请求缺少或带错误的 X-Telegram-Bot-Api-Secret-Token 头时返回 401。在 Cloudflare 配置为密钥,不写入仓库

可选(不填则使用源码顶部默认值)

变量 默认 说明
OWNER_IDS 空数组 主人 / 副主人 TGID。第一个是主人(收全部通知),其余副主人(收加黑踢出通知)
SUPER_ADMIN_IDS 空数组 超管 TGID,等同群管理员全部权限但免挂管理员身份;不含主人高级命令、不参与 /stats、本人豁免广告自动检测
KILLER_MODE_GROUPS 空数组 杀手群,自动并入 GROUP_IDS(自动检测禁言、人工命令踢出;不参与同款 / 连带 / 投票;不收全体通知)
KILLER_ADMIN_IDS 空数组 杀手权限 TGID,只管杀手群、与超管分开管;只放 Dashboard,别写进 wrangler.toml 的 [vars]
STAT_SEARCH_GROUPS 空数组 关键词搜索的正文保留群(这些群按 created_at 保留 180 天,其余群只留全局最新 200 条);自动并入 GROUP_IDS,不并入则不写缓存、配了也搜不到;不收全体通知
PROFILE_LOOKUP_GROUPS 空 只读资料群,仅供 /admins 查昵称,完全不参与治理
STATIC_USER_PROFILES 空 /admins 静态资料兜底(JSON),查到实时资料后自动覆盖
SELF_UNBAN_KEYWORD 见源码 自助解封确认整句,必须完整逐字粘贴(防广告号绕过)
START_WELCOME 见源码 /start 欢迎语(支持 HTML 子集)
SELF_UNBAN_PROMPT 见源码 无参 /unban 返回的自助解封检查清单
SELF_UNBAN_APPROVED / _NOLINK 见源码 解封成功回执(能 / 拿不到主群链接的两套文案)
SELF_UNBAN_CONTACT_GROUP 空(= 主群) 解封成功后「联系管理员」按钮指向的群(须在 GROUP_ID 内,否则回落主群)
BLACKLIST_PAGE_LIMIT 30 /blacklist 单次展示条数
BLACKLIST_REASON_LABELS 见源码 原因字段中文映射(JSON)
GKY_BANLIST_ENDPOINT https://gkybot.gmeow.cc/banlist GKY 封禁查询后端(新后端 HTML 须与 parseBanlistHTML 正则兼容)
FLASH_MESSAGE_TTL_MS 5000 群内闪屏存活毫秒数(0~60000)
FED_SOURCE_URL 空 联合封杀:要订阅的那台机器人的域名(https),如 https://对方域名。和下一项都填了才开启
FED_SOURCE_KEY 空 联合封杀:对方在后台「联合封杀」分区生成给你的 key(类型选「密钥」)。见 联合封杀
ADMIN_PASSWORD 空 网页后台正式密码(长短不限,类型选「密钥」),打开域名即登录页。设了就用它、/adminpass 停用;空则照旧私聊 /adminpass 领一次性密码。陌生 IP 错 5 次锁 15 分钟,登录成功过的 IP 不锁;后台「登录记录」可看次数与 IP;改密码即踢掉旧登录
MSG_CACHE_SIZE 50 清扫回看上限(1-500),/spam 按它回看当前群近期消息
AD_SCORE_THRESHOLD 7 旧总分接口兼容值;当前自动处罚按内容硬证据及独立位置组合裁决
AD_JOIN_SCORE_THRESHOLD 0 旧入群评分线兼容值,不再改变最终位置裁决
AD_OBSERVATION_SCORE 5 历史兼容值,当前模式不生成观察判定
AD_OBSERVATION_HOURS 24 旧观察记录兼容保留期,当前模式不新增观察记录
AD_AI_SIMILARITY_THRESHOLD 0.78 AI 硬命中阈值(0.1-1)
AD_AI_TOP_K 0 AI 多样本聚合:0 = 关闭(一条样本越线即定罪);设 3 则取最高 3 条过半超线才定罪,把单证改成多证。零额外推理,改回 0 即回退;治不了「同质样本扎堆」
AD_LLM_DAILY 1000 第 ⑥ 层生成式深度判定的每日总次数上限(0-5000,0 = 关闭本层)。前五层都定不了罪时才调;同一条文案在同实例内只判一次
AD_LLM_DAILY_MESSAGE 500 消息路径(闸一 + 闸二)的分池上限 —— 广告真正出现的地方,额度保底。0 = 关掉这一路的第⑥层
AD_LLM_DAILY_JOIN 300 入群筛查的分池上限(0 = 关掉这一路)
AD_LLM_DAILY_CRON 100 定时滚动复查简介的分池上限(0 = 关掉这一路)。三个分池各记各的账,互不挤占
AD_LLM_CONF 0.85 第 ⑥ 层采信线(0.5-1),模型结论需与当前内容证据核实;未确认时自动补查,不发送观察或确认封禁通知
AD_LLM_MODEL 见源码 第 ⑥ 层用的文本生成模型 ID,换模型只改这个变量不动代码;中文能力弱的 1B 小模型认不出同音变形,别随手降配
AD_FINGERPRINT_MIN_CONFIDENCE 0.6 指纹参与判定的最低置信度(0-1)
AD_PROTECTED_USERNAMES 空 权限人 @handle 永不学习白名单
AD_TRUSTED_BOTS nmnmfunbot,tc520lh_bot 可信 bot 白名单,名单内完全免检
AD_ENRICH_EVERY 5 每新增多少条 AI 样本自动提炼一次指纹(0-200,0 = 关闭自动提炼)
AD_ENRICH_MIN_OCCURRENCE 2 提炼候选子串需跨样本出现的最少次数(2-20)
AD_ENRICH_MAX_RESULTS 20 单次提炼最多入库的指纹条数(1-100)
AD_CARD_KILL ban 结构型广告卡片通道,ban 正常自动判定、off 关闭;旧 observe 值按正常检测兼容,已核实广告会处理,不再生成观察记录。需要只学不处罚时使用全局演练
AD_AVATAR_VISION_DAILY 150 头像视觉识别每日上限,0 关闭头像推理;保留缓存与可靠指纹判定
AD_IMAGE_VISION_DAILY 800 正文图片视觉识别每日上限,0 关闭普通图片推理;保留缓存和素材指纹判定
AD_IMAGE_SIMILARITY_DAILY 100 内容相似阶段实际模型调用的每日上限,失败调用也计入,缓存不扣。0 关闭内容相似推理,完全相同素材的主人判定仍有效;无需新增外部密钥或 AI 绑定
STATS_TZ_OFFSET 8 /stats 切天的时区偏移小时数(-12~14,非法值回落 +8)

关于源码顶部 =可修改= 区段

  • 优先级 —— 环境变量 > 源码默认值:Cloudflare 后台已填同名变量时,改源码不生效
  • 生效方式 —— 改源码后必须 wrangler deploy 重新部署
  • 建议 —— 优先改环境变量(不用重新部署),源码默认值仅作兜底

存储绑定

绑定 binding 名 必需性 用途
D1 Database DB 必需 唯一存储后端。黑名单、清扫缓存、批量任务、投票状态、广告指纹库全部存 D1。表结构由代码自动建立,首次写入自动建表。
Queue BULK_QUEUE 推荐 /ban /sban /spam /unban 超出同步安全预算后的自动续接队列。注意这是 Cloudflare Queue 绑定,不是 wrangler secret put 环境变量。
Workers AI AI 可选 广告检测第三层语义判定(@cf/baai/bge-m3 1024 维多语言嵌入模型)与第 ⑥ 层生成式深度判定。不绑则自动降级为「评分 + 指纹」两层。

未绑定 D1 或 D1 黑名单读取失败时,自助解封会失败关闭并拒绝继续,避免绕过全局黑名单。/ban /sban /spam /unban /blacklist 等命令会提示未绑定存储空间。 未绑定 BULK_QUEUE 时,大批量任务仍会创建到 D1,但不会自动续接,需要管理员用 /jobrun 任务ID 手动补跑。 未绑定 AI 时广告检测仍工作(评分 + 指纹两层),/adstats 会明确标注「未绑定,降级为评分 + 指纹两层」,不会静默失效。

D1 表结构(全部自动建立,无需手动 SQL)

  • 核心 5 张 —— schema_meta 当前版本 9、blacklist 全局名单、moderation_messages 消息缓存、batch_jobs 批量任务、dynamic_groups 动态配置群。新自动处罚使用带来源标记的本群记录,不写全局名单。
  • 统计 4 张 —— stat_speech stat_member stat_actions 按天计数(/stats 数据源)、stat_member_events 入群/退群/申请明细(/profile 时间线,永久不剪枝)
  • 按需建立 3 张 —— ad_votes ad_vote_allowlist(/ad 投票)、dryrun_groups(旧版 killer_mode 表已停用,线上残留无害)
  • 联合封杀 5 张(按需) —— 数据源:fed_changelog 黑名单变更流(每人只留最新一条)、fed_keys 发出去的 key(只存哈希);订阅方:federated_blacklist 同步来的名单、fed_exempt 本地豁免、fed_state 同步游标与状态
  • 广告数据 —— 判定:ad_fingerprints 指纹库(keyword/domain/username/bio 四类)、ad_user_screening 旧观察兼容记录、ad_sample_embeddings AI 样本与向量、ad_domain_whitelist 域名白名单、ad_profile_shapes 资料形状库、ad_spam_texts 同款直封名单;素材指纹三张:ad_avatars 头像、ad_images 正文图片(kind 标识素材类型,动态媒体使用可识别缩略图)、ad_badges 会员标 + 正文贴纸 emoji(同一 id 体系共用一张表与同一道安全阀)—— 三者 verdict 同为 pending/ad/clean 三态,/ignore 纠错口径一致;流程:ad_group_members 名册、ad_scan_state 滚动复查游标、ad_learn_snapshots /recent 冻结快照、ad_confirm_tokens 二次确认令牌、ad_join_checks 入群检查流水(含正常号,留 30 天)、ad_dryrun_log 演练命中流水(含整份 evaluation 供按钮回放,留 30 天)、ad_pending_snapshots 已处罚及误封纠错快照(100 年不过期,/ignore 后置 expires_at=0 不再算案底)、ad_link_cache 资料挂载链接解析缓存(两本案底 ad_known 查用户黑名单、ad_confirmed 自举标记,按 fetched_at 6 小时过期)、ad_group_admins 配置群管理员同步(群内提权/撤职即时写、cron 全量兜底,热路径的免检读它)、ad_profile_ok 资料临时放行(按「username+昵称+简介」哈希记到期时间,复判确认资料正常后免掉资料这一路;改资料即失效,命中位置最长 72 小时,/ignore 不涉及该表)

上述表与字段按需建立,无需手动 SQL。ad_automatic_case_targets 保存实际自动目标与归属;ad_dryrun_sessions、ad_dryrun_close_cases 保存轮次、冻结边界、分批游标、删除与学习结果,ad_dryrun_close_bans 按轮次、用户、目标群记账,ban_scope_snapshot 冻结收尾目标;ad_dryrun_report_parts 保存下载分片及发送回执,ad_dryrun_learning_receipts 防止中断重复加权,ad_dryrun_material_labels 保存第一主人明确勾选的素材标签。group_blacklist.auto_case_id 支持精确回滚。原图片相似、正文骨架、正常反例及学习统计保留。

新规则不批量清空或迁移历史名单;已开始的旧本群收尾作业保持原范围,重试不会自动扩成全局。

部署

1. 安装 Wrangler

npm install -g wrangler
wrangler login

2. 创建 D1 数据库

wrangler d1 create tg-unban-bot-plus

把返回的 database_id 填进 wrangler.toml 的 [[d1_databases]],binding 必须是 DB。

3. 创建批量任务 Queue

wrangler queues create tg-unban-bot-plus-bulk

绑定名必须是 BULK_QUEUE。

4. 绑定 Workers AI(可选,广告检测第三、四层)

wrangler.toml 加 [ai] 段、binding = "AI";Dashboard 部署则在 设置 → 绑定 → 添加绑定 → Workers AI,名字必须正好是 AI。不绑则降级两层。

5. 启用 Observability(可选)

wrangler.toml 加 [observability.logs] enabled = true —— 回执只有中文原因,英文原文在 Worker 日志。

6. 设置环境变量

完整清单见 环境变量。下面只列关键点。

6.1 最小可用配置(4 个必填项)

wrangler secret put TOKEN        # 你定的随机字符串,用作 HTTP 接口密码
wrangler secret put BOT_TOKEN    # BotFather 给的 token
wrangler secret put GROUP_ID     # -1001234567890(可逗号分隔多群)
wrangler secret put WEBHOOK_SECRET # 独立的随机字符串,用于验证 Telegram 更新来源

6.2 推荐加上(强烈建议)

OWNER_IDS —— 主人 + 副主人 TGID,第一个是主人;不填则不发任何私聊通知。

可选 —— 解封文案 SELF_UNBAN_KEYWORD START_WELCOME SELF_UNBAN_PROMPT SELF_UNBAN_APPROVED _NOLINK SELF_UNBAN_CONTACT_GROUP;群与权限 SUPER_ADMIN_IDS KILLER_MODE_GROUPS KILLER_ADMIN_IDS STAT_SEARCH_GROUPS PROFILE_LOOKUP_GROUPS STATIC_USER_PROFILES;联合封杀 FED_SOURCE_URL FED_SOURCE_KEY;其它 ADMIN_PASSWORD BLACKLIST_PAGE_LIMIT GKY_BANLIST_ENDPOINT FLASH_MESSAGE_TTL_MS MSG_CACHE_SIZE STATS_TZ_OFFSET;广告阈值 AD_*(含 AD_JOIN_SCORE_THRESHOLD)建议一个都不填,理由见 阈值调优与运维。默认值见源码顶部 =可修改= 区段。 `

6.3 老部署升级需要做什么

  • Webhook 校验 —— 本版本不再允许未配置或非法的 WEBHOOK_SECRET 放行。升级前先在仍运行的旧版本完成有效密钥配置,访问 /{TOKEN} 重新注册,并确认消息正常接收,再发布本版本。仅填写密钥而未重新注册,Telegram 不会发送匹配的头
  • wrangler.toml —— 保留 keep_vars = true,并启用 compatibility_flags = ["nodejs_als"]。手动上传 _worker.js 时也需要启用 nodejs_als 兼容标志,供请求状态隔离使用
  • 动态素材模块 —— 一并保留 ad-media.js、vendor/tlottie.wasm 及许可证。使用 wrangler deploy 自动打包依赖;单独替换 _worker.js 会缺少模块。无需增加转码服务或新的绑定
  • 自动检测与学习 —— 观察和待人工判断通知不再自动发送,原通知按钮与 /spam、/ban、/sban 权限保留。第一主人有效引用上报及自动判定后的学习失败会在后台续接,已完成的项目不重复学习
  • 素材覆盖 —— 静态图片检查原图,视频和 WebM 使用模型的 video_url 输入,TGS 分批解码全部帧并保存进度。未查完、文件下载失败或模型额度不足会保留为后台待处理;图文组合判断不把正常图片单独学成广告。实际模型准确率需要运行数据验证
  • 队列 —— 保留消费者 max_retries = 3(与源码的重试上限一致)。临时故障按当前消息有限重试;已保存成功的群操作不会重放,重试耗尽或永久错误会记录失败,仍可按原权限用 /jobrun 续跑
  • 数据 —— 无需手动 SQL,表结构自动迁移,黑名单一条不动
  • 订阅 —— 改过 allowed_updates 必须重新访问一次初始化地址
  • AI —— 绑了 AI 记得发几次 /warmup 补满向量

7. 部署 Worker

wrangler deploy

Workers 已连 GitHub 时,git push 即自动部署。

发布前可运行 wrangler deploy --dry-run 检查打包;广告防线的本地行为验证使用 node --no-warnings --test tests/test_ad_defenses.mjs tests/test_runtime_safety.mjs,测试使用模拟 Telegram/AI,不向真实群聊发送消息。

8. 初始化 Webhook

浏览器访问 https://你的Worker域名/{TOKEN} —— 这一步注册 Webhook + 下发 secret_token 和 allowed_updates + 注册命令菜单 + 设置第一主人的小程序菜单。修改 WEBHOOK_SECRET、allowed_updates 或升级小程序入口后必须重访一次。检查返回的 Webhook 注册结果和 MiniApp.已设置;菜单失败会单独说明原因,重试初始化即可。

Telegram 管理小程序

部署后先配置 OWNER_IDS,用其中第一个账号私聊机器人发送 /start,再访问上面的初始化地址。在该账号与机器人的私聊中点击菜单按钮 「群务台」 打开。现有 21 条菜单命令与全部命令处理逻辑保留,可继续手动输入。

模块 支持操作
群组管理 查看预设与动态治理群、添加动态群、停止动态群治理、让机器人退出群
黑名单 搜索用户 ID / 原因 / 备注、分页、移除黑名单并逐群解除禁言与封禁
广告治理 查看指纹、样本、已处罚记录、检测规则与冻结证据,只有误封时需要纠错回滚;不展示观察工作队列
用户查询 按 TGID 查看资料、黑名单、发言统计、处罚及事件记录、外部风险查询

页面内置于 _worker.js,使用同一个域名,无需独立前端部署或新增环境变量。支持 Telegram 明暗主题;停止治理、退群、解封和误报处理都有确认弹窗,逐群失败会显示具体结果。环境变量里的群不能在页面停止治理,需修改 GROUP_ID;退出这些群后也需移除对应配置。

GET /app 仅提供公共页面,不读取数据库。管理 API 为 POST /app/api/<action>,JSON 请求携带 Telegram.WebApp.initData。后端按 Telegram 的 HMAC-SHA256 规则验签,并检查签名用户是否为第一主人;副主人和普通群管理员无访问权限。签名有效期为一小时,过期后关闭并重新打开。页面与 URL 不包含 Bot Token 或初始化密钥;直接在普通浏览器打开只会显示 Telegram 入口提示。

操作失败后先刷新查看状态,再重试。解封会报告解除禁言与解除封禁两步的结果;小程序误报回滚未完成时保留待复核记录。更改治理范围和调用 Telegram 接口的操作仅在主动确认后执行。

杀手后台 —— KILLER_ADMIN_IDS 里的人(非主人)初始化后私聊菜单出现 「杀手后台」(对方须先私聊过机器人),五页:群组(含运行检查)/ 黑名单(封禁、解封、搜索)/ 用户(查询、发言检索)/ 通知 / 统计。范围只有杀手群、只写杀手黑名单,主黑名单只读;超过 19 人转批量任务;封禁、解封、通知都抄送第一主人。主后台接口对他一律 403。

第一主人从主后台顶部 「杀手后台」 按钮进入同一个页面,顶部标 「第一主人」、带「返回群务台」;范围同样只有杀手群,操作人记为本人、不抄送给自己。两方都封不了主人与杀手权限持有者。

使用方法

用户自助解封

  1. 私聊发 /unban → 返回自助解封检查清单
  2. 复制 <code> 里整句并发送 → 逐字整句匹配(多 / 少标点、夹带字符一律拒绝)
  3. 解封全部配置群 → 成功回执 + 主群「联系管理员」按钮

在 D1 全局黑名单中的用户第一道闸就被拦(永久封禁,只能 /unban 移除)。

二次审核流程

两个按钮,复制内容交真人管理员使用:

  • 📋 点击复制 GKY 添加白名单代码 —— 两行 GKYbotSave\n用户ID,粘贴到封禁记录对应的群发送
  • 📋 点击复制 本地解封命令 —— /unban 用户ID,有权限的管理员发送(复制本身不改 D1)

复制按钮只进剪贴板,机器人不会自动代发(GKY 不认其它 Bot 代发的 GKYbotSave)。

HTTP 接口

查询封禁记录(公开)

GET /{TGID} —— 给普通用户自查,不要 TOKEN、只读。页面带查询框,同时显示 GKY 封禁库记录和本机器人黑名单的「是否封禁 + 封禁日期」(原因 / 备注 / 操作人不公开);?format=json 返回 {tgid, local, gky}。GET /banlist?tgid= 只查 GKY,返回 JSON。

联合封杀(订阅别人的黑名单)

  • 分享自己的:后台「联合封杀」分区 → 生成 key → 把页面上的地址和 key 发给对方。key 只显示一次,列表里能看到每把 key 的最后访问时间,随时可吊销。对方只拿得到 TGID 和封禁 / 解封时间,拿不到原因、备注、操作人。
  • 订阅别人的:Dashboard 填 FED_SOURCE_URL + FED_SOURCE_KEY,每 10 分钟同步一次。名单里的人在全局群发言、进群,和本地全局黑名单一样处置;独立群不接。对方解封,下次同步自动移出。
  • 豁免:后台「联合封杀」分区可豁免 / 取消豁免;/unban 或后台解封联合名单里的人会自动本地豁免,之后对方再封也不拦。
  • 接口:GET /fed/changes?since=游标,请求头带 Authorization: Bearer 加 key,key 错返回 401。

黑名单导出(受 TOKEN 保护)

GET /{TOKEN}/export —— 浏览器看 HTML 表格(带搜索),?format=json / ?format=csv 下载(CSV 带 BOM,Excel 不乱码),POST 同路径返回 JSON;必须带正确 TOKEN 否则返回 405,字段全部 escapeHtml 转义。

黑名单导出(给可信用户,不用交出 TOKEN)

第一主人私聊机器人发 /exportpass,把收到的登录地址 https://你的域名/export 和临时密码转发给对方。对方输入密码后能看到与 /{TOKEN}/export 相同的黑名单(带搜索、JSON / CSV 下载),其他管理接口一个都进不去。密码一次性:登录成功一次即作废,24 小时没用也作废;关掉浏览器后要新密码重新登录。不用配任何变量(需绑定 D1)。

黑名单清扫入口(受 TOKEN 保护)

GET /{TOKEN}/purge 分批清扫 D1 存量黑名单里仍在群里的人;GET /{TOKEN}/purge/run 立即执行一次(默认分批,避免撞子请求上限)。

常见问题

部署后却不生效:三个静默失效点

  1. Webhook 没初始化 = 一条消息都收不到。 部署完必须访问 /{TOKEN};改过 allowed_updates 必须重访一次(一旦显式声明,默认清单整体失效)。这一步不调不报错、日志也干净。确认:/health 里 webhook 状态应为 set。
  2. 环境变量与源码默认值打架 = 你改的没生效。 优先级是环境变量 > 源码默认值:后台已填同名变量时,改 _worker.js 顶部 DEFAULT_* 不生效,改源码要 wrangler deploy。反向地 wrangler.toml 必须 keep_vars = true,否则部署会用本地值覆盖远端变量(fork 后改过记得改回来)。
  3. D1 或 AI 没绑对 = 功能静默降级。 binding 必须正好是 DB / AI、database_id 要对得上:缺 D1 时自助解封失败关闭、各命令提示未绑定;缺 AI 时 /adstats 标注「未绑定,降级为评分 + 指纹两层」。

收不到、没反应

  • 收不到群内手动封/解封的同步信号 → bot 必须是群管理员,然后重访初始化地址重订 webhook。
  • 第一主人收不到详情 / 通知发不出 → 先私聊 bot 发一次 /start 建立会话,并核对 OWNER_IDS[0];bot 不能主动给没聊过的人发私信。配置了 OWNER_IDS 也一样。
  • 管理员命令没反应 → /ban /spam /check 鉴权是「任一配置群的管理员或群主」;/blacklist 只能私聊发;/sban 更严(限第一主人、副主人、该群群主,私聊仅前两者),其余人在群里完全静默。未授权者发隐藏指令群内静默、私聊才回「权限不足」,按钮点击时重新验权限。
  • 群内发命令后还有 5 秒闪屏吗 → 不会,群内只发简洁汇总,完整明细私聊第一主人;群内发令者自己收不到详情,私聊执行时自己收到。
  • 操作人标签 → OWNER_IDS[0] 标主人、其余标副主人,剩下按调用上下文兜底标管理员。

执行失败

  • /ban /sban /spam 报「Telegram 封禁失败 0/N」 → 群设置 → 管理员 → 本机器人,打开封禁用户(禁言与踢出都靠它);/sban 撤回历史发言另需删除消息权限。
  • 自助解封通过后仍不能发言 → 三种情况:kicked 要重新加群、被其它系统限言、在 GKY 全局黑名单(会触发二次审核提醒)。
  • 发了正确确认句却没被解封 → 必须完整逐字粘贴整句,多/少标点、夹带字符一律拒;改过确认句要用当前生效那句。
  • 批量超过 50 个 → 单次上限 50,超过拆批;预算不足的自动转批量任务(/job 查、/jobrun 补跑)。
  • 黑名单用户的旧消息 → 踢出时自动撤回最近 48 小时(平台上限),更早的只能手动删;/ban 禁言不撤回,要清历史引用回复 /spam,或在群里对单个 TGID 发 /ban 顺带清扫当前群。
  • Windows 下 git push 报 socks5 代理错 → 不是本项目问题,把 git 代理改成 http://127.0.0.1:端口。

查询与外部依赖

  • /banlist?tgid=... 返回失败或无数据 → 依赖外部服务 GKY_BANLIST_ENDPOINT,外部不可用时等恢复或换后端(HTML 须与 parseBanlistHTML 兼容)。
  • /admins 显示「昵称:未获取 用户名:未获取」 → Bot API 只能查 bot 所在群的成员,把 bot 拉进对方所在的群填 PROFILE_LOOKUP_GROUPS,或用 STATIC_USER_PROFILES 填静态资料。
  • 想看 Telegram 返回的英文原文 → 回执只有中文原因,英文在 Cloudflare 后台 → Workers → 本 Worker → 日志。

广告检测

  • 正常用户被误封 → /pending 拿序号 → /ignore 序号:一键解封 + 给命中指纹加误报,累计 3 次该指纹自动退役。
  • 广告号没被检测到 / 同款查杀漏了号 → 引用回复 /spam 最快(自动学指纹,该文案进同款直封名单后直发即删 + 封);手工加 /addword;被抢先删的用 /recent + /learnlast。
  • /adstats 显示「降级为评分 + 指纹两层」 → Workers AI 没绑上,wrangler.toml 加 [ai] 段,绑定名必须正好是 AI。
  • 广告检测的 18 张表建失败 → 既有功能完全不受影响,广告层静默跳过并进 60 秒冷却,用 /adstats 诊断。
  • 处置完广告,正文又被某个 bot 带引用贴回群里 → 已拆两条通道:bot 发的广告 → 删 + 封;已处置正文的重发 → 只删不封。
  • 管理员置顶后被 bot 删除并取消置顶 → 两种成因:服务消息被清扫缓存误删(v2 已修复,旧版升级清一次存量缓存);频道转发帖本身被广告检测删掉(另一条路径)。

License

本项目沿用原项目 MIT License。

原作者:CMLiussss — Copyright (c) 2026 原项目:CF-Workers-TGUnbanBot

再次特别鸣谢原作者 CMLiussss 设计的源代码支持 🙏

详见 LICENSE 文件。

About

Telegram 群组自助解封机器人 | 基于 Cloudflare Workers + D1 | 多群管理 / 广告检测 / 黑名单导出 / GKY联查 / 314条离线测试 | Fork of CF-Workers-TGUnbanBot【项目取用cmliu/TGUnbanBot】

Topics

Resources

Stars

7 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages