Skip to content
Engineering

以编程方式打开电子邮件:从原始格式到 JSON

| | 4 分钟阅读
Open an Email Programmatically: From Raw to JSON
Open an Email Programmatically: From Raw to JSON

电子邮件是许多系统仍然依赖的最后一个”以人为本”的界面之一。但如果你正在构建 AI 智能体、LLM 工具链或 QA 测试框架,你最终需要以编程方式打开电子邮件,仅提取有用的工件(OTP、魔法链接、发票 ID、重置 URL),然后继续进行。

困难的部分是电子邮件以一个混乱的、有数十年历史的标准堆栈的形式到达:RFC 5322 标头、MIME 多部分正文、奇怪的编码,以及从未打算被测试(或智能体)解析的 HTML。本指南介绍了”原始电子邮件”实际是什么,为什么很棘手,以及如何可靠地将其转换为你的自动化可以信任的 JSON 格式。

以编程方式”打开电子邮件”意味着什么

当人类”打开电子邮件”时,电子邮件客户端悄悄地做了很多工作:

  • 解析消息格式(标头加正文)
  • 解码传输编码(base64、quoted-printable)
  • 选择要显示的正文(通常是 text/plain 或 HTML)
  • 解压附件
  • 规范化日期、地址和字符集

以编程方式,你需要决定对你的工作流程来说”打开”意味着什么。对于自动化,“打开”通常意味着:

  • 定位正确的消息确定性地(没有脆弱的邮箱搜索)
  • 解析和规范化为稳定的模式
  • 提取一个小的、可验证的工件(OTP、链接、令牌)
  • 记录足够的信息以调试失败而不泄露敏感内容

一个好的心理模型是:将电子邮件视为不受信任的入站事件,而不是文档。

原始电子邮件,你实际收到的格式

大多数系统最终将电子邮件表示为原始 RFC 5322 消息:由标头和正文组成的文本和字节块。如果你需要标准参考,从 RFC 5322(消息格式)和 MIME 系列开始,如 RFC 2045(MIME 基础)。

一个”原始”消息通常包括:

  • 标头:键/值对,如 FromToSubjectDateMessage-ID,以及许多其他
  • 正文:有时是纯文本,通常是 HTML,经常是带有边界的多部分
  • 附件:表示为 MIME 部分,通常是 base64 编码

MIME 是为什么”只解析正文”会失败

如果你只看过纯文本电子邮件,解析会很容易。实际上:

  • 许多消息是 multipart/alternative(both text/plain 和 text/html)
  • 一些是 multipart/mixed(正文加附件)
  • 一些包含嵌套的多部分
  • 正文可以被编码(quoted-printable、base64)
  • 字符集各不相同(UTF-8、ISO-8859-1 等)

这就是为什么对 HTML 进行正则表达式处理或在空行上分割很快就会变得脆弱。

从原始到 JSON:在自动化中持续有效的规范化管道

一个强大的”原始到 JSON”管道有几个清晰的阶段。这与实现无关:你可以在自己的服务中用库来做,或者使用收件箱 API 产生的 JSON。

一个简单的流程图,显示传入的电子邮件经过标记为:原始 RFC 5322、MIME 解析、解码+规范化、提取链接/OTP、为测试和 LLM 智能体输出 JSON 的阶段。

阶段 1:解析结构(标头、MIME 树)

在这个阶段,你想要:

  • 安全地解析标头(处理折叠标头、重复)
  • 构建部分的 MIME 树
  • 识别候选正文(text/plain、text/html)
  • 识别附件(文件名、内容类型、大小)

阶段 2:解码和规范化

规范化是大多数自动化可靠性的来源:

  • 解码传输编码(quoted-printable、base64)
  • 规范化行尾
  • 将文本转换为一致的 Unicode 表示
  • Date 解析为 ISO 时间戳(但保留原始值以进行调试)
  • 将地址字段规范化为结构化对象(姓名、地址)

阶段 3:选择和清理内容

对于自动化和智能体,优选可预测的内容:

  • 在可用时优选 text/plain
  • 保留 HTML,但将其视为次要(适合渲染,解析有风险)
  • 删除或忽略危险元素(脚本、奇怪的重定向)

阶段 4:提取自动化工件

