I have a simple PHP endpoint that takes a POST request and uses PHPMailer to send me an email. The whole thing works fine but I notice that in my email client (Gmail on web), the emails I receive from it seem to be grouped as part of the same thread/conversation.
Is there a param I can set in the email header to inform email clients that each message should be treated as its own separate conversation? In other words, don't chain the emails (as shown in the screenshot).
I assume this behavior can be achieved since you can effectively do this if you were sending separate emails to someone manually (versus replying to an email chain you already sent).
Here is how I send an email (simplified and redacted):
<?php
require '../utils/phpmailer/vendor/autoload.php';
$email = $_POST['email'];
$message = $_POST['message'];
$mailer = new PHPMailer;
$mailer->isSMTP();
$mailer->Host = 'smtp.mailgun.org';
$mailer->SMTPAuth = true;
$mailer->Username = getenv('MAILGUN_SMTP_USERNAME');
$mailer->Password = getenv('MAILGUN_SMTP_PASSWORD');
$mailer->SMTPSecure = 'tls';
$mailer->Port = 587;
$mailer->From = 'noreply#mydomain.com';
$mailer->addAddress('myemail#gmail.com', 'Me');
$mailer->isHTML(true);
$mailer->Subject = 'Message from Endpoint';
$mailer->Body = 'Received a message from '.$email.'. Message: '.$message;
if (!$mailer->send()) {
die('failed');
} else {
echo 'success';
}
?>
Screenshot from my email client showing messages being chained together as the same "conversation":
No, there is not.
There is a whole chunk of email RFCs relating to connecting messages together in threads: the Message-ID, In-Reply-To, and References headers. Unfortunately widespread incompetence and broken implementations have made a bit of a mess of them in practice, and so mail clients (such as gmail) sometimes resort to linking messages together by home-grown heuristics, e.g. if they are from the same sender, or happen have the same subject, even if those messages are completely unrelated in any sensible way.
What's worse, some have taken up ignoring correctly set headers, which doesn't help anyone.
Client-specific heuristics are by definition outside of the email spec, and are thus uncontrollable from the sender's point of view. Gmail is particularly poor at this, and randomly links together all kinds of unrelated messages.
While I'm here, this looks very suspicious:
require '../utils/phpmailer/vendor/autoload.php';
Your vendor folder should belong to your project, not any library used by it. Using an autoloader generated from PHPMailer's own composer.json (which is what this line looks like) is likely to include dev dependencies, which should not be present in production.
Related
I am working on Laravel and I am trying to send an email with PHPMailer and my mail server is Zoho.
Here is my Code:
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host = 'smtp.zoho.com';
$mail->SMTPAuth = true;
$mail->Username = 'ServerUserName';
$mail->Password = 'ServerUserPassword';
$mail->SMTPSecure = 'TLS';
$mail->Port = 587;
$mail->setFrom('itsupport#foo.net', 'Foo');
$mail->addAddress($email);
$mail->addReplyTo('noreply#foo.com', 'No-reply');
$mail->isHTML(true);
$mail->Subject = "Testing - " . $subject;
$mail->Body = $body;
if(!empty($attachment)) {
$mail->AddAttachment($attachment['abs_path'], $attachment['name']);
}
$mail->SMTPDebug = 2;
$mail->Debugoutput = function($str, $level) {echo "debug level $level; message: $str"; echo "<br>";};
if(!$mail->Send()) {
$error = 'Mail error: '.$mail->ErrorInfo;
echo "Error"."<br>"."================================="."<br>"."<br>";
dd($mail);
} else {
$error = 'Message sent!'.$mail->ErrorInfo;
echo "Success"."<br>"."================================="."<br>"."<br>";
dd($mail);
}
My Scenarios
1) When I am sending an email with my Valid and Real email it gives me
success status and in my mail server its shows me in Sent tab.
2) But when I am sending an email with Valid but Fake email it gives me also Success status and when I check my mail server It gives
me this mail.
3) And in both scenarios in my debugging code it gives me always this return:
What I want
I want when a mail server return undelivered or failed mail it should return me an error code e.g. (550, 552, 553 etc) + Error Message. I search a lot but not find anything.
Is there any possibility that server return me the error code also.
Note: I tried my phpmailer code in try catch. But when I use fake email it dos not goes to catch.
You're misunderstanding the structure of email. Email uses an asynchronous store-and-forward approach, which means that can be sent successfully, but fail later, before it reaches its destination. This is completely unlike HTTP which gives immediate responses.
You are submitting the message successfully to Zoho's mail server, but then that server is failing to deliver the message to its intended destination, so it gets sent back as a bounce to the envelope sender address (the address in the SMTP MAIL FROM command, set via the Sender property in PHPMailer).
To handle bounces in your code, you can configure your mail server to pipe the inbound message into a script attached to your bounce address, for example as described in this article.
Unfortunately that's not the end of the story. While you will then have programmatic access to the bounced message, actually figuring out why it bounced and who bounced it is often difficult, if not impossible in some cases. For example, Microsoft Exchange sometimes sends bounces that do not contain any means of identifying the address the original message was sent to! You can address that particular shortcoming by using VERP addressing, where every message has a unique bounce address, which you can do with PHPMailer.
Writing bounce handlers is generally a very unpleasant experience that I recommend avoiding if you can. There is a commercial bounce classification library by BoogieTools that works well, but there is still a large element of guesswork and heuristics involved.
I don't use PHP that often but when I do and I need to write a function to send E-Mails, I just used the mail() function. I have used it on a shared hosting service and I always received the E-Mails from a... well... not an account? A bot? It didn't even have an E-Mail address.
And that's what I want to achieve at this very moment - send an E-Mail to me without really connecting to a SMTP server or going through authentication. How can be that done with PHPMailer? Is it even possible in my case? And if you somehow got my question, how are such E-Mails even called; the ones that... aren't sent by... well... an E-Mail account?
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'PHPMailer-master\src\Exception.php';
require 'PHPMailer-master\src\PHPMailer.php';
require 'PHPMailer-master\src\SMTP.php';
$mail = new PHPMailer();
$mail->FromName = "A random name";
$mail->addAddress("myemail#gmail.com", "Recepient Name");
$mail->isHTML(true);
$mail->Subject = "Subject is here";
$mail->Body = "Hello, <br>test body ";
if(!$mail->Send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
} else {
echo "Message has been sent";
}
?>
This did make me laugh a bit...
No, emails can't just magically spring into existence, but there isn't necessarily a direct correlation between email user accounts and addresses.
When you send from a shared hosting account by calling mail(), the mail server knows the account you're sending from, and sometimes doesn't require authentication as a result. This for example is how GoDaddy operates. Unfortunately this approach is very prone to abuse because there is often little preventing you from flat-out lying about who you are. This is why such services are usually a) terrible and b) extremely unreliable for actually delivering messages.
If you don't specify a "from" address, the server will usually make one up from information it does have – typically your user account name, or the name of the user running the script (e.g. www-data), and the hostname of the server you're on, often something like randomnumber.hostingprovider.example.com. Look at the headers of messages you've sent before, and you'll probably see something like that.
Sometimes this address can be the same for all users on a given shared server, so your delivery reputation can depend on what others are sending, which could well be spam, phishing, malware, etc.
This vagueness is terrible for deliverability, so if you host your contact form on such a system, expect messages from it to end up in a spam folder.
If you use SMTP to send via a "proper" account you gain a lot more control and reliability, but unfortunately some hosting providers (GoDaddy again) block outbound SMTP and force you to use their mail servers. This is a way of saying that if you want to send email that will be delivered, use a decent hosting provider.
Once you get control over your sending, you can choose exactly what addresses messages are sent from, subject to authentication constraints including things like SPF, DKIM, and DMARC, but that's another story.
To my knowledge it is possible and have it work correctly each time. In the last year I found that the e-mails I sent using the mail() function would immediately go into my spam box (as well as the junk box of others) causing great confusion. I upgraded to PHPMailer to solve this and I have never set it up to use SMTP and works just fine.
The code I have is:
$mail = new PHPMailer(true);
$html = $email->get(); // This gets a standard HTML Template to use as the base of the e-mail.
$title = 'Title for Inside the HTML';
$subject = 'The E-mail Subject';
$html = str_replace('[title]',$title,$html); //Use this to replace the [title] element in my HTML Template with $title.
$html = str_replace('[date]',date("F j, Y g:i A"),$html); // Again, replaces [date] in the HTML Template with the current date and time.
$body = 'Hello My Good Friend,<br>This is just a simple <strong>HTML Message</strong><br><br>Thank you.';
$html = str_replace('[body]',$body,$html); //Add my HTML Message to the HTML Template.
try {
//Recipients
$mail->setFrom('noreply#example.com', 'My Organization');
$mail->addAddress($row["email"], $row["fullname"]); // Add a recipient
//Content
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = $subject;
$mail->Body = $html;
$mail->AltBody = strip_tags($html,'<br>');
$mail->send();
//Return Success Message
$rMsg .= '<div class="alert alert-success">
<strong>Success: </strong> We have e-mailed the warning.</div>';
} catch (Exception $e) {
$rMsg .= '<div class="alert alert-danger">
<strong>Error: </strong> There was an error e-mailing the warning.</div>';
}
everybody,
I am working on Email system to send emails via SMTP protocol with PHP,
everything goes fine and now I can send messages without a problem, I have tow problems Actually and I hope I will find a solution,
1 - I send email to users using a phpmailer library, but I can not control and get the result of sending email because I send about 10 emails at one SMTP connection.
this is my send code
$mail = new PHPMailer;
$froms=$respu['froms'];
$mail->Timeout = 3600;
$mail->SMTPDebug = 2; // Enable verbose debug output
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = $respu['server']; // Specify main and backup SMTP servers
$mail->SMTPAuth = $respu['authentication']; // Enable SMTP authentication
$mail->Username = $respu['username']; // SMTP username
$mail->Password = $respu['password']; // SMTP password
$mail->SMTPSecure = $respu['security']; // Enable TLS encryption, `ssl` also accepted
$mail->Port = $respu['port']; // TCP port to connect to
$mail->SetFrom($respu['username'],$froms);
$mail->AddAddress($to);
$mail->Subject = $subject;
$mail->MsgHTML($message);
if(!$mail->Send()) {
//$errors=$mail->getSMTPInstance()->getError();
$date=date('Y-m-d h:i');
echo $msg= "Message Not Sent: to $to " . $mail->ErrorInfo;
$date=date('Y-m-d h:i');
$sql="insert into log (log_text,user_email,log_time,status)values ('$msg','$to','$date',0) ";
$this->query_return($sql);
exit();
} else {$date=date('Y-m-d h:i');
$sql="insert into log (log_text,user_email,log_time,status)values ( 'Message Sent Successfully ','$to','$date',1) ";
$this->query_return($sql);
}
the if(!$mail->Send()) condition return true every time even if the email is wrong . it working like to test if the SMTP connection is done or not, I want to know if the email received by users or not.
my second problem is, I have more than 3000 mail address and I want to send email to them at the same time, what is happening is the procedure take a long time and I have to wait for a long time to finish it, how can I do it faster.
For sending to lists, use the mailing list example provided with PHPMailer as a starting point. Also read the wiki article about sending to lists.
For maximum performance, you want to be submitting to a local or nearby mail server, which then takes responsibility for onward delivery. Some messages may fail to be delivered, in which case you will need to rely on bounce handlers; when a message fails to send, it will be returned to the Return-path address, which you can control by setting the Sender property in PHPMailer (by default it uses your From address). Note that as a sender you should never set a return-path header yourself; that's the receiving server's job.
Be warned though: handling bounces is very unpleasant; because bounce messages are fairly "invisible" in normal use, it means that they are extremely variable in quality. For example, it's possible for bounces from some Microsoft Exchange servers to omit the address that the message bounced for! You can handle that scenario (and many other shortcomings of badly-configured mail servers) by using VERP addressing to help you identify original recipient addresses, or even individual messages. However you deal with this, you need to be on very good speaking terms with your mail server. Using an external service to handle sends like this isn't necessarily any better, since they face exactly the same problems, though at least they may deal with much of the unpleasantness of bounce handling.
FYI I run https://smartmessages.net, an email marketing service; it's built around PHPMailer (which is partly why I'm the maintainer), and we can send at about 300 messages/second (using a very good mail server), so decent throughput is entirely possible with PHPMailer.
There are already many questions about it, but the answers I found are not clear or contrasting, while the problem, even if stated in many ways, seem IMHO to be a general one (and I have it too).
When you have hundreds to thousands recipients for your email (usually with attachments), which is the best way to follow?
I am using AddBcc (see my code above) but I've met many issues during the year, because many recipients find the mail in the spam, many simply do not receive it (or so they say), many have issues with attachments and so on.
Here the suggestion seem to use a single email with as many AddBcc as the recipients, but here we see that "SMTP RFC (RFC 5321) does not impose any limit on BCC field length, though some ISP may limit it intentionally to prevent spamming." and we find a suggestion to send one mail for recipient.
On the other hand here we find that "I'm pretty sure it's actually built into the email protocol that you can't detect which are successful. Otherwise, this information could be used maliciously to discover email addresses for spamming purposes.", so what can I do to ensure everybody to get their email?
Moreover, here we see someone strongly suggesting one email for recipient, pointing out to the PHPmailer wiki article on sending to lists
which says (amongst other interesting things) "If the messages you send are absolutely identical, you can add all the addressees using addBCC(), which will mean you only need to send() a single message, though most mail servers will have a limit on the number of addresses you can send at once."
So, if there is no theoretical limit to Bcc number, but "some" mail servers "may" have a limit on that number, and we cannot even know which email arrived and which not, focusing on reliability, what should I do?
<?php
// database connection and session init
require 'main.php';
//mailer init
require 'phpmailer/PHPMailerAutoload.php';
$mail = new PHPMailer;
$mail->setFrom('myadd#mysite.gov.it');
//query
$q="SELECT email FROM ".$genitori_table.",".$users_table." WHERE cf_g is not null";
$q=$q." AND ".$users_table.".id_g1=".$genitori_table.".id AND ".$users_table.".stato=1";
while($row = $retval->fetch_array()){
echo $row['email'];
$mail->AddBCC($row['email']);
//$mail->addAddress($row['email']);
}
$mail->isHTML(true);
$mail->Subject = 'my subject';
$mail->Body = 'my body';
$mail->AltBody = 'my alt body.';
$mail->AddAttachment('LetteraAiGenitori.pdf','lettera');
$mail->AddAttachment('AutorizzazioneUscitaAutonomaAlunni.pdf');
if(!$mail->send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
echo 'Message has been sent';
}
?>
I am using the following PHP CODE to send BULK MAIL .But Mails seems to Land in SPAM.I am using "phpmailer" class to send the mail.
require 'mailer/class.phpmailer.php';
$mail = new PHPMailer();
$mail->IsSMTP();
$mail->SMTPAuth = true;
$mail->SMTPSecure = "ssl";
$mail->Host = "smtp.gmail.com";
$mail->Port = 465;
$mail->Username = "info#gmail.com";
$mail->Password = "Bexwa44Puciz"; // GMAIL password
$mail->AddReplyTo('info#gmail.com', 'Info');
$Appname = 'info.com';
$_subject="Newsletter From: ".$Appname;
$ema=",";
$to_bcc=explode(",",$ema);
$mail->AddCustomHeader($headers);
foreach($to_bcc as $tb){
$mail->AddBCC($tb, $dname);
}
$_body ="News content";//$hid;
$mail->FromName = "info.com";
$mail->From="inf#gmail.com";
$mail->Subject = $_subject;
$mail->AltBody = "To view the message, please use an HTML compatible email viewer!";
$mail->MsgHTML($_body);
if($mail->Send()){
echo "Done";
}else {
echo "Failed";
}
I experienced same. My website sends requests for data confirmation to users a few times each day while I do my daily data maintenance. I sent a test message to my Gmail address and found that if you read your mail through Gmail webmail interface it will sometimes tell you Why the message was spammed. Very useful. It gave the reason "A lot of messages from hp19.hostpapa.com were spam". I am on a budget shared server and I assume a hundred other spammers have bought accounts on the same machine as mine and are using it for evil. My site is non-profit so buying a dedicated box to avoid spam is not an option. So...
My solution was to change my CMS to not use PHP mail() at all. Now my CMS simply displays the message and a mailto: link with Subject parameter set. Now my process is to hit CTRL+C, Click the link, CTRL+V, and hit send. Messages are sent from my computer's IP Address (not on any blacklist) using my mail client, Thunderbird.
This takes me just a couple of seconds longer than it did when my CMS used PHP mail() to send the message for me. However I have found I am receiving a lot more replies so I am happy that the vast majority of messages are not getting spam-binned.
I appreciate this manual solution is not appropriate for automated bulk messaging but for small non-profit sites on shared server who trigger each message with a click, I thought it was worth sharing.
There are a number of reasons you could be going into someones spam box. Your email server could be blacklisted due to either you, or another user on your server. You can check it at http://mxtoolbox.com/blacklists.aspx
Also check your SPF records in your DNS