PHPMailer & Gmail conversation view - php

I'm using PHPMailer to send emails to support when our server is pinged with updates (usually related to payments).
I'm trying to get related emails to display as a Gmail conversation to make it easier to support staff to follow previous updates/replies. I had originally assumed that it was based on subject, but that doesn't seem to make a difference.
My mailer 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->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}" );
If I get 2 emails from the same user relating to the same payment (so the same subject), what I want it to come in as:
+-----------------------------------------------------------------------------+
| Support (2) | [Payment] Player foo (123456789) - Payment ID 123456789 |
+-----------------------------------------------------------------------------+
What it's actually coming in as:
+-----------------------------------------------------------------------------+
| Support | [Payment] Player foo (123456789) - Payment ID 123456789 |
+-----------------------------------------------------------------------------+
| Support | [Payment] Player foo (123456789) - Payment ID 123456789 |
+-----------------------------------------------------------------------------+
Am I missing something simple?

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 to foo#domain.com = no threading
foo#domain.com sending to bar#domain.com = threading
foo#domain.com sending to foo#domain.com and bar#domain.com = threading on both
foo#domain.com sending to foo#domain.com with re: pre-pended to the subject = no threading
foo#domain.com sending to foo#domain.com with header In-Reply-To set to foo#domain.com = no threading
foo#domain.com sending to foo#domain.com with header In-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.

Check out the accepted answer here:
https://webapps.stackexchange.com/questions/965/how-does-gmail-decide-to-thread-email-messages
The author also has more information in a blog post. It's 3 years old, but hopefully the information still holds.

Well, this doesn't really have anything to do with PHP. This has to do with the way Gmail nests emails together in a "conversation"
You might want to have a look at questions like https://webapps.stackexchange.com/questions/16651/gmail-not-grouping-messages-with-the-same-subject-from-google-groups

Related

phpmailer recipients failed [duplicate]

So i just received this error when trying to send an mail using PHPmailer from my site.
SMTP Error: The following recipients failed: XXXX
I tried to set $mail->SMTPAuth = true; to false but no result. And i tried to change the password for the mail account and update that in the sendmailfile.php but still the same.
It worked as intended two days ago, now i don't know why this is happening. Since there ain't any error code either i don't really know where to begin and since it did work..
Anyone who might know?
$mail = new PHPMailer();
$mail->CharSet = 'UTF-8';
$mail->ContentType = 'text/html';
$mail->IsSMTP();
$mail->Host = "HOST.COM";
$mail->SMTPAuth = true;
$mail->Username = "MAIL_TO_SEND_FROM";
$mail->Password = "PASSWORD";
$mail->From = "MAIL_TO_SEND_FROM";
$mail->FromName = "NAME";
$mail->AddAddress($safeMail);
$mail->AddReplyTo("no-reply#example.COM", "No-reply");
$mail->WordWrap = 50;
$mail->IsHTML(true);
$sub = "SUBJECT";
mail->Subject = ($sub);
I've encountered the same problem. Managed too fix it when i commented the next row:
$mail->isSMTP();
Noticed you already found an answer, however maybe this will fix the problem for other people.
This does prevent using your external SMTP server as RozzA stated in the comments.
Maybe your class.phpmailer.php file is corrupt. Download the latest version from :
https://github.com/PHPMailer/PHPMailer
$mail->SMTPDebug = 1; // enables SMTP debug information (for testing)
// 1 = errors and messages
// 2 = messages only
It is a restriction from your SMTP server.
Sending e-mail messages is a vital part of the ever-growing Internet business. Sometimes, a large number of e-mails are required to be sent daily, even hourly. With this comes also the ever-increasing problem with the e-mail spam, and the countless number of junk messages users receive constantly.
The most common restrictions are:
150 e-mails per hour;
1500 e-mails per 24 hours;
50 recipients per message, where each recipient is counted as a separately sent e-mail message (e.g. if you have 50 recipients in a single message, this willcount as 50 sent messages);
One solution is to use a mailing list, then the restriction is 1500 e-mails for 24 hours. There's no restriction for the amount of emails sent per hour, i.e. you can send an email to a mailing list with up to 1500 recipients without a problem.
If you reach the hourly/daily limit you will get this error when trying to send further e-mails:
550 - Stop, you are sending too fast!
You will be able to send e-mails again, once the hour/day has passed.
Things you should know in order to avoid exceeding your limit:
The above e-mail restrictions are valid for the entire hosting account, and not for a single mailbox. This means, that if one of your mailboxes exceeds the allowed limit, you will not be able to send messages from any of your other e-mail accounts.
If, at any point you receive the afore-mentioned error message, it is highly recommended to stop all attempts to send messages from your mailboxes. If you continue trying, your messages will be left in a mail queue, which will have to clear first, before the server timer can reset and allow you to send e-mails again.
try inlcuding this
$mail->SMTPDebug = 1;
Just try to set SMTPAuth to false.
there is a slightly less probable problem.maybe this condition is caused by protection placed by your ISP.and you said it worked well two days ago.maybe that is the problem.try contacting your ISP.
or maybe its a problem with the recipients/senders email adresses
Here is some additional info about SMTP Auth
PLAIN (Uses Base64 encoding.)
LOGIN (Uses Base64 encoding.)
e.t.c - you can watch here http://en.wikipedia.org/wiki/SMTP_Authentication
For me solution was to set SMTPAuth to true for PHPMailer class
Please note in your lines i.e....
$mail->Username = "MAIL_TO_SEND_FROM";
$mail->Password = "PASSWORD";
$mail->From = "MAIL_TO_SEND_FROM";
Here at Line 1 and 3 you have to use same email address (You can't use different email address), this will work sure, I hope u r using different email address, (Email address must be same as username/password matching).
for Skip sending emails to invalid adresses; use try ... catch
$mail=new PHPMailer(true);
try {
$mail->CharSet = 'utf-8';
$mail->isSMTP();
$mail->isHTML(true);
$mail->Host = 'smtp.yourhost.com';
$mail->Port = 25;
$mail->SMTPAuth = false;
$mail->Username = 'xxxx';
$mail->Password = 'xxxx';
$mail->SMTPSecure = 'tls';
$mail->SMTPDebug = 0;
$mail->MailerDebug = false;
$mail->setFrom($absender, $name);
$mail->addAddress($to);
$mail->Subject = $subject;
$mail->Body = $message_other_player;
}
$mail->send();
// echo 'Message has been sent';
} catch (Exception $e) {
// echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}
PHPMailer - Skip sending emails to invalid adresses

PHPMailer sets the From same as the smtp username

I am using PHPMailer library to send SMTP email for booking enquiry. (Note: The same problem I was facing in PHP Pear Mail library as well).
I set the email from as below
$mail = new PHPMailer;
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'smtp.gmail.com'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true;
$mail->Username = 'gmail.owner#gmail.com'; // SMTP username
$mail->Port = 465; // TCP port to connect to
$mail->isHTML(true);
$mail->Password = 'xxxx';
$mail->setFrom(mark.antony#example.com, Mark Antony);
$mail->replyTo(mark.antony#example.com, Mark Antony);
$mail->addAddress(gmail.owner#gmail.com, Gmail Owner);
$mail->Subject = $whatever subject;
$mail->Body = $whatever html;
The problem is after sending email in the received mailbox I see the From: is the same as To: (Or same as the gmail/smtp username).
I have fixed the problem on reply to by setting replyTo value.
Is there anyway I can fix this? Or is that how it suppose to be?
Google does not allow you to set arbitrary from addresses, because doing so is usually forgery. If you try to, gmail will ignore it and substitute your Username address, which is what you're seeing.
There is one exception to this: you can set up additional aliases in your gmail settings (which you need to verify), and once you've done that you can use those addresses as from addresses.
If you're using this for a contact form (as it sounds like you are), setting to and from to your own address, and the submitter as a reply-to is the correct way to go, as the PHPMailer contact form example demonstrates.

DKIM error when sending mail with GSuite using PHP Mailer

I am hosted at A2 hosting, but I am using GSuite to handle all my mail.
When I send test message to mail-tester.com from Gmail I get an awesome rating.
However when I sent a message using my PHP script:
$mail = new PHPMailer(true);
ob_start();
//Server settings
$mail->SMTPDebug = SMTP::DEBUG_SERVER; // Enable verbose debug output
$mail->Host = 'smtp.gmail.com'; // Set the SMTP server to send through
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = $pickuploc . '#xxxx.com'; // SMTP username
$mail->Password = 'xxx';
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` also accepted
$mail->Port = 587; // TCP port to connect to
//Recipients
$mail->setFrom($pickuploc . '#xxx.com', 'xxx xxxx');
$mail->addAddress($email, $fname . " " . $lname); // Add a recipient
$mail->addBCC($pickuploc . '#xxx.com');
// Content
$mail->isHTML(true); // Set email format to HTML
include 'email-confirmed.html';
$mail->Subject = 'Your Reservation Has Been Confirmed!';
$mail->Body = ob_get_clean();
$mail->AltBody = 'Your reservation has been confirmed.';
$mail->send();
I get an error from mail-tester.com that reads my DKIM is not valid.
I think this is because I am sending form a foreign server (not Google) and my MX records point to Google, but I really need these emails to get though, how should I work this problem?
Is there a way to configure this in PHP Mailer? Thanks.
The reason it's complaining is because you're not signing with DKIM at all!
You can do DKIM signing with PHPMailer, but there's a certain amount of setup required. PHPMailer provides some code to help you do this. Make sure you're using PHPMailer 6.1.1 or later; older versions have bugs affecting DKIM signing.
First of all you need to create your DKIM keys and put them in your DNS.
Now you need to alter your script to sign messages using your private key, as shown in this example; the parts you need to add are:
//This should be the same as the domain of your From address
$mail->DKIM_domain = 'example.com';
//See the DKIM_gen_keys.phps script for making a key pair -
//here we assume you've already done that.
//Path to your private key:
$mail->DKIM_private = 'dkim_private.pem';
//Set this to your own selector
$mail->DKIM_selector = 'phpmailer';
//Put your private key's passphrase in here if it has one
$mail->DKIM_passphrase = '';
//The identity you're signing as - usually your From address
$mail->DKIM_identity = $mail->From;
//Suppress listing signed header fields in signature, defaults to true for debugging purpose
$mail->DKIM_copyHeaderFields = false;
//Optionally you can add extra headers for signing to meet special requirements
$mail->DKIM_extraHeaders = ['List-Unsubscribe', 'List-Help'];

PHPMailer: Dynamic gmail forwarding

I do not know if what I want to do is possible (but finding out that it isn't would be useful in itself).
I cannot use my company's gmail account "real.business#gmail.com" directly with PHPMailer. I can, however, use an intermediary gmail account "fake.12345.account#gmail.com" which can have "less secure apps" enabled, which permits SMTP verification.
However I do not want to have the emails be sent from this fake.12345.account#gmail.com account (wouldn't look particularly professional) - but rather the company's gmail account.
I can send the emails from the intermediary account to real.business#gmail.com; either through the editing of the PHPMailer parameters, or by automatically forwarding emails from fake.12345.account#gmail.com to the company account.
The problem lies in how real.business#gmail.com can then successfully email the email (or at least appear to be the sender), as originally intended.
The code so far
$Mail = new PHPMailer();
$Mail->IsSMTP(); // Use SMTP
$Mail->Host = "smtp.gmail.com"; // Sets SMTP server for gmail
$Mail->SMTPDebug = 0; // 2 to enable SMTP debug information
$Mail->SMTPAuth = TRUE; // enable SMTP authentication
$Mail->SMTPSecure = "tls"; //Secure conection
$Mail->Port = 587; // set the SMTP port to gmail's port
$Mail->Username = 'fake.12345.account#gmail.com'; // gmail account username
$Mail->Password = 'a_password'; // gmail account password
$Mail->Priority = 1; // Highest priority - Email priority (1 = High, 3 = Normal, 5 = low)
$Mail->CharSet = 'UTF-8';
$Mail->Encoding = '8bit';
$Mail->Subject = 'Mail test';
$Mail->ContentType = 'text/html; charset=utf-8\r\n';
$Mail->From = 'testing.num.101#gmail.com'; //Your email adress (Gmail overwrites it anyway)
$Mail->FromName = 'Testing Again';
$Mail->WordWrap = 900; // RFC 2822 Compliant for Max 998 characters per line
$Mail->addAddress($personEmail); // To: the PERSON WE WANT TO EMAIL
$Mail->isHTML( TRUE );
$Mail->Body = ' Good news '.$personName.'! The email sent correctly!';
$Mail->AltBody = 'This is a test mail';
$Mail->Send();
$Mail->SmtpClose();
if(!$Mail->send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $Mail->ErrorInfo;
exit;
}
So the issue is: not having the email sent to $personEmail from fake.12345.account#gmail.com (that's trivial) but rather how to send the email from fake.12345.account#gmail.com to real.business#gmail.com such that real.business#gmail.com forwards the message to $personEmail
What you're describing is really relaying, which is usually configured in the mail server config (not the messages), but you don't have access to anything like that in gmail.
You can set allowed aliases in gmail, but I would guess that these are not allowed to overlap with existing gmail account names as that would be a major security hole. Why not enable "less secure apps" on the main account? It's not as if it is actually any less secure - if anything it's better, because the setup to use OAuth2 is so deeply complex and unpleasant...
That said, rather than trying to do all this forgery, you may be interested in this PR and associated docs. It's fairly likely the xoauth branch will get merged into master and released without any further changes as PHPMailer 5.2.11, and it would very helpful if you could give it a try.
PHPMailer is made for sending.
What you want to do is forward an email. This implies receiving the email and then sending it through.
What you need is some kind of IMAP client in php, that will allow you to read the emails on fake.12345.account#gmail.com (and maybe real.business#gmail.com). Then save their body and title and pass it to PHPMailer. You can then use PHPMailer to send the emails with real.business#gmail.com.

SMTP Error: The following recipients failed:XXXX

So i just received this error when trying to send an mail using PHPmailer from my site.
SMTP Error: The following recipients failed: XXXX
I tried to set $mail->SMTPAuth = true; to false but no result. And i tried to change the password for the mail account and update that in the sendmailfile.php but still the same.
It worked as intended two days ago, now i don't know why this is happening. Since there ain't any error code either i don't really know where to begin and since it did work..
Anyone who might know?
$mail = new PHPMailer();
$mail->CharSet = 'UTF-8';
$mail->ContentType = 'text/html';
$mail->IsSMTP();
$mail->Host = "HOST.COM";
$mail->SMTPAuth = true;
$mail->Username = "MAIL_TO_SEND_FROM";
$mail->Password = "PASSWORD";
$mail->From = "MAIL_TO_SEND_FROM";
$mail->FromName = "NAME";
$mail->AddAddress($safeMail);
$mail->AddReplyTo("no-reply#example.COM", "No-reply");
$mail->WordWrap = 50;
$mail->IsHTML(true);
$sub = "SUBJECT";
mail->Subject = ($sub);
I've encountered the same problem. Managed too fix it when i commented the next row:
$mail->isSMTP();
Noticed you already found an answer, however maybe this will fix the problem for other people.
This does prevent using your external SMTP server as RozzA stated in the comments.
Maybe your class.phpmailer.php file is corrupt. Download the latest version from :
https://github.com/PHPMailer/PHPMailer
$mail->SMTPDebug = 1; // enables SMTP debug information (for testing)
// 1 = errors and messages
// 2 = messages only
It is a restriction from your SMTP server.
Sending e-mail messages is a vital part of the ever-growing Internet business. Sometimes, a large number of e-mails are required to be sent daily, even hourly. With this comes also the ever-increasing problem with the e-mail spam, and the countless number of junk messages users receive constantly.
The most common restrictions are:
150 e-mails per hour;
1500 e-mails per 24 hours;
50 recipients per message, where each recipient is counted as a separately sent e-mail message (e.g. if you have 50 recipients in a single message, this willcount as 50 sent messages);
One solution is to use a mailing list, then the restriction is 1500 e-mails for 24 hours. There's no restriction for the amount of emails sent per hour, i.e. you can send an email to a mailing list with up to 1500 recipients without a problem.
If you reach the hourly/daily limit you will get this error when trying to send further e-mails:
550 - Stop, you are sending too fast!
You will be able to send e-mails again, once the hour/day has passed.
Things you should know in order to avoid exceeding your limit:
The above e-mail restrictions are valid for the entire hosting account, and not for a single mailbox. This means, that if one of your mailboxes exceeds the allowed limit, you will not be able to send messages from any of your other e-mail accounts.
If, at any point you receive the afore-mentioned error message, it is highly recommended to stop all attempts to send messages from your mailboxes. If you continue trying, your messages will be left in a mail queue, which will have to clear first, before the server timer can reset and allow you to send e-mails again.
try inlcuding this
$mail->SMTPDebug = 1;
Just try to set SMTPAuth to false.
there is a slightly less probable problem.maybe this condition is caused by protection placed by your ISP.and you said it worked well two days ago.maybe that is the problem.try contacting your ISP.
or maybe its a problem with the recipients/senders email adresses
Here is some additional info about SMTP Auth
PLAIN (Uses Base64 encoding.)
LOGIN (Uses Base64 encoding.)
e.t.c - you can watch here http://en.wikipedia.org/wiki/SMTP_Authentication
For me solution was to set SMTPAuth to true for PHPMailer class
Please note in your lines i.e....
$mail->Username = "MAIL_TO_SEND_FROM";
$mail->Password = "PASSWORD";
$mail->From = "MAIL_TO_SEND_FROM";
Here at Line 1 and 3 you have to use same email address (You can't use different email address), this will work sure, I hope u r using different email address, (Email address must be same as username/password matching).
for Skip sending emails to invalid adresses; use try ... catch
$mail=new PHPMailer(true);
try {
$mail->CharSet = 'utf-8';
$mail->isSMTP();
$mail->isHTML(true);
$mail->Host = 'smtp.yourhost.com';
$mail->Port = 25;
$mail->SMTPAuth = false;
$mail->Username = 'xxxx';
$mail->Password = 'xxxx';
$mail->SMTPSecure = 'tls';
$mail->SMTPDebug = 0;
$mail->MailerDebug = false;
$mail->setFrom($absender, $name);
$mail->addAddress($to);
$mail->Subject = $subject;
$mail->Body = $message_other_player;
}
$mail->send();
// echo 'Message has been sent';
} catch (Exception $e) {
// echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}
PHPMailer - Skip sending emails to invalid adresses

Categories