在日常的自动化与 AI Agent 实践中,处理各类通知、账单邮件是一个极其高频的需求。为此,我开源了两个互相配合的项目:

  • mail-statement-parser:纯粹、无状态的底层邮件抓取与解析引擎。
  • lite_agent:一个轻量级的 AI Agent 框架,通过技能挂载调用底层解析引擎,实现微信端对话与推送。

近期,我们对邮件模块进行了一次“大换血”级别的重构。本文将详细盘点新增的功能:如何优雅地统一接入国内外四大主流邮箱(QQ、163、Gmail、Outlook),如何彻底告别“密码错误”,全面拥抱 OAuth2Microsoft Graph API


💡 为什么我们需要重构鉴权?

过去,我们习惯于在配置里写死账号和“应用专用密码”(App Password)去走 POP3/IMAP。但现实是残酷的:

  • Google / Microsoft 等海外巨头正在疯狂收紧风控。哪怕你填了应用专用密码,在异地 VPS 上请求也很容易直接抛出 [AUTH] Username and password not acceptedaccess_denied
  • 传统 POP3 的局限性。连接慢、拉取全量邮件重试成本高。

为了解决这个问题,我们在项目中引入了全新的鉴权机制,针对不同厂商“对症下药”。

支持的四大邮箱与接入方案

  1. 国内阵营(QQ 邮箱、网易 163)
    • 沿用最稳定、高效的 Basic Auth (应用授权码) + POP3/IMAP 协议。
  2. 国外阵营(Gmail、Outlook)
    • Gmail:全面接入 OAuth 2.0 (Desktop App / Web App Flow),通过本地回环获取 Token 并加密落盘,安全穿透 Google 风控。
    • Outlook/Office365:直接拥抱现代化,抛弃 POP3,自动路由走 Microsoft Graph API,不仅免去了繁琐的邮件协议配置,抓取速度和稳定性也得到了史诗级提升。

🛠️ 极简的配置体验

为了兼容不同的鉴权模式,我们在 mail-statement-parser 中重新设计了 email-config.local.json

1. 传统授权码配置(以 QQ 为例)

国内邮箱极其简单,只需要提供 authCode 即可:

{
  "provider": "qq",
  "account": "yourmail@qq.com",
  "account_name": "我的QQ",
  "authCode": "你的十六位授权码"
}

2. 现代 OAuth2 配置(以 Gmail / Outlook 为例)

你需要去 Google Cloud Console 或 Azure AD 申请一对 Client ID 和 Client Secret(针对 Desktop / Web App)。
配置中摒弃了密码,取而代之的是 auth_type 和密钥信息:

{
  "provider": "gmail",
  "account": "yourmail@gmail.com",
  "account_name": "我的Gmail",
  "auth_type": "oauth2",
  "client_id": "你的_Client_ID",
  "client_secret": "你的_Client_Secret",
  "imap_proxy": "127.0.0.1:18988"  // 支持配置本地代理,解决国内服务器无法直连的问题
}

3. 一键获取与加密 Token

配置好 client_id 后,你不再需要自己去手搓 OAuth 的繁琐请求。我们在项目中提供了一个专门的工具脚本 oauth_helper.py
只需在终端运行:

python oauth_helper.py authorize gmail
# 或者
python oauth_helper.py authorize outlook

脚本会自动弹出浏览器让你完成授权。拿到 Code 后,系统会利用本机的环境变量 API_AUTH_TOKEN 作为盐值,将 Refresh Token 高度加密并保存(生成 token_gmail.json 等)。
这就意味着,即使你的服务器被黑客连锅端了,没有你的环境变量盐值,他们也绝对无法解密盗用你的邮箱 Token!


🤖 在 LiteAgent 中的丝滑调用

mail-statement-parser 提供了扎实的底层能力,而 lite_agent 则赋予了它灵魂。

我们在 lite_agent 中封装了诸如 ops_mail_reader.pyops_mail_list.py 等 AI 技能。
得益于引擎的重构,现在你在微信端使用时,体验是跨时代的:

场景一:直接查阅最新邮件

你可以对机器人直接发送直通口令:

👉 /mail g 3 (代表抓取别名为 g 的 Gmail 最近 3 封)
👉 /mail qq 5(代表抓取别名为 qq 的 QQ 邮箱最近 5 封)

底层系统会动态识别:

  • 如果是 QQ,走 POP3 传统通道。
  • 如果是 Gmail,自动读取加密的 Token,携带 Bearer Token 走安全通道。
  • 如果是 Outlook,瞬间切换到 Graph API 极速拉取并格式化返回。

场景二:后台定时扫信与 LLM 智能摘要

我们构建了 fetch_only (静默拉取) 和 enrich (LLM 提炼) 的解耦双阶段架构:

  1. 定时任务定期静默触发,快速将新邮件拉入本地 SQLite 数据库中。
  2. 调度池分发给 LLM(如 GPT-4o 或 GLM-4 等),对冗长的营销邮件和账单进行提炼总结。
  3. 发现高优或者临期账单(比如信用卡还款),通过 push_alert 接口,秒级推送到你的企业微信 / 微信上。

🚧 踩坑实录(避坑指南)

在打通 OAuth2 和 Graph API 的过程中,我们踩过了无数深坑。为了让后来的开发者少走弯路,这里特意总结了 Gmail 和 Outlook 配置时的血泪教训:

🛑 Gmail 配置的两大死穴

  1. 必须选择“Web 应用”类型
    在 Google Cloud Console 创建 OAuth 客户端 ID 时,千万不要选择“桌面应用”!Google 最新的控制台 UI 存在设计缺陷(或有意为之),针对桌面应用类型不再提供/显示 Client Secret。这会导致后续本地脚本拉取 Token 时报错。正确的做法是:选择“Web 应用 (Web application)”,并将“已授权的重定向 URI”精确设置为 http://localhost:8080
  2. 切记添加测试账号
    当你的 OAuth 权限屏幕处于“测试 (Testing)”阶段时,即使你拥有 Client ID,直接授权也会报 403 Access Denied 错误。你必须在配置页面手动将你自己的 Gmail 地址加入到“测试用户 (Test users)”列表中,才能成功完成授权闭环。

🛑 Outlook (微软个人账号) 的三大玄学

  1. 彻底放弃传统的 POP 功能
    如果你试图用 Outlook 个人账号走传统的 POP3(哪怕你带了应用密码),你会发现它在异地服务器上几乎 100% 会触发微软极其严苛的“异常登录拦截”。想要一劳永逸,唯一的出路就是老老实实走 Microsoft Graph API
  2. Azure 应用与权限配置
    Graph API 的前置条件极高。你需要登录 Microsoft Entra (原 Azure AD),注册一个全新的应用程序。并且必须在“API 权限”中,手动添加 Microsoft Graph -> Mail.Read 权限。
  3. 必须开启“允许公共客户端流”
    这是最容易卡住的一步!在 Azure 应用的“身份验证 (Authentication)”菜单栏最底部,有一个高级设置名为“允许公共客户端流 (Allow public client flows)”选项。必须将其切换为“是”。如果不开启此项,即便你账号密码权限全对,在使用本地无头脚本换取 Token 时,微软也会无情拒绝你的请求!

🚀 结语

无论你是想要一个无感知的个人账单管家,还是想要一套能深度二开的 LLM 邮件处理流,这套架构都能轻松满足。

感兴趣的朋友,欢迎直接 Clone 体验、提 Issue 和 PR:
👉 解析引擎maifeipin/mail-statement-parser
👉 agent 主控maifeipin/lite_agent

Enjoy hacking with LLM & Emails!

image