php发送的电子邮件中的Message-Id有啥问题

Posted

技术标签:

【中文标题】php发送的电子邮件中的Message-Id有啥问题【英文标题】:what's the issue with Message-Id in email sent by phpphp发送的电子邮件中的Message-Id有什么问题 【发布时间】:2013-01-07 04:14:59 【问题描述】:

我有可疑的 php 发送到 gmail 帐户的邮件的 message-id 标头:

Message-Id: <5100054f.a489440a.5d93.6a70SMTPIN_ADDED_MISSING@mx.google.com>

你能告诉它有这种奇怪的格式吗? SMTPIN_ADDED_MISSING 在这里是什么意思?我在互联网上看到的示例具有类似这样的格式,包含发送域,但由于某种原因我的消息 ID 不包含它:

38D1C1FD-3C35-4568-925C-FC46CAC0DE8A@sendinghost.com

我不认为我在 Zend_Mail 中设置了这个标题。是什么产生了这个标题?您是否发现此标头有任何问题?

【问题讨论】:

【参考方案1】:

发送电子邮件时,适当的出站电子邮件客户端应生成 Message-ID 标头。当邮件通过其电子邮件系统时,Google 会为您生成它,但大多数不会,并且大多数垃圾邮件过滤器会将这个丢失的标头视为邮件更有可能是垃圾邮件的指示。任何格式错误或缺失的标头都会添加到“垃圾邮件分数”中。

生成并不难,只需要每个消息都是唯一的:

$message-id = time() .'-' . md5($sender . $recipient) . '@' $_SERVER['SERVER_NAME'];

或者

$message-id = time() .'-' . md5($sender . $recipient) . '@yourdomain.com';

给予:

1358961017-677533f745f613447d06de25e7fa4d32@yourdomain.com

【讨论】:

您的意思是缺少 Message_Id 会增加发送垃圾邮件的机会吗? message_id可以包含发送邮件的smpt服务器的域名吗? smpt server 不会自动添加message_id,应该是应用程序添加的吧? 就像我说的,'任何格式错误或丢失的标题都会增加“垃圾邮件分数”'。 SMTP 服务器应该添加它,但你的显然不是。 是否可以配置 SMTP 服务器自动添加消息 ID 不在应用程序中发送?【参考方案2】:

如果丢失,Google SMTP 会生成它。此标头必须由第一个 SMTP 服务器设置。所以你不会生成它 - 谷歌会。它用于防止多次传递并将相关消息链接在一起。

不需要设置消息 id 标头,但对于大多数(但不是全部,仅配置)smtp 添加(可能会修复)此标头是一种好习惯。因此,为避免其他人生成此标头,您可以自己生成它。

【讨论】:

我应该从 php 设置它还是应该服务器 smpt 服务器添加它们? message_id 是否应该包含发送地址的服务器域,例如:8D1C1FD-3C35-4568-925C-FC46CAC0DE8A@sendinghost.com? 你的意思是如果发送的邮件中没有message id,received email会生成它并添加到邮件中? SMTP 服务器在它不存在时生成它。不需要从 PHP 生成。它包含@domain 部分。推荐jwz.org/doc/mid.html 如果我发送它的 SMTP 服务器生成它,为什么它设置谷歌域而不是发送它的 smtp 域。 是否可以配置 SMTP 服务器自动添加消息 ID 不在应用程序中发送?【参考方案3】:

这个对我有用(我还在标题中添加了一个“日期”行,因为这对我来说也是一个垃圾邮件问题)。基于this peace of code。

这是我的 PHP 数组方法(使用 Pear 的 Mail 和 Mime 库):

$headers = array(
   'From'       => $from,
   'Subject'    => $subject,
   'To'     => $to,
   'Cc'     => '',
   'Date'       => date('r'),
   'Message-ID' => sprintf("<%s.%s@%s>",
                                base_convert(microtime(), 10, 36),
                                base_convert(bin2hex(openssl_random_pseudo_bytes(8)), 16, 36),
                                'yourdomain.com')
                );

请注意,使用 $_SERVER['SERVER_NAME'] 而不是字面上的 'yourdomain.com' 在 php cli 中不起作用,正如 Oleg 在另一个答案中所注释的那样。

【讨论】:

【参考方案4】:

我使用相同的 MessageId 来跟踪交换的消息。

我使用以下方法修复 MessageId:

$mail->MessageID =sprintf('<%s@%s>', $myMessageID, 'myserver');

【讨论】:

【参考方案5】:

tl;dr; 发送电子邮件时不要使用端口 25,而是使用端口 587

当我使用端口 25 从自定义创建的 golang 电子邮件客户端发送出站电子邮件到我的本地后缀服务器时,我看到的目标电子邮件地址是 gmail 或 google gsuite 地址

Message ID  <5be55db9.1c69fb81.d0444.d894SMTPIN_ADDED_MISSING@mx.google.com>

从 gmail Show Original 中的目标电子邮件地址查看...但是,由于我在我的 golang 电子邮件客户端和本地 postfix 服务器中都使用完整的 TLS 证书,所以当我在出站中使用安全端口 587 替换使用端口 25 时电子邮件客户端(postfix 已经在使用 TLS 证书)然后我得到了正确的

Message ID  <20181109163255.F164D8E9588@mail.myexample.com>

注意 - 我在任何时候都没有定义电子邮件标头 message-id 实际上我正在使用的 golang 存储库没有定义该标头的 api 调用

【讨论】:

【参考方案6】:

您错过了“”括号。

【讨论】:

以上是关于php发送的电子邮件中的Message-Id有啥问题的主要内容,如果未能解决你的问题,请参考以下文章

使用 Mandrill 为批量电子邮件设置 Message-Id

在 Rails3 / ActionMailer 中设置 Message-ID 邮件头

用PHP发送轻松可靠的HTML电子邮件

是否可以捕获使用 SmtpClient 发送的电子邮件的“消息 ID”?

这个使用 Pear Mail 发送邮件的 PHP 脚本有啥问题?

在 Python 中使用 Gmail API 使用 message-id 搜索电子邮件