listmonk 如何配置 POP3 弹跳邮箱:Return-Path 自定义头与软硬弹跳分类规则
【免费下载链接】listmonkHigh performance, self-hosted, newsletter and mailing list manager with a modern dashboard. Single binary app.项目地址: https://gitcode.com/GitHub_Trending/li/listmonk
在 listmonk 中发送 campaign 后,退信(bounce)并不会自动进入系统——你需要配置一个弹跳处理流程。本文的任务是:让 listmonk 通过 POP3 定期扫描一个弹跳邮箱,把退信记录到系统里,并按 soft/hard 分类触发你预设的动作(如将订阅者加入 blocklist)。适用的前提是:邮件通过 SMTP 发出,且你能拿到一个可以接收退信的 POP3 邮箱(可以是 campaign 发件地址背后的邮箱,也可以是专门的弹跳邮箱)。
前提:启用弹跳处理
在Settings -> Bounces中启用 bounce processing。只有启用后,POP3 弹跳扫描和弹跳相关 API 才会生效(见 Bounce processing 文档)。
同一设置页里,还要为 soft、hard、complaint 三类事件分别配置触发策略:Bounce count(达到多少次后触发动作)与 Action(触发的动作)。官方文档在 SES 章节给出的示例配置是:
- Soft:Bounce count
2,ActionNone - Hard:Bounce count
1,ActionBlocklist - Complaint:Bounce count
1,ActionBlocklist
这个策略对经 POP3 邮箱记录进来的弹跳同样适用。
决定退信回到哪个邮箱:两种方式二选一
listmonk 文档给出了两条路径,核心区别在于弹跳邮箱是否为发件地址本身:
方式一:发件地址背后就有 POP3 邮箱。如果 campaign 的 "From" 地址(或 settings 中配置的发件地址)本身就是一个可以收信的邮箱,退信会自然回到它,直接用它做 POP3 弹跳邮箱即可。
方式二:配置专用弹跳邮箱,并用Return-Path自定义头指向它。如果你的发件地址无法收信(比如通过第三方 SMTP 服务发送),就在Settings -> SMTP -> Custom headers中把专用弹跳邮箱的地址加为Return-Path(envelope sender)头,格式如下:
[ {"Return-Path": "your-bounce-inbox@site.com"} ]把your-bounce-inbox@site.com替换为你的专用弹跳邮箱地址。
从源码可以确认这个头的生效机制:发送时,如果存在Return-Path头,listmonk 会把它写入 SMTP 信封的 Sender 字段,并从邮件正文头中删除(internal/messenger/email/email.go)。也就是说,邮件服务商的退信会按信封发件人(即你配置的Return-Path地址)投递,而收件人看到的邮件头里不会出现这个头。
另外,文档提示:部分邮件服务器会把退信投递到Reply-To地址,如果存在这种情况,也可以在 header 设置里一并添加。
在 Settings -> Bounces 中配置 POP3 邮箱
启用弹跳处理后,在 Bounces 设置页填写 POP3 邮箱的连接参数。设置项对应的字段定义在 internal/migrations/v2.0.0.go 的种子数据和 models/settings.go 中,包括:
| 字段 | 说明 |
|---|---|
host | POP3 服务器主机名 |
port | POP3 端口 |
auth_protocol | 认证协议;设为none时跳过认证,否则使用username/password登录 |
username/password | 邮箱登录凭据 |
return_path | 与该邮箱关联的 Return-Path 地址 |
tls_enabled/tls_skip_verify | 是否启用 TLS、是否跳过证书校验 |
scan_interval | 两次扫描之间的间隔,如15m |
官方迁移脚本中的默认示例配置可供参照(v2.0.0.go):
[{"enabled":false, "type": "pop", "host":"pop.yoursite.com","port":995,"auth_protocol":"userpass","username":"username","password":"password","return_path": "bounce@listmonk.yoursite.com","scan_interval":"15m","tls_enabled":true,"tls_skip_verify":false}]其中type目前只支持pop;设为其他值时弹跳管理器会返回unknown bounce mailbox type错误(internal/bounce/bounce.go)。
一个重要的运行行为:POP3 扫描器每轮会下载邮箱里的全部消息(单轮上限 1000 条),处理完成后删除服务器上的这些邮件(internal/bounce/mailbox/pop.go)。也就是说这个 POP3 邮箱应当只用于接收退信,不要混入人工邮件;每轮扫描结束后按scan_interval休眠再扫描(internal/bounce/bounce.go)。
软硬弹跳分类规则
每封退信都会经过classifyBounce函数分类,规则按以下优先级执行(internal/bounce/mailbox/pop.go):
- SMTP 状态码。在消息内容中匹配形如
5.x.x/4.x.x的状态码(可带Status:前缀):5.x.x→ hard bounce4.x.x→ soft bounce
- 硬弹跳关键词。匹配不到状态码时,检查消息正文是否包含硬弹跳特征词(大小写不敏感),包括:
NXDOMAIN、user unknown、address not found、mailbox not found、address ... reject、does not exist、invalid recipient、no such user、recipient ... invalid、undeliverable、permanent ... failure、permanent ... error、bad ... address、unknown ... user、account ... disabled、address ... disabled。命中任意一个即为 hard bounce。 - 默认 soft。以上规则都没命中时,退信按 soft bounce 处理。这与文档描述一致:listmonk 通过一系列启发式规则猜测 soft/hard,都不匹配时默认 soft。
分类结果中的匹配原因会写入弹跳记录的 meta 字段(如smtp_status=5.1.1或body_match=...),同时 meta 还会保存弹跳邮件的From、Subject、Message-Id、Delivered-To和Received头,便于事后排查。
弹跳要关联到具体的订阅者和 campaign,靠的是原始邮件中嵌入的自定义头X-Listmonk-Subscriber和X-Listmonk-Campaign(models/common.go)。扫描器优先从邮件头读取这两个值;如果邮件服务器在转发退信时剥离了头,会退化为对原始消息字节做正则提取(internal/bounce/mailbox/pop.go)。
验证:查看已记录的弹跳
配置完成后,发一封会退信的测试邮件(或向无效地址发送 campaign 预览),等待一个扫描周期后,用以下方式确认弹跳已被记录:
通过 JSON API 导出(bounces.md):
curl -u 'username:passsword' 'http://localhost:9000/api/bounces'-u后填 listmonk 的 API 用户名和密码,localhost:9000换成你的实例地址。
或者直接查询数据库:
SELECT bounces.created_at, bounces.subscriber_id, subscribers.uuid AS subscriber_uuid, subscribers.email AS email FROM bounces LEFT JOIN subscribers ON (subscribers.id = bounces.subscriber_id) ORDER BY bounces.created_at DESC LIMIT 1000;如果查询里能看到对应地址、分类类型符合上文规则,说明 POP3 扫描、分类和记录链路已正常工作;达到配置的 Bounce count 后,系统会执行你在 Bounces 设置中选择的 Action。
限制与替代路径
- POP3 邮箱扫描只支持
pop类型,没有 IMAP 选项。 - 如果你的邮件服务商支持 webhook(SES、Azure ACS、SendGrid、Postmark、Forward Email、Lettermint),可以改用
webhooks/service/*端点接收弹跳事件,配置方法见 bounces.md;这条路径与 POP3 邮箱是并列的替代方案,二选一即可,但两者都依赖先启用 bounce processing。
【免费下载链接】listmonkHigh performance, self-hosted, newsletter and mailing list manager with a modern dashboard. Single binary app.项目地址: https://gitcode.com/GitHub_Trending/li/listmonk
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考