For anybody looking for what worked: following the link left by @ErikNedwidek will lead you to this blog post: http://www.sensefulsolutions.com/2010/08/how-does-email-threading-work-in-gmail.html
Two rules are specified:
- The subject must be similar.
- The sender must be a part of the thread OR in-reply-to must be used.
The first one is covered, as the subjects are identical, and the first part of the second should be covered as the sender is the same as the receiver.
There was also this part:
One interesting thing to note is that if you send email messages from Gmail they will also be threaded. The rules are exactly the same as when you receive them, except for one minor detail. If you send the same exact message twice with no subject prefix (e.g. subject is test not re: test) it does get threaded on the receiving end, but not on sending end. Conversely, if it does contain a prefix (e.g. re: test) it will be threaded in both cases.
I figured it wasn't getting threaded because the sender and receiver addresses are the same. Changing the receiver address to another test address meant that messages were threaded properly when received. Keeping the sender and receiver address the same, but adding another receiver address also meant that they got threaded properly. Just having one receiver address that matches the sender address wouldn't work though.
I tried adding a 're:' to the start of the subject, but that didn't make any difference. What did work however, was adding the 'In-Reply-To' header using:
$mail->addCustomHeader( 'In-Reply-To', '<' . SUPPORT_EMAIL . '>' );
Note that the <
and >
are important, as without it seemed to be ignored.
So to summarise:
foo@domain.com
sending tofoo@domain.com
= no threadingfoo@domain.com
sending tobar@domain.com
= threadingfoo@domain.com
sending tofoo@domain.com
andbar@domain.com
= threading on bothfoo@domain.com
sending tofoo@domain.com
withre:
pre-pended to the subject = no threadingfoo@domain.com
sending tofoo@domain.com
with headerIn-Reply-To
set tofoo@domain.com
= no threadingfoo@domain.com
sending tofoo@domain.com
with headerIn-Reply-To
set to<foo@domain.com>
= threading
Full PHPMailer code:
$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}" );
Unrelated small point - whatever address you set for the setFrom
seemed to be ignored - Gmail would take whatever address is behind the MY_EMAIL_LOGIN
login.