Swiftmailer - PHP-Mails landing in Spam folder - php

Im using swiftmailer for sending mails via PHP. Most times it works fine. But sometimes, my mail Mails are landing in Spam-Folder.
Here my code, which sends the mails
function sendMail2($from,$to,$subject,$body,$attachment=NULL) {
require_once 'include_apth/swiftmailer/swift_required.php';
$transport = Swift_MailTransport::newInstance();
$mailer = Swift_Mailer::newInstance($transport);
$message = Swift_Message::newInstance($subject);
$message->setFrom($from);
$message->setTo($to);
$message->setBody($body, 'text/html');
if($attachment) {
$message->attach(Swift_Attachment::fromPath($attachment));
}
if(#$mailer->send($message)) {
return true;
}
else {
return false;
}
}
any ideas, why its landing sometimes in spam-folder?

I was having the same issues with deliver-ability of emails. Getting all of the correct DNS settings, headers and the like isn't enough.
Most, if not all cloud-hosting, and home-ISPs IP ranges are on various lists of IPs from where emails are not expected to be sent from - and so they are more likely to be marked as spam.
The easiest way to solve that is to use a dedicated service where emails are well known to come from, and that the company spends a great deal of effort to get email delivery properly configured.
There are a number of well known such companies, many of which offer significant free tiers, as long as you are well behaved and send appropriate emails that aren't being marked as spam, or bounce. If you are hosted on Amazon EC2 for example, you can get over 60,000 emails delivered per month via AWS/SES. My my own systems, I have an account, currently free, with Mailgun, and a 'limit' of 10,000 email sends per month.
For Swiftmailer, there are a number of plugins that can, for example, use a HTTP API to send email to the service, which then is sent over SMTP in the usual way - with greatly improved deliverabilty.

Add the below code and it will work perfectly
$headers =& $message->getHeaders();
$headers->addIdHeader('Message-ID', "b3eb7202-d2f1-11e4-b9d6-1681e6b88ec1#domain.com");
$headers->addTextHeader('MIME-Version', '1.0');
$headers->addTextHeader('X-Mailer', 'PHP v' . phpversion());
$headers->addParameterizedHeader('Content-type', 'text/html', ['charset' => 'utf-8']);
Solution get from the below question
Swiftmailer mails go into SPAM Folder

Related

How to improve the efficiency of PHP mail sending?