而不是”理解整个电子邮件”,提取你的工作流程需要的内容:

  • 验证链接(以及最终目标主机允许列表)
  • OTP 候选(带有紧密模式和上下文检查)
  • 关键标识符(订单 ID、票据 ID)

阶段 5:发出带有稳定字段的 JSON

你的 JSON 输出应该支持:

  • 确定性匹配(message_id、inbox_id、相关 ID)
  • 简单断言(主题包含、来自域等于)
  • 最小工件提取(otp、verification_url)
  • 可调试性(原始标头快照、接收时间戳)

这里有一种有用的方法来思考将原始电子邮件映射到 JSON 字段。

原始电子邮件元素 它看起来的样子 自动化所需的 JSON 为什么重要
Message-ID 标头 Message-ID: <abc@domain> message_id 去重和幂等性
Date 标头 Date: Tue, 30 Jan... received_at(ISO)、date_raw 时间断言,调试延迟
From/To RFC 5322 地址格式 from: {name, address}to: [...] 可靠的发送者检查
MIME 部分 多部分边界 texthtmlattachments[] 避免解析错误的部分
传输编码 base64、quoted-printable 解码的字符串和字节 防止垃圾输出
正文中的链接 HTML 锚点、纯 URL links[](规范化) 更安全的魔法链接处理

破坏天真”打开电子邮件”实现的陷阱

即使是成熟的团队也会被相同的电子邮件边缘情况所困扰。如果你正在构建程序化的”打开电子邮件”路径,请预先为这些设计。

重复和折叠的标头

标头可以合法重复,并且可以跨行折叠。如果你天真地将标头映射到字典中,你可能会丢失数据或解析错误。

选择错误的正文

很多系统意外地解析:

  • HTML 跟踪像素部分而不是用户可见的内容
  • 页脚而不是 OTP 行
  • 电子邮件中的转发消息

在可能时优选 text/plain,并明确说明你如何选择”主要”正文。

编码和字符集

如果你没有一致地解码传输编码和字符集,你会看到:

  • 破损的 Unicode
  • 缺失的标点符号,这可能会破坏 OTP 提取
  • 测试中的错误比较

时间不是单一字段

电子邮件时间戳是混乱的。Date 标头是发送方提供的,并不总是值得信赖的。你的接收系统的时间戳对于延迟和超时通常更有用。

HTML 解析是一个安全边界

如果你对电子邮件内容运行智能体,将 HTML 视为对抗性输入。一个安全的策略是:

  • 提取候选链接,然后对允许列表验证它们
  • 避免在自动化中”点击”未知 URL
  • 保留原始内容用于审计,但默认情况下不要将完整的 HTML 馈送给 LLM

对于解析像 Message-ID 和相关字段这样的标识符的更深入可靠性指导,Mailhook 有一个专门关注标头解析的单独帖子:Headers Email Guide: What to Parse for Reliability

为 LLM 智能体提供的实用 JSON 合约

智能体最适合小的、结构化的输入。而不是给 LLM 整个电子邮件(特别是 HTML),提供一个紧凑的 JSON 对象,它是:

  • 确定性的
  • 最小的
  • 可追溯到原始消息

一个示例”智能体安全”的形状可能看起来像这样:

{
  "message_id": "<...>",
  "received_at": "2026-02-01T20:12:33Z",
  "from": {"address": "[email protected]", "name": "Example"},
  "to": [{"address": "[email protected]", "name": null}],
  "subject": "Your login code",
  "text": "Your code is 123456",
  "links": ["https://example.com/verify?token=..."],
  "attachments": [{"filename": "invoice.pdf", "content_type": "application/pdf", "size": 48211}]
}

然后你可以添加第二层:你的测试或智能体工具实际消费的小提取对象(例如 { "otp": "123456" })。这保持你的工作流程简单并减少 LLM 对敌对内容的暴露。

自己构建 vs 从收件箱 API 消费 JSON

你有两种广泛的方法:

  • 自己解析原始电子邮件(通过 IMAP/POP、直接 SMTP 接收或提供商 API)
  • 使用提供结构化 JSON 和确定性检索的可编程收件箱服务

这里有一个决策表,倾向于匹配现实世界的工程权衡。

方法 最适合 常见痛点 典型结果
IMAP 邮箱爬取 快速原型 不稳定的搜索,并发冲突,慢轮询 在 CI 和并行运行中中断
提供商 API(Gmail/Graph) 带有账户的内部工具 OAuth、配额、长期身份 有效,但操作上很重
运行你自己的 SMTP 捕获 本地集成测试 与真实电子邮件的可投递性差异 本地很好,在分阶段时不完整
带有 JSON 输出的可编程收件箱 API QA 自动化、LLM 智能体、验证流程 需要集成另一个 API 对自动化最确定性

如果你的核心需求是”以编程方式打开电子邮件并获得 JSON”,关键属性是不需要 HTML 抓取的机器可读输出

使用 Mailhook 将电子邮件打开为 JSON(Webhook 优先,轮询后备)

Mailhook 围绕可编程一次性收件箱构建。而不是创建完整的电子邮件账户,你通过 API 创建收件箱,在你的工作流程中使用生成的地址,然后接收消息作为结构化 JSON

相关 Mailhook 功能(来自产品描述):

  • 通过 API 创建一次性收件箱
  • 结构化 JSON 电子邮件输出
  • RESTful API 访问
  • 实时 Webhook 通知
  • 电子邮件轮询 API
  • 用于安全的签名有效负载
  • 批处理电子邮件处理
  • 共享域和自定义域支持

因为 API 在发展,端点和有效负载的权威来源是 Mailhook 的实现参考。在你连接智能体工具或测试之前,确保查看 llms.txt

参考流程(概念性)

一个可靠的自动化流程看起来像这样:

  • 为运行(或智能体会话)创建新收件箱
  • 触发被测系统向该地址发送电子邮件
  • 等待投递(优选 Webhook,使用轮询作为后备)
  • 消费 JSON 有效负载
  • 仅提取你需要的内容(OTP/链接)

这里是说明集成形状而不假设任何特定端点名称的伪代码:

# 伪代码:查阅 https://mailhook.co/llms.txt 获取确切的 API 字段和路由。

inbox = mailhook.create_inbox(
  webhook_url="https://your-service.example/mailhook/webhook"
)

email_address = inbox["address"]
inbox_id = inbox["inbox_id"]

app.trigger_signup(email=email_address)

# Webhook 优先:你的 Webhook 处理程序存储由 inbox_id 键控的 JSON 消息。
# 轮询后备:等待超时和退避。

message = mailhook.wait_for_message(inbox_id=inbox_id, timeout_seconds=60)

otp = extract_otp(message["text"])
verify_url = extract_allowed_link(message.get("links", []))

assert otp is not None or verify_url is not None

验证 Webhook 签名

如果你接受入站 Webhook,将它们视为任何其他外部请求:

  • 验证签名(Mailhook 支持签名有效负载)
  • 使用幂等性来处理重试
  • 仅存储你需要的内容,只要你需要它

同样,确切的签名方案和标头应该来自 llms.txt 中的合约。

使电子邮件自动化变得无聊(在好的方面)的设计技巧

目标不是”完美解析电子邮件”,而是使你的自动化可预测。

优选隔离和相关性

如果多个测试运行或智能体会话共享收件箱,你会重新引入最难的问题:找出哪个消息属于哪个运行。隔离的收件箱完全避免了邮箱搜索。

在意图上断言,而不是在呈现上

HTML 经常变化。你的断言应该针对稳定的属性:

  • 发送者域
  • 主题意图
  • 单个 OTP 的存在
  • 其主机在允许列表中的验证链接

保持原始消息可用于调试

当某些东西失败时,你想知道:

  • 消息到达了吗?
  • 它有什么标头?
  • 你解析了正确的 MIME 部分吗?

这就是”原始加规范化 JSON”有用的地方。自动化在规范化字段上运行,而工程师使用原始上下文进行调试。

这让你处于何处

要在 2026 年以编程方式打开电子邮件,你有两个现实的选择:

  • 成为电子邮件解析专家(RFC 5322、MIME 边缘情况、编码怪癖、安全陷阱)
  • 使用已经进行规范化并为你提供测试和智能体可以消费的 JSON 的收件箱抽象

如果你的主要需求是智能体工作流程和 QA 可靠性,获胜策略通常是:将电子邮件视为事件流,每次运行隔离收件箱,并消费结构化 JSON

如果你想使用 Mailhook 实现这一点,从 Mailhook llms.txt 中的合约开始,并围绕确定性等待(Webhook 优先,轮询后备)和最小工件提取设计你的工具。

email parsing automation API integration AI agents QA testing

相关文章