I want to make a PHP newsletter sender for a few hundred people, say monthly.Does it work for me to send all the emails through a for() loop? i.e. will it use an excessive amount of resources? Also, should I sleep() for a period between each email I send? Note: to send the emails, i use the PEAR Mail::factory('smtp' ...); function.
If you're sending to a couple of hundred people, there shouldn't be too many problems.
Things to bear in mind are whether you're going to be sending individual emails, or if you're sending the same email to multiple people using BCC - the former will mean you send fewer emails, but you can't then personalise them at all.
You can definitely loop through the database with a for loop; if you're going to be sending individual emails, then I would recommend the occasional sleep(), too, just so you don't hit the mailserver too hard. It might be worth talking to them first, to let them know - they'd probably appreciate knowing that you're going to be doing that, especially if your newsletter subscribers grow into the thousands.
You can use a for loop for sending 100 emails, but I don't know about the sleep(). I have sent 200 mails at a time using PHP mailer in a for loop.
Related
I am building a site through WordPress and coded in my own bulk email. I used a plugin to ensure that emails are sent authentically through my gmail account. I use wp_mail to trigger the email.
My first strategy was to send to: myself and bcc: everyone. This gave a gmail error for too many recipients.
Then, I split the email into chunks of 49, and it worked well. Now, I’m creating an unsubscribe link and I realized that I have no way to include the recipients email address in the email because it’s the same email bcc’d to 50 people.
What is the best approach to solve this problem? Can I send to: hundreds of people without gmail getting upset at me?
No, usually you can't send hundreds of mails just like that, you will be blocked and it may have repercussions like having your domain-name credibility hurt for a long time.
there are several ways:
Ask your Hoster about his stance. For example, my Hoster allows 1 Mail every 1.5 seconds in average. I'm using a cronjob that calls a wordpress endpoint in which i loop thru several 1000 emails (legit newsletters), each loop 2 seconds of break. this is just an example, it doesn't make quite sense, but the important part is: set the timeout fresh on each loop, set a sleep. i tested this with 100000 mails and it worked without a hitch on the website.
for ($i = 1; $i <= $total; $i++) {
set_time_limit(20);
sleep(2);
wp_mail($email, $subject, $body); //i set up an smtp plugin for this
}
Another, and frankly more professional solution, is using a service like mailgun.com, there you can hammer as many mails thru their API as you want. But of course, it costs some $ :-)
I'm using a homemade PHP script with PHPmailer for sending email, currently I just do one select statement in MYSQL and then run a 100-150 email send request from PHPmailer via a for loop.
my problem is that I have to port this script to a 7000 user mailing list, and I know it's not going to hold up since sending to 150 takes about 8 secs of execution time - also sending 7000 emails might mark me as a spammer or I won't be able to handle all responces.
I thought about splitting the 7000 into groups of like 200-500 and sending an email to each group every day until sending everyone - to do that i'll have to write a PHP script that handles the limits and remembers when & who on the list hasn't received that email yet and is due to receive it on the next batch.
What are my options, what are your thoughts?
Just my 2 cents.
1) I agree with Dave re: make it take longer than it needs. Most black/grey listing is the the recipient mail server deciding there is an odd amount of traffic compared to usual. Yahoo is terrible for this and given the sheer volume of domains they deal with, it can get annoying.
2) Using multiple IP addresses doesn't hurt. Extra IPs are usually free, and if you are using exim, you can easily configure it to use each IP based on e.g. EHLO, or send to domain etc etc. This means that there is less volume coming from any one IP.
3) Keep a track of bounce backs. Some providers will keep a track of the number of attempts to deliver mail to a non-existent address, the more you try, the more suspicious it looks. Easiest way to keep a track of them in my experience is to use VERPs and get PHP to process the incoming data.
4) Set up reverse DNS. Some hosts will just ignore the mail if you have not got it set up for the sender. I believe AOL is an example.
Just a few pointers from my experience.
Your first approach is a pretty good idea. As long as you're ok with it taking about 3 minutes to send all the emails (which it should be, if you're only sending a weekly newsletter or the like). To reduce the chance of getting marked spam, lower the threshold or make it take longer. Beyond that, it might be a good idea to move into a hosted mass mailing service.
The act of sending 7000 [or more] emails is not going to get you marked as a spammer ~assuming~ that the mail you are sending is:
not spam
contains complete & accurate header information
The only problem you might get is clogging up your mail queue, but you r volume is still pretty low. I would say for scalability - throttle your delivery over about an hour or so.
and consider ceejayoz's suggestion "MailChimp" it's free up to 5000 emails/month and has an excellent API that you can literally integrate into your app in a couple of hours.
-sean
I figure I can either use one mail() command with a large Bcc list or have a loop that sends many individual emails.
I was just going to use Bcc since that is easiest to program and seemed easiest for the server to handle, but then I have to choose some address for the To field. I can just send mail to the websites own address but it would look more sensible to recipients if it was addressed to them. Also, it would be nice to customize each message by saying "Hello [firstname]" at the beginning.
I'm just concerned that sending to too many people will take too long. The maximum number of recipients will be 2000. Users on the website choose a list of people to send to, type a message, and press Send. Would they be waiting forever if it was sending to 2000 people? Would the server choke?
Also what considerations are there regarding mail servers thinking of this as spam?
EDIT: Apparently my client has an SMTP server he says can throttle the outgoing emails. Still not sure though if the PHP would be slow when sending to 1000+ people...
Sending large number of emails at once can really bog down your server, or if its a shared hosting, there is a limit to the number of emails that can be sent over an hour (with bluehost its 700 per hour). So i would recommend you to send emails in chunk.
Create table email_queue with two fields email_to and email_content. Now whenever you wish to send an email, just insert a record into this table with the email address that you wish to send the email to stored in the email_to column and the raw email content in the email_content column.
Next you would create a cron job that runs every hour, that cron job would check the email_queue table to see if it has to send any email, it will pick up 100 records from the email_queue table and send those 100 emails, when the emails have been send those 100 records would be deleted.
This I think would be an ideal way to send out emails in large numbers.
It's a pretty complex subject with respect to making sure the emails don't start looking like spam. You can really do yourself some favours by hooking it up to something like MailChimp.com and letting them deal with the nasty details for you.
I would actually recommend looking at a third party that can be accessed by an API. Mailing out large numbers of e-mails can be detrimental to your server as it can end up black listed. Check out a company like www.postmark.com or something similar that will throttle your message queue, manage white listed servers, etc.
I'm about ready to unveil a "coming soon" page and one thing I need is a way for users to enter their email address for me to email once the site goes live. What is the best way to do this?
Should I store the emails in a DB and then run a PHP script to email them from my web host? Should I have the emails just kind of be collected and then emailed manually by me either locally or from the server? Is there another way I should do it?
Also, are there certain web-hosts that restrain the amount of emails you can send out, thus causing a problem for mass email.
The only "unknown" currently is how large of a response I'll get...only time will tell.
Thanks guys!
Store it in the database - Yes. It's no unlike storing any other piece of data.
Mass email at once - No
Mass email manually (or individually mail manually) - No
Do some web hosts limit how many you can send at once? - Yes
I don't know the "best" way but I know a really good way. We have built several mass emailing programs and the technique we incorporated was a throttling technique whereby we had a script that ran every three minutes and sent 20 emails at a time.
It keeps the server from choking and the mail queue from exceeding any of our hosts' mail limits.
Store the email addresses in a database and write a batch job that mail merges them into your message and sends them out as needed.
There are dozens of methods you can use for this kind of problem, but unfortunately there's no real way to pinpoint a solution for you, since there are a lot of variables.
If you only get 3 responses, then you might want to just manually email the users from your email client using BCC:. You've already got all the tools you need to do that, and setting up a script might be a waste of time. This isn't really a great long-term solution however.
For most moderate-sized web sites you would store the emails in a database, and use a mailing script to send them out. PHPMailer is a good tool to help with getting mail sent, and you can manage a decent amount of email addresses manually. Managing addresses manually can be a bit of a pain however, as you have to deal with unsubscribe links, script timeouts, bounced email, etc.
If you get up the tens of thousands of email addresses, you may want to start looking at a third-party mailing software or service that can do threaded sending. Looping through and sending email to 50,000 people via a PHP script can be slow, and take hours.
Basically you have to weigh the difficulty, time and cost of each method versus how much flexibility and power you think you're going to need.
To store emails in a db, and sending them out using a cronjob is a good way to solve the problem, if you have constrains regarding the amount of emails you're allowed to send within a period of time, you can handle it by keeping track of how many emails you've sent every time the cronjob runs.
Also, there are open source products to do this, such as phplist http://www.phplist.com/
Like Eric mentioned above, another option is to use a commercial service to manage your mailing list.
I use Mailchimp (http://www.mailchimp.com). They give you everything you need (signup forms, email templates, etc.), and are completely free unless your list grows to more than 500 subscribers.
Writing the emails to a database or a text/log file are both fine ways to store the emails.
Depending on how many emails you receive, you may want to write a program (PHP works) to send a separate email to each person. Don't send a mass email from your regular email client with everyone on a big To: line.
There are also commercial programs that manage mailing to lists of people (probably open source ones, too). Most of those commercial ones offer a free trial period.
I am currently writing a music blog. The administrator posts a new article every 2-3 days. Once the administrator posts an article, a mass email will be sent to around 5000 subscribers immediately.
What is the best way to implement the mass mail feature?
Does the following function work?
function massmail()
{
$content = '...';
foreach ($recipients as $r) {
$_content = $content . '<img src="http://xxx/trackOpenRate.php?id='.$r.'">';
mail($r, 'subject', $_content);
}
}
Another question: If all 5000 subscribers are using Yahoo Mail, will Yahoo treat it as a DDOS attack and block the IP address of my SMTP server?
First off, using the mail() function that comes with PHP is not an optimal solution. It is easily marked as spammed, and you need to set up header to ensure that you are sending HTML emails correctly. As for whether the code snippet will work, it would, but I doubt you will get HTML code inside it correctly without specifying extra headers
I'll suggest you take a look at SwiftMailer, which has HTML support, support for different mime types and SMTP authentication (which is less likely to mark your mail as spam).
I would insert all the emails into a database (sort of like a queue), then process them one at a time as you have done in your code (if you want to use swiftmailer or phpmailer etc, you can do that too.)
After each mail is sent, update the database to record the date/time it was sent.
By putting them in the database first you have
a record of who you sent it to
if your script times out or fails and you have to run it again, then you won't end up sending the same email out to people twice
you can run the send process from a cron job and do a batch at a time, so that your mail server is not overwhelmed, and keep track of what has been sent
Keep in mind, how to automate bounced emails or invalid emails so they can automatically removed from your list.
If you are sending that many emails you are bound to get a few bounces.
This is advice, not an answer: You are much, much better off using dedicated mailing list software. mailman is an oft-used example, but something as simple as mlmmj may suffice. Sending mass mails is actually a more difficult task than it actually appears to be. Not only do you have to send the mails, you also have to keep track of "dead" addresses to avoid your mail, or worse, your mailserver, being marked as spam.
You have to handle people unsubscribing for much the same reason.
You can implement these things yourself, but particularly bounce handling is difficult and unrewarding work. Using a mailing list manager will make things a lot easier.
As for how to make your mail palatable for yahoo, that is another matter entirely. For all its faults, they seem to put great stock in SPF and DomainKey. You probably will have to implement them, which will require co-operation from your mail server administrator.
You may consider using CRON for that kind of operation. Sending mass mail at once is certainly not good, it may be detected as spam, ddos, crash your server etc.
So CRON could be a great solution, send 100 mails at once, then wait a few minutes, next 100, etc.
Do not send email to 5,000 people using standard PHP tools. You'll get banned by most ISPs in seconds and never even know it. You should either use some mailing lists software or an Email Service Provider do to this.
Why don't you rather use phplist? It's also built on top of PHP Mailer and a lot of industry leaders are using it. I've used it myself a couple of times to send out bulk mails to my clients. The nice thing about phplist is that you can throttle your messages on a domain level plus a time limit level.
What we've also done with a couple of internal capture systems we've got was to push our user base to the mailling list and then have a cron entry triggering a given mail each day. The possibilities are endless, that's the awesome thing about open source!
Also the Pear packages:
http://pear.php.net/package/Mail_Mime
http://pear.php.net/package/Mail
http://pear.php.net/package/Mail_Queue
sob.
PS: DO NOT use mail() to send those 5000 emails. In addition to what everyone else said, it is extremely inefficient since mail() creates a separate socket per email set, even to the same MTA.
Also have a look at the PHPmailer class. PHPMailer
You can use swiftmailer for it. By using batch process.
<?php
$message = Swift_Message::newInstance()
->setSubject('Let\'s get together today.')
->setFrom(array('myfrom#domain.com' => 'From Me'))
->setBody('Here is the message itself')
->addPart('<b>Test message being sent!!</b>', 'text/html');
$data = mysql_query('SELECT first, last, email FROM users WHERE is_active=1') or die(mysql_error());
while($row = mysql_fetch_assoc($data))
{
$message->addTo($row['email'], $row['first'] . ' ' . $row['last']);
}
$message->batchSend();
?>
I already did it using Lotus Notus and PHP.
This solution works if you have access to the mail server or you can request something to the mail server Administrator:
1) Create a group in the mail server: Sales Department
2) Assign to the group the accounts you need to be in the group
3) Assign an internet address to the group: salesdept#DOMAIN.com
4) Create your PHP script using the mail function:
$to = "salesdept#DOMAIN.com";
mail($to, $subject, $message, $headers);
It worked for me and all the accounts included in the group receive the mail.
The best of the lucks.
There is more into it aside from using a software. If you could create a bulk emailer program that sends intermittently. Say if you will send 5,000 recipients, create a loop that would send 38 lists per sending then pause for 10 seconds. I have an actual experience sending 500 manually per days for the past weeks and so far i have good results.
Another consideration are the content of your email. Nowadays it is a standard that you need to put your physical office address and the "unsubscribe" opt-out. These are factors that majority of recipient emails servers are checking. If you don't have these they will classify you as spammer.
Mailchimp is my best recommendation to use if you want a paid service provider in sending to your email subscriber NOT sending unsolicited or cold email marketing.
Hope it helps.