I'm using PHP to send mails to multiple people in CakePHP.
I'm currently using foreach on the recipient array, which contains mail address and names, and send the mails. It's taking quite a while to send mails and can't be done as put recipients' mail as array since there's a tiny different between all mails such as receiver's names.
The mails are using same template but different parameters, is there anyway I can improve the efficiency of it?
Update: Here is the Email Template
<?= $userSex ?> <?= $userName ?>, <br>
Thanks for ordering!<br>
Your order's ID is "<?= $orderID ?>".<br>
You can check the shipping status on our website.<br>
Thank you and hope you have a wonderful day.
and here's the code.
$mail_list = {
[0]=>{
'userSex'=>'Miss',
'userName'=>'V',
'orderID'=>'xxxxxxxx'
},
[1]=>{
'userSex'=>'Mr.',
'userName'=>'Arasaka',
'orderID'=>'xxxxxxxx'
}
}
foreach($mail_list as $target) {
$email = new Email();
$email->viewBuilder()->setTemplate('notify_template');
$email->setEmailFormat('html')
->setSubject($subject)
->setViewVars([
'userSex' => $target['userSex'],
'userName' => $target['userName'],
'orderID' => $target['orderID'],
]);
$emailRes = $email
->setFrom(['no-reply#service.com' => 'service announence'])
->setTo($target['email'])
->setSubject($subject)
->send();
if (!$emailRes) {
$res = false;
break;
}
}
Every mail sent is slightly different.
Is there a way to improve the mailing speed?
The speed of your mailing will be dictated by the speed of your configured transport (See https://book.cakephp.org/3/en/core-libraries/email.html#using-transports).
Sending the emails sequentially like this will always take time and it's normally done in some sort of background process (like a cron job).
If you really need to send emails quicker than what a quick transport can offer (for orders and other transactional email, I doubt it) you could investigate other options. Most email API services provide some sort of way to send bulk messages using templates (such as Sendgrid, Mandrill, Mailgun, Postmark, etc.)

Symfony swift_mail: send to multiple address but only display one address per email

I want to send an email to a list of address but I want each person to receive the email with his email address in to: (and not with the other email addresses of the diffusion list).
I am using symfony and Swift mail. My code look like that at the moment (it is working):
public function sendmail(Notification $notification, $alert){
$to = array();
foreach ($members as $member) {
$to[] = $member->getUser()->getEmail();
}
$html = $this->templating->render(
'PlatformBundle:Emails:email.html.twig',
array('alert' => $alert, 'notification' => $notification, 'user' => $this->user)
);
// Configure and send the mail
$message = \Swift_Message::newInstance()
->setSubject('an email ')
->setFrom($this->sender_email)
->setCc($this->user->getEmail())
->setTo($to)
->setBody($html, 'text/html');
$mailStatus = $this->mailer->send($message);
}
I have 2 solutions (I do not like any for them!).
using BCC (Sending to multiple Email addresses but displaying only one C#) but it makes my email looking like a spam
looping and sending the same email to each member (seems really server resource consuming)
public function sendmail(Notification $notification, $alert){
$to = array();
foreach ($members as $member) {
$to[] = $member->getUser()->getEmail();
$html = $this->templating->render(
'PlatformBundle:Emails:email.html.twig',
array('alert' => $alert, 'notification' => $notification, 'user' => $this->user)
);
// Configure and send the mail
$message = \Swift_Message::newInstance()
->setSubject('an email ')
->setFrom($this->sender_email)
->setCc($this->user->getEmail())
->setTo($to)
->setBody($html, 'text/html');
$mailStatus = $this->mailer->send($message);
}
Is this loop OK?
Any better idea?
Looping is really the only solution.
If you have many recipients, you will be marked as spam (and banned) pretty fast. You will want to go through a dedicated mail platform (with a bit of time between each send), which you can code yourself (pretty heavy work), or there are many mail platform as service around, like MailChimp or MailJet for instance.
It all depends on the number of mails to send. Up to about 100 per day might be OK (although it's an arbitrary number from the top of my head).
More than a certain threshold, and depending on the mail server you use (local on your server or gmail for instance), your IP or account might get banned. Most email providers have a mail limit per day, for instance.
Email services have many rules for sending, for instance, they delay the emails ; they send using multiple domains and addresses ; they work with the main mail providers (gmail, yahoo...) to make sure their domains are not marked as spam automatically...
Basically, if you really want to send many emails to many people, I really don't recommend doing it yourself. There are too many caveats.

SwiftMailer Sends Mail Very Slowly

I am developing my php website on my own computer using WAMP Server. I am using the Swiftmailer to Send mail. It sends the Mail, But it works very slowly. It sends a single mail in about 8-12 seconds.
I am using the following code
$transport = Swift_SmtpTransport::newInstance('smtp.gmail.com',465, 'ssl');
$transport->setUsername('xyzmail#gmail.com');
$transport->setPassword('xyz12345');
$message = Swift_Message::newInstance();
$message->setTo("myownemail#gmail.com");
$message->setSubject("Test Mail from News Page");
$message->setFrom("xyzmail#gmail.com");
$message->setBody("This is the Message Body");
$mailer = Swift_Mailer::newInstance($transport);
if($mailer->send($message))
{
$output_msg = "Message Has been Sent Successfully!";
}
else
{
$output_msg = "Could Not Sent Message!";
}
One Thing I mention here that I am not sending so much text in the message body, I am sending the same single line text, as I have used in the above example.
Why it is working so slow, Is there any problem on my part? or do I need to use any other mail sender tool?
Not sure if SwiftMail is the problem here.
Maybe server configurations does not allow to send e-mails faster. I had a problem like this when i was in a shared server.
Because sending email fast (i.e. every 0,5 secs) can overload the server so the server administrator have configured to send an email every 10 seconds.
Another reason could be for spam security.

Swiftmailer BCCing 500 users

There are 500 unique users in our system and we have created a notification system that will send all the users a plain-text email when there is an update to one of the sections. The system uses swiftmailer and creates an email object and then BCCs the 500 users before sending it.
I just want some reassurance that BCCing 500 users means the server will consider this as sending out 1 email but to a lot of users. I don't want to run into any email limit restrictions set by my server host.
It will not count as one email. The fact that the content of the message is the same is irrelevant, as you still have 500 recipients. In addition, your host's email server probably caps the number of BCC recipients per message at a more reasonable value, so I'd be surprised if you could even do this at all. This sort of blast should be sent via individual messages. If your host balks at the volume, you'll likely have to go to a delivery service like Constant Contact et al.
I also tried to send 1000 emails using this method of BCC and it seemed that the limit for me was around 100 emails. So don't use this. Instead try to use the plugin that SwiftMailer provides.
Here is some sample code:
$mailer = Swift_Mailer::newInstance(
Swift_SmtpTransport::newInstance('smtp.example.org', 25)
);
// Use AntiFlood to re-connect after 100 emails
$mailer->registerPlugin(new Swift_Plugins_AntiFloodPlugin(100));
// And specify a time in seconds to pause for (30 secs)
$mailer->registerPlugin(new Swift_Plugins_AntiFloodPlugin(100, 30));
$content = 'email body'
$message = Swift_Message::newInstance('Email subject')
->setFrom(array('no-reply#email.com'=> 'From me'))
->setBody($content,'text/html');
$emails = array('email1#email.com','email2#email.com','email3#email.com');
foreach($emails as $recipient){
$message->setTo($recipient);
$mailer->send($message);
}
I hope this helps with your problem as a simpler solution.

Swift Mailer can address be banned for mass mailing?

I need to send over 2000 mails and I am using Swift Mailer library for it.
We have own server and it has both SMTP and sendmail transports. I am using SMTP:
$transport = Swift_SmtpTransport::newInstance('localhost', 25);
All mails are send fine to few people, but I'm afraid that we will be banned when we send mass mail.
I don't really know what means "banned" and how it looks like, but I'm afraid about the aftermath.
So, is it true, that such "ban" exists and how to implement mass mailing with Swift Mailer in a right way?
P.S.: My code looks like:
// Create the Transport
$transport = Swift_SmtpTransport::newInstance('localhost', 25);
// Create the Mailer using your created Transport
$mailer = Swift_Mailer::newInstance($transport);
// Create a message
$message = Swift_Message::newInstance($message_theme)
->setFrom(array($sender => $name))
->setTo($emails)
->setBody($message_text,"text/html")
;
try {
// Send the message
$result = $mailer->send($message);
}
catch(Exception $e) {
echo "Error: ".$e->getMessage();
}
As I'm hoping you will not use this for spam!!!
Here are some things to do:
try to same different Emails (change name of the recipient in body)
send emails once every 3-4 seconds and not 100 emails/second - it should send 2000 emails in about 2-3 hours.
Blacklisting/graylisting does indeed exist and there are some best practices you can implement to try to avoid these issues. For 2,000 emails, as long as your headers are legitimate, there is nothing fishy going on in your body text, and your recipients are on different domains, you should not run into this issue. However, as khomyakoshka mentions, the above code is incorrect and you should use a loop to send each email. This avoids exposing your entire mail list to each user.
Some additional best practices:
1) Swiftmailer offers plugins (http://swiftmailer.org/docs/plugins.html) that will help you send bulk email. Of particular note are the Throttler and AntiFlood plugins.
2) If you intend on modifying the contents of the mail to tailor to the recipient, consider using the Decorator plugin (also mentioned on the plugins page) for this task.
Hope these tips help.

Categories