For the web applications I build a lot of them want to sent out an email to their users for many different reasons. (All these reasons are legitimate, for example sending our a link to allow the users to login, reminders about upcoming classes etc) This can generate a lot of traffic. Usually this would be no problem, except that it appears that the company who is hosting the sites has started to throttle the amount of emails that can be sent.

This itself isnt an issue, they are doing a good job at stopping people from sending unsolicited bulk mail and that is great. The issue lies in that due to the throttling the scripts that send out the emails are timing out. This makes it difficult to know who has received the mail and who has missed out. Also it is just a general source of frustration for the people who use the sites because they don’t know if the messages have arrived or have been lost in the ether.

So I need a way to slowly release the emails out into the wild. This is the fix that I came up with to do so.

First we are going to need a database which will be used to hold queued messages.

I am going to store the following information about who it is going to, when it was submitted, subject, message, headers, status and the date it was sent. So to setup the database table I used the following code:

CREATE TABLE IF NOT EXISTS `email_queue` (
  `id` int(5) NOT NULL AUTO_INCREMENT,
  `submission_date` varchar(50) NOT NULL,
  `recipient` varchar(250) NOT NULL,
  `subject` varchar(250) NOT NULL,
  `message` text NOT NULL,
  `headers` text NOT NULL,
  `status` varchar(50) NOT NULL,
  `sent_date` varchar(50) NOT NULL,
  PRIMARY KEY (`id`)
)

Now that I have the storage table setup. I need to adjust the scripts that sent the email to place them into the storage table rather then trying to send them automatically. I will cover the whole script which also sets up the messages etc.

<?
//Collect the variables
$subject = addslashes($_POST['subject']);
$message_original = $_POST['message'];
$sent = "";

/* Now get all of the contacts, with an email address and that are subscribed. */
$sql = "SELECT * FROM `contacts` WHERE `email` != '' AND `subscribed` = 'y' ";
$results = mysql_query($sql)
	or die($error = "Error getting email addresses.");

/* Now check if there are any email addresses to send to. */	
if(mysql_num_rows($results) == 0) {
	echo "No valid email address on record.";
	exit();
} //if check for results

/* From the results above create an array of contacts and additional information. */
while($row = mysql_fetch_array($results)) {
	$email_array[] = array($row['name'], $row['email']);
} //while create the array of email addresses
					
/* Now we will need to loop through the available email addresses and create and send the emails. */
foreach($email_array as $ea) {
	$message = $message_original;
	
	/* Setup the message. The message will replace the text '::name::' with the customer name from the database. This makes the messages nice and personal */
	$message = str_replace("::name::", $ea[0], $message); //Name replacement
	$message = str_replace("\n", "<br />\n" , $message); //Replace new lines correctly
	$message = $message_header .$message .$message_footer; //Add the message header and footer
	$message = wordwrap($message,70,"\n"); //Wrap the lines at 70 characters.
							
	/* This adds the message into the holding table. */
	$sql = "INSERT INTO `email_queue` (`id` ,`submission_date` ,`recipient` ,`subject` ,`message` ,`headers` ,`status` ,`sent_date` )";
	$sql .= "VALUES (NULL , '" .strtotime("now") ."' ,  '" .$ea[1] ."',  '$subject',  '" .addslashes($message) ."', ";
	$sql .= "'" .addslashes($headers) ."',  'queued',  '')";
	
	$results = mysql_query($sql)
		or die($error = "Error sending email");
	
} //foreach
?>

So in this post we have setup the holding database, pulled information from a database about our contacts, created the messages, and placed them into the holding database ready to be sent in smaller batches. In the next post I will setup the script which will be used to pull the messages out and send them in batches to bypass the throttling.