最近做了个很小的自动化:把邮箱验证码自动推送到 Telegram 群。
起因是腾讯出了一个 Agent Mail。我第一反应是:这东西正好可以接进 Hermes。Hermes 本来就能跑定时任务、发 Telegram、调工具,如果再接上邮箱,验证码、登录链接、一次性 token 这些东西就可以自动推送出来。
而且我不想改所有已经注册过的网站邮箱。
很多服务都绑在我的 Gmail 上。如果为了验证码推送,逐个把邮箱地址改成一个新的专用邮箱,太麻烦,也有风险。所以当时的思路是:
现有 Gmail
→ 自动转发到 Agent Mail / 专用邮箱
→ Hermes 定时扫这个邮箱
→ AI 判断是不是验证码邮件
→ 是的话推送到 Telegram 群
这个方案的好处是迁移成本低。原来的注册邮箱不用动,只要在 Gmail 里加转发规则就行。理论上,所有验证码邮件都会先到 Gmail,再被转发到专用邮箱,然后由 Hermes 处理。
但跑下来之后,我发现它更像一个临时补丁。
第一个问题是 Token 消耗。
如果把邮件全部转发过去,再让 AI 判断“这封是不是验证码”,那每封邮件都要消耗一次模型调用。验证码邮件本来只是很小的确定性任务,结果变成了持续烧 Token 的分类系统。邮件越多,成本越不受控。
第二个问题是延迟。
链路变成了:Gmail 收到邮件,Gmail 转发,Agent Mail 收到,Hermes 定时任务扫到,AI 判断,再发 Telegram。中间每一步都不算慢,但叠在一起就不够干净。验证码这种东西通常只给 5 到 10 分钟有效期,延迟和不确定性越少越好。

第三个问题是 Agent Mail 没法在收到邮件时直接通知 Hermes。
也就是说,它不是事件驱动的。Hermes 只能用 cron 不断去扫:
* * * * *每分钟问一次“有没有新邮件”。
这就很别扭。邮件本来是一个事件,结果被我做成了轮询。没邮件的时候也要扫,有邮件的时候也可能要等下一分钟。再加上 agently-cli 偶尔会遇到 api.agent.qq.com 的 TLS handshake timeout,整个链路就更脆了。
还有一个实际问题是误报。
有一次一封 newsletter 被识别成验证码邮件,脚本还从正文里抓了几个普通英文单词当 token。验证码推送这种东西,一旦误报多了,就会变成另一个没人想看的通知源。
后来我换成了 maillab/cloud-mail。它是一个基于 Cloudflare 的简易邮箱系统,支持 Email Routing 收邮件、Worker 处理入站邮件、D1/R2 存储、Telegram Bot 推送,也可以用 Workers AI 自动识别验证码。
新的流程是:
邮件发到域名邮箱
→ Cloudflare Email Routing 收到邮件
→ Worker 立刻处理
→ cloud-mail 提取验证码
→ Telegram Bot 推送到群核心变化是:从轮询变成事件驱动。
以前是 Hermes 每分钟主动查邮箱;现在是邮件到了,Cloudflare 主动触发 Worker。路径更短,延迟更低,也不需要本地机器一直参与。
cloud-mail 里已经内置 Telegram 推送。收到邮件后,只要后台打开 Telegram Bot,并配置好 chat id,就能把邮件推到指定群。它还能把识别出的验证码做成一个可复制按钮,手机上点一下就能复制,比从邮件正文里找数字舒服很多。
当然,我并不想所有邮件都进 Telegram。理想状态是只推这些东西:
verification code
security code
login code
one-time code
OTP
magic link
verify your email
password reset
验证码
验证代码
魔法链接
密码重置最终逻辑应该是:
收到邮件
→ 判断是不是认证/验证码相关
→ 提取验证码或登录链接
→ 有结果才推 Telegram
→ 普通邮件静默保存或转发
这件事也让我重新想了一下 Agent 的边界。
不是所有自动化都需要 Agent 常驻参与。验证码推送不需要大模型思考,也不需要聊天上下文。它要的是快、稳、少误报、低成本。
所以更好的架构是:
事件源自己触发
→ 小 Worker 做确定性处理
→ 只有复杂判断才交给 AgentHermes 很适合用来搭系统、调试规则、写脚本。但真正长期运行的部分,能交给更轻的小工具就交给小工具。
我最后关掉了那个每分钟轮询的验证码任务。不是因为它不能用,而是因为这件事已经有更适合的形态了。
Discussion