news 2026/9/14 9:37:29

listmonk 如何配置 POP3 弹跳邮箱:Return-Path 自定义头与软硬弹跳分类规则

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
listmonk 如何配置 POP3 弹跳邮箱:Return-Path 自定义头与软硬弹跳分类规则

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 count2,ActionNone
  • Hard:Bounce count1,ActionBlocklist
  • Complaint:Bounce count1,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 中,包括:

字段说明
hostPOP3 服务器主机名
portPOP3 端口
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):

  1. SMTP 状态码。在消息内容中匹配形如5.x.x/4.x.x的状态码(可带Status:前缀):
    • 5.x.x→ hard bounce
    • 4.x.x→ soft bounce
  2. 硬弹跳关键词。匹配不到状态码时,检查消息正文是否包含硬弹跳特征词(大小写不敏感),包括:NXDOMAINuser unknownaddress not foundmailbox not foundaddress ... rejectdoes not existinvalid recipientno such userrecipient ... invalidundeliverablepermanent ... failurepermanent ... errorbad ... addressunknown ... useraccount ... disabledaddress ... disabled。命中任意一个即为 hard bounce。
  3. 默认 soft。以上规则都没命中时,退信按 soft bounce 处理。这与文档描述一致:listmonk 通过一系列启发式规则猜测 soft/hard,都不匹配时默认 soft。

分类结果中的匹配原因会写入弹跳记录的 meta 字段(如smtp_status=5.1.1body_match=...),同时 meta 还会保存弹跳邮件的FromSubjectMessage-IdDelivered-ToReceived头,便于事后排查。

弹跳要关联到具体的订阅者和 campaign,靠的是原始邮件中嵌入的自定义头X-Listmonk-SubscriberX-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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 9:34:06

基于JSP+SSM的大学生创业创新网站开发实践

1. 项目概述这个Java毕业设计项目选题"jspssm大学生创业创新网站"是一个典型的基于Java EE技术栈的Web应用开发实践。作为一名有多年Java开发经验的工程师,我认为这个选题非常适合计算机相关专业的毕业设计,因为它涵盖了从数据库设计到前端展示…

作者头像 李华
网站建设 2026/9/14 9:33:32

SpringBoot+Vue智能健康推荐系统开发实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 9:33:25

西门子PLC模拟量编程:揭秘27648的由来与工程值换算

1. 为什么每个西门子工程师都绕不开 27648做西门子 PLC 的同学应该都有过这种经历:第一次接触模拟量编程,翻开手册看到“单极性 0~27648”“双极性 -27648~27648”,第一反应基本都是——这数字也太奇葩了,为…

作者头像 李华
网站建设 2026/9/14 9:33:05

直播点赞爱心特效:Canvas对象池与性能优化实践

简介:html5与canvas结合实现的仿抖音直播爱心飘动点赞动画特效,是一份面向Web前端初学者的完整源码案例,重点展示如何用Canvas实时渲染动态图形,并还原直播场景中的点赞交互体验。压缩包共10个文件,以HTML页面、JavaSc…

作者头像 李华
网站建设 2026/9/14 9:32:54

STM32+UART HMI扫雷:嵌入式人机交互闭环实践

1. 这不是玩具,是嵌入式人机交互的完整闭环实践 “毕业设计|STM32UART HMI,玩扫雷游戏”——光看标题,很多人第一反应是:“又一个学生凑数项目?”但真正做过HMI类毕业设计的人都知道,这八个字背…

作者头像 李华