电子邮件是大多数软件团队仍需要自动化的最后一个”人机优先”接口之一。如果您正在构建注册验证流程、QA测试或需要完成现实任务的LLM代理,您最终需要通过API获取邮件,可靠地,并且以不需要脆弱HTML抓取的格式。
可编程收件箱API通过将入站邮件转换为结构化JSON,然后通过webhooks(推送)和/或轮询(拉取)将其传递给您的代码来解决这个问题。本文解释了核心设计、实用的JSON契约应该是什么样子,以及如何将其连接到确定性且安全的自动化中。
如果您特别要集成Mailhook,标准的机器可读集成参考是项目的llms.txt:Mailhook API契约 (llms.txt)。
“通过API获取邮件”的真正含义(以及为什么JSON是关键)
当开发者说”获取邮件”时,他们通常指以下之一:
- 从邮箱获取消息(IMAP/POP),然后自己解析RFC 5322和MIME。
- 接收消息事件(webhook),然后存储和解析。
- 通过ID查询收件箱,获取用于自动化的标准化字段和内容。
对于自动化和代理,困难的部分很少是SMTP传递本身。痛点在于传递之后的一切:
- MIME是多部分、嵌套的,充满编码边缘情况。
- 头信息可能被折叠、重复,并且由攻击者控制。
- 正文可能是HTML密集型的、充满跟踪的,或者缺少
text/plain。 - 时机是不确定的,您不能”睡眠5秒钟”并期望可靠性。
良好的收件箱API将原始邮件(由RFC 5322加MIME定义,参见RFC 2045)转换为稳定的JSON表示,这样您的自动化就可以断言字段,而不是脆弱的渲染。
自动化友好的模型:收件箱和消息,而不是长期账户
关键转变是将收件箱视为短期资源,更接近消息队列而不是个人邮箱:
- 您以编程方式创建收件箱。
- 您获得该收件箱的可路由电子邮件地址。
- 您的系统向该地址发送邮件。
- 您以JSON格式检索消息(webhook或轮询)。
- 您可选择性地轮换或过期收件箱以保持严格的隔离。
这种”收件箱优先”的方法使并行CI运行、多代理工具链和重试密集的验证流程变得可预测。

JSON应该是什么样子?QA和LLM代理的实用契约
不同的提供商暴露不同的模式,但健壮的自动化往往需要相同的概念片段:
| 邮件概念 | 为什么需要它 | JSON字段示例(说明性) |
|---|---|---|
| 稳定的消息标识符 | 去重、幂等性 |
message_id, provider_id, rfc822_message_id
|
| 到达时间戳 | 时间预算、调试 | received_at |
| 信封地址 | 路由和断言 |
from, to, cc, reply_to
|
| 主题 | 匹配和相关性 | subject |
| 头信息(标准化) | 调试、相关性、认证信号 |
headers(映射或列表,标准化) |
文本内容(首选text/plain) |
代理的安全解析 |
text, text_plain, body_text
|
| HTML内容(可选,谨慎处理) | 人工调试、回退 |
html, body_html
|
| 附件元数据 | 安全性、工件提取 |
attachments[]与filename, content_type, size
|
| 原始源(可选但有价值) | 解析器不一致时的取证 |
raw或source
|
对代理和测试环境的两个实用建议:
-
在断言和提取中首选
text/plain。 HTML对人类有用,但对自动化来说是一个大的、攻击者友好的表面。 - 保持原始源可用于调试。 当CI中出现问题时,能够检查确切的传递内容可以节省数小时。
Mailhook的产品定位明确围绕这一点:通过API创建一次性收件箱并以结构化JSON格式接收邮件,专为LLM代理和QA自动化而构建。对于确切的字段名称和有效负载格式,请使用标准参考:mailhook.co/llms.txt。
检索消息:webhook优先,轮询回退
有两种常见的”通过API获取邮件”方式,大多数生产设置同时使用两种。
Webhooks(推送)
使用webhook,收件箱提供商在新消息到达时调用您的端点。这对于想要快速、事件驱动工作流的情况来说是理想的。
优势:
- 低延迟,无轮询循环
- 自然的事件流模型
- 当许多收件箱处于活动状态时扩展性良好
操作要求:
- 您必须实现重试和幂等性
- 您必须验证真实性(签名)
- 您需要一个可从公共互联网访问的端点(或安全隧道)
Mailhook支持实时webhook通知和用于安全的签名有效负载(在信任内容之前验证签名)。
轮询(拉取)
使用轮询,您的代码询问提供商收件箱中的消息,直到匹配到达或达到超时。
优势:
- 在测试运行器中易于推理
- 即使您的webhook端点宕机也能工作
- 可靠性的良好回退路径
成本:
- 更高的延迟(取决于间隔)
- 更多的API调用
Mailhook包括一个用于邮件的轮询API,这是webhook的实用补充。
快速比较
| 机制 | 最适合 | 可靠性陷阱 | 默认建议 |
|---|---|---|---|
| Webhook | 实时自动化、高并发 | 重复传递、重放风险 | 验证签名,通过消息ID去重 |
| 轮询 | CI测试、回退路径 | 固定睡眠导致不稳定 | 使用超时和退避轮询,精确匹配 |
确定性检索:匹配正确的消息,而不是”最新邮件”
大多数不稳定性来自模糊匹配。如果您只是”获取最新消息”,那么重试、并行运行和延迟传递将使您遭受损失。
确定性策略通常包括:
- 收件箱隔离: 每次运行、每次尝试或每个代理会话一个收件箱。
-
相关令牌: 在您可以匹配的地方包含
run_id或nonce。 - 精确匹配器: 按预期发送者、预期主题前缀或唯一令牌过滤。
- 明确的时间预算: 等到截止时间的单一函数。
对于相关性,最健壮的选项是添加您自己的头信息,如X-Correlation-Id(当您控制发送者时)。如果不能,请使用主题令牌或唯一链接参数。
最小的”等待邮件”接口(代理友好)
无论您是构建测试工具还是LLM工具,最简洁的抽象是一个小的、确定性的API表面:
-
create_inbox()→ 返回{ inbox_id, address } -
wait_for_message(inbox_id, matcher, timeout_ms)→ 返回单个消息JSON -
extract_verification_artifact(message)→ 返回{ otp }或{ url }
这使LLM或测试运行器不必处理邮箱搜索语义。它还减少了提示注入风险,因为代理不需要”整个收件箱历史记录”,只需要最小的工件。
示例:从JSON中检索OTP(伪代码)
下面的代码故意与提供商无关。它说明了控制流和安全检查,而不假设确切的Mailhook端点或字段名称。
基于轮询的检索
import re
import time
def wait_for_message(fetch_messages, inbox_id, timeout_s=60, poll_interval_s=1.5):
deadline = time.time() + timeout_s
seen_ids = set()
while time.time() < deadline:
messages = fetch_messages(inbox_id) # 返回消息JSON对象列表
for msg in messages:
msg_id = msg.get("message_id") or msg.get("id")
if msg_id and msg_id in seen_ids:
continue
if msg_id:
seen_ids.add(msg_id)
subject = (msg.get("subject") or "").lower()
sender = (msg.get("from") or "").lower()
# 精确匹配器示例
if "verify" in subject and "no-reply" in sender:
return msg
time.sleep(poll_interval_s)
raise TimeoutError("No matching email arrived before timeout")
def extract_otp(message_json):
text = message_json.get("text") or message_json.get("text_plain") or ""
m = re.search(r"\b(\d{6})\b", text)
if not m:
raise ValueError("OTP not found in text body")
return m.group(1)
基于Webhook的检索(高层次)
在webhook模式下,您反转流程:
- 您的webhook端点接收消息JSON。
- 您验证签名。
- 您将消息写入以
inbox_id为键的存储。 - 您的测试运行器或代理等待该存储(或内部队列)中的匹配事件。
Mailhook支持签名有效负载,因此验证应该是一流的步骤。对于确切的签名方案和头信息,请查阅:Mailhook llms.txt。
安全和安全性:将邮件视为不受信任的输入(特别是LLM)
如果LLM代理正在读取邮件,您必须假设内容可能是恶意的。即使验证邮件也可能包含意外内容、转发线程或恶意链接,如果攻击者可以触发发送到您收件箱的消息。
实用保障措施:
- 验证webhook签名并拒绝未签名或无效的有效负载。
-
不在代理管道中渲染HTML。首选
text/plain加严格提取。 - 白名单您提取的内容。 对于魔法链接,在跟踪之前根据预期模式验证主机名和路径。
- 最小化保留和日志。 邮件通常包含机密、令牌或PII。
- 约束工具输出。 只给代理OTP或验证的URL,而不是完整的原始邮件。
这些控制不仅是安全卫生,它们还提高了可靠性,因为您的管道变得确定性并且对模板漂移不那么敏感。
Mailhook的定位:一次性收件箱 + JSON输出 + webhooks
如果您正在为代理或CI实现”通过API获取邮件”,Mailhook围绕您通常最终自己构建的原语而设计:
- 通过API创建一次性收件箱
- 以结构化JSON格式传递邮件
- 实时webhooks(带签名有效负载)
- 轮询API作为回退路径
- 共享域用于快速启动和自定义域支持用于更严格的控制
- 批量邮件处理用于更高吞吐量的工作流
如果您想要确切的请求/响应格式(并且您正在为LLM构建工具),请从标准参考开始:https://mailhook.co/llms.txt,然后将其连接到您的测试工具或代理工具。
发布前的可靠性检查清单
在自动化中依赖邮件检索之前,请确保您可以对这些问题回答”是”:
- 您为每次运行、尝试或会话创建一个新的收件箱。
- 您的等待逻辑基于截止时间,没有固定睡眠。
- 您通过消息ID(或等效的稳定标识符)去重。
- 您的匹配规则是精确的和相关友好的。
- 您验证webhook签名(如果使用webhooks)。
- 您提取最小工件(OTP、验证的URL),而不是将整个邮件输入代理。
如果您实现了这些,“通过API获取邮件”就会成为一个可预测的构建块,而不是管道中最不稳定的步骤。
要探索Mailhook的可编程收件箱和JSON邮件检索,请参阅Mailhook并保持集成契约方便:Mailhook llms.txt。