You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP场景下如何获取退信邮件对应的原始发件MessageID

绝大多数邮件服务提供商生成未送达报告(NDR/DSN)时不会自动填充References或In-Reply-To头,所以你从overview字段中拿不到对应值是正常现象,可通过以下两种方案解决问题:


方案1:解析退信内容提取原始Message-ID

标准投递状态通知属于multipart类型邮件,其中会完整携带原始邮件的头部信息,你需要获取完整邮件内容而非仅overview字段来提取:

  1. 先在循环中判断是否为退信:可通过发件人是否为MAILER-DAEMON、主题包含「未送达」「Delivery Status Notification」「Undelivered Mail Returned to Sender」等特征判断
  2. 使用imap_fetchstructure获取邮件结构,定位到包含原始邮件头的部分(通常是message/rfc822-headers类型,或者文本部分中引用的原始头信息)
  3. 从原始头中匹配Message-ID字段即可拿到你之前自定义的ID

参考代码片段:

foreach ($result as $overview) {
    $isNdr = str_contains(strtolower($overview->from), 'mailer-daemon') 
             || str_contains(strtolower($overview->subject), 'undeliver')
             || str_contains(strtolower($overview->subject), '退回');
    if (!$isNdr) {
        // 原有正常回复的处理逻辑
        continue;
    }
    $originalMsgId = '';
    // 获取邮件完整结构
    $structure = imap_fetchstructure($mbox, $overview->msgno);
    if (isset($structure->parts) && count($structure->parts)) {
        foreach ($structure->parts as $partNum => $part) {
            // 优先匹配单独存储的原始邮件头部部分
            if ($part->type == 5 && $part->subtype == 'RFC822-HEADERS') {
                $rawHeaders = imap_fetchbody($mbox, $overview->msgno, $partNum + 1);
                if (preg_match('/Message-ID:\s*<(.+?)>/i', $rawHeaders, $matches)) {
                    $originalMsgId = $matches[1];
                    break;
                }
            }
            // 无单独头部部分则从文本内容中匹配
            if ($part->type == 0 && $part->subtype == 'PLAIN' && empty($originalMsgId)) {
                $body = imap_fetchbody($mbox, $overview->msgno, $partNum + 1);
                if (preg_match('/Message-ID:\s*<(.+?)>/i', $body, $matches)) {
                    $originalMsgId = $matches[1];
                    break;
                }
            }
        }
    }
    // 拿到$originalMsgId后即可去数据库匹配对应邀请记录
}

方案2:通过可变退信地址匹配(稳定性更高)

你提到不能修改Reply-To地址,这个方案完全不涉及Reply-To的改动,只需要调整发件时的Return-Path(即退信接收地址):
发件时将Return-Path设置为bounce+{唯一标识}@你的域名.com,这里的唯一标识可以直接用你生成的MessageID做URL安全编码,也可以用数据库里对应邀请记录的主键ID。
退信时邮件会发送到这个带标识的地址,你只需要解析收件地址中+后面的部分,就能直接拿到对应记录的标识,无需解析复杂的NDR内容,兼容性远高于前者。

注意:需要你的邮件服务商支持「加号地址」(plus addressing)功能,目前绝大多数主流邮件服务都支持该特性。


内容的提问来源于stack exchange,提问作者lvor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 17:57:05