【问题标题】:PHPMailer & Gmail conversation viewPHPMailer 和 Gmail 对话视图
【发布时间】:2014-03-25 15:55:50
【问题描述】:

当我们的服务器收到更新(通常与付款有关)时,我正在使用 PHPMailer 发送电子邮件以支持支持。

我正在尝试将相关电子邮件显示为 Gmail 对话,以便支持人员更轻松地跟踪以前的更新/回复。我原本以为它是基于主题的,但这似乎并没有什么不同。

我的邮件代码:

$mail               = new PHPMailer;                        // create a new instance
$mail->isSMTP();                                            // set that we're using stmp
$mail->CharSet      = 'UTF-8';                              // make sure it's utf-8 encoded
$mail->Host         = 'smtp.gmail.com';                     // the hostname of the mail server
$mail->Port         = 587;                                  // set the smtp port number (587 for authenticated TLS)
$mail->SMTPSecure   = 'tls';                                // set the encryption to use, ssl (deprecated) or tls
$mail->SMTPAuth     = true;                                 // should we use smtp authentication?
$mail->Username     = MY_EMAIL_LOGIN;                       // the user name for the smtp authentication
$mail->Password     = MY_EMAIL_PASSWORD;                    // the password for smtp authentication
$mail->wordWrap     = 70;                                   // make sure we've no lines longer than 70 chars
$mail->Subject      = "[Payment] - Player {$payment->user->name} ({$payment->user->id}) - Payment ID {$payment->id}";
$mail->Body         = $htmlBody;                            // our html body
$mail->AltBody      = $plainBody;                           // our fallback, plain-text body
$mail->setFrom( SUPPORT_EMAIL, 'Support' );                 // who this is from
$mail->addReplyTo( SUPPORT_EMAIL, 'Support' );              // who we can reply to
$mail->addAddress( SUPPORT_EMAIL );                         // who we're sending it to
$mail->isHTML( true );                                      // is this a html formatted email?
if( !$mail->send() )
    error_log( "Can't send an email to support about payment {$payment->id} for user {$payment->user->id}" );

如果我收到来自同一用户的 2 封与同一付款相关的电子邮件(因此主题相同),我希望它以如下形式出现:

+-----------------------------------------------------------------------------+
| Support (2)       | [Payment] Player foo (123456789) - Payment ID 123456789 |
+-----------------------------------------------------------------------------+

实际上是这样的:

+-----------------------------------------------------------------------------+
| Support           | [Payment] Player foo (123456789) - Payment ID 123456789 |
+-----------------------------------------------------------------------------+
| Support           | [Payment] Player foo (123456789) - Payment ID 123456789 |
+-----------------------------------------------------------------------------+

我错过了一些简单的东西吗?

【问题讨论】:

    标签: php email phpmailer


    【解决方案1】:

    对于任何寻找有效方法的人:点击@ErikNedwidek 留下的链接将引导您访问此博客文章:http://www.sensefulsolutions.com/2010/08/how-does-email-threading-work-in-gmail.html

    指定了两条规则:

    • 主题必须相似。
    • 发件人必须是线程的一部分,或者必须使用 in-reply-to。

    第一个被覆盖,因为主题是相同的,第二个的第一部分应该被覆盖,因为发送者和接收者是一样的。

    还有这部分:

    需要注意的一件有趣的事情是,如果您从 Gmail 发送电子邮件,它们也会被串接起来。规则与您收到它们时的规则完全相同,除了一个小细节。如果您两次发送相同的确切消息而没有主题前缀(例如主题是测试而不是重新:测试),它确实会在接收端线程化,但不会在发送端线程化。相反,如果它确实包含前缀(例如 re:test),它将在两种情况下都被线程化。

    我认为它没有被线程化,因为发送者和接收者地址相同。将接收者地址更改为另一个测试地址意味着消息在接收时被正确线程化。保持发送者和接收者地址相同,但添加另一个接收者地址也意味着它们得到了正确的线程化。但是,只有一个与发送者地址匹配的接收者地址是行不通的。

    我尝试在主题的开头添加一个“re:”,但这没有任何区别。然而,起作用的是使用以下方法添加“In-Reply-To”标头:

    $mail->addCustomHeader( 'In-Reply-To', '<' . SUPPORT_EMAIL . '>' );
    

    请注意&lt;&gt; 很重要,因为没有它似乎会被忽略。

    总结一下:

    • foo@domain.com 发送到 foo@domain.com = 没有线程
    • foo@domain.com 发送到bar@domain.com = 线程
    • foo@domain.com 发送到 foo@domain.combar@domain.com = 两个线程上的线程
    • foo@domain.com 发送到 foo@domain.com 并在主题前添加 re: = 无线程
    • foo@domain.com 发送到 foo@domain.com,标头 In-Reply-To 设置为 foo@domain.com = 无线程
    • foo@domain.com 发送到 foo@domain.com,标头 In-Reply-To 设置为 &lt;foo@domain.com&gt; = 线程

    完整的 PHPMailer 代码:

    $mail               = new PHPMailer;                                // create a new instance
    $mail->isSMTP();                                                    // set that we're using stmp
    $mail->CharSet      = 'UTF-8';                                      // make sure it's utf-8 encoded
    $mail->Host         = 'smtp.gmail.com';                             // the hostname of the mail server
    $mail->Port         = 587;                                          // set the smtp port number (587 for authenticated TLS)
    $mail->SMTPSecure   = 'tls';                                        // set the encryption to use, ssl (deprecated) or tls
    $mail->SMTPAuth     = true;                                         // should we use smtp authentication?
    $mail->Username     = MY_EMAIL_LOGIN;                               // the user name for the smtp authentication
    $mail->Password     = MY_EMAIL_PASSWORD;                            // the password for smtp authentication
    $mail->wordWrap     = 70;                                           // make sure we've no lines longer than 70 chars
    $mail->Subject      = "[Payment] Player {$payment->user->name} ({$payment->user->id}) - Payment ID {$payment->id}";
    $mail->Body         = $htmlBody;                                    // our html body
    $mail->AltBody      = $plainBody;                                   // our fallback, plain-text body
    $mail->setFrom( SUPPORT_EMAIL, 'Support' );                         // who this is from
    $mail->addReplyTo( SUPPORT_EMAIL, 'Support' );                      // who we can reply to
    $mail->addAddress( SUPPORT_EMAIL );                                 // who we're sending it to
    $mail->addCustomHeader( 'In-Reply-To', '<' . SUPPORT_EMAIL . '>' ); // so we get threading on gmail (needed as to and from are the same address)
    $mail->isHTML( true );                                              // is this a html formatted email?
    if( !$mail->send() )
        error_log( "[paymentsRealtimeUpdates] Can't send an email to support about payment {$payment->id} for user {$payment->user->id}" );
    

    不相关的小点 - 您为 setFrom 设置的任何地址似乎都被忽略了 - Gmail 将采用 MY_EMAIL_LOGIN 登录后面的任何地址。

    【讨论】:

    • 哎呀,是的。这让我发疯(在我正在编写的 C# 应用程序中)。只需设置“In-Reply-To”标题就可以了。
    • 我喜欢你记录一切的方式。你是开发者:-)
    【解决方案2】:

    在此处查看接受的答案:

    https://webapps.stackexchange.com/questions/965/how-does-gmail-decide-to-thread-email-messages

    作者还在一篇博文中提供了更多信息。它已经 3 年了,但希望信息仍然有效。

    【讨论】:

      【解决方案3】:

      嗯,这与 PHP 没有任何关系。这与 Gmail 在“对话”中将电子邮件嵌套在一起的方式有关

      你可能想看看像https://webapps.stackexchange.com/questions/16651/gmail-not-grouping-messages-with-the-same-subject-from-google-groups这样的问题

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-02-11
        • 2021-03-22
        • 2012-05-20
        • 2017-11-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-18
        相关资源
        最近更新 更多