Newsletter mailing - need expert advice on app design.

Discussion in 'Programming' started by Artashes, Aug 1, 2008.

  1. #1
    I run an active forum with over 10,000 members. Around 7,000 of those members are opt-in newsletter subscribers.

    The problem comes is that I cannot use forum software to distribute the newsletter because my hosting company sets a limit on outbound email traffic, so most of the emails will end up undelivered. On top of that, I don't want to load the server like that as one-time action - I would rather spread the load over a period of time.

    So I need to create some sort of an application in which I can insert all the extracted email addresses in a regular text format (separated by comma or semicolumn). The application will then send the newsletter (in a text or HTML format (for that I attach the HTML file like you would with a Word document) in specified by me batches/numbers (ex: 200 emails at a time) and time periods (ex: every 2 hours). If necessary, I will also insert all the outgoing server information (which can actually give me the flexibility to use any of the sites I have as mail out point) and an email "face" account from which the mailing is done from.


    Question: How do I approach it? How will you suggest building such an application? I am looking for some great ideas on how to solve this problem. I obviously don't care about the looks, just functionality - I need the best possible and reliable solution. Whether it is web-based or desktop-based doesn't make a difference.


    PS: I had a script done a couple of years ago that looked just like a regular web form. As far as I know, it used "cron" to memorize the email list and send out emails according to my specifications. It worked fine, but every time I made changes to the server, the form/cron would break. So I need something different.

    I really appreciate any input I can get! Please keep in mind that I am not strong on "technical" lingo.

    Thank you in advance.
     
    Artashes, Aug 1, 2008 IP
  2. Vooler

    Vooler Well-Known Member

    Messages:
    1,146
    Likes Received:
    64
    Best Answers:
    4
    Trophy Points:
    150
    #2
    As you said, cron would break if changes made to server, yes it would definitely, but there is a solution, why not let the script clear all cron jobs and just add one new for sending the newsletter. And when job's done scirpt erases the cron job.

    Secondly, I disagree sending 200 in 1 hour, I would suggest send 20 in 5 minutes, it will be ok, if the mail size is not too large. Sending 200 in one attempt may cause bottle-neck situation.

    Now here is the prototype of the scripts


    Script1.php - Admin Panel
    Step 1. Extract all subscribers and save them to plain text file, such as

    $res = mysql_query("SELECT email FROM your_table WHERE subscribed='Yes'");
    $array = Array();
    while($row = mysql_fetch_asoc($res)) 
         $array []= $row['email'];
    $array = implode("\n",$array);
    
    $f = fopen("newsletter.txt","w"); #write the file
    fwrite($f,$array);
    fclose($f);
    Code (markup):
    Step 2. Wipe up all cron jobs, and write new one
    #clear all
    $raw_arr = Array();
    exec("crontab -r",$raw_arr);
    Code (markup):
    #set new
    $path = dirname($_SERVER['SCRIPT_FILENAME']);
    $job = "* * * * * php -q ".dirname($_SERVER['PHP_SELF'])."/newsletter.php";
    $tmp_file = dirname($_SERVER['PHP_SELF'])."/tempfile.crn";
    $f = fopen($tmp_file, "w");
    fwrite($f, "$job\n");
    fclose($f);		
    $raw_arr=Array();
    exec("crontab $tmp_file",$raw_arr);		
    @unlink("$tmp_file");
    Code (markup):
    newsletter.php - the sender

    
    $per_attempt = 20; #20 mails per attempt
    
    #first check if already empty
    if(file_size("newsletter.txt")==0) {
       #remove all cron job
       $raw_arr = Array();
       exec("crontab -r",$raw_arr);
       #delete temporary mails text file
       @unlink("newsletter.txt");
       die();
    }
    
    $arr = @file("newsletter.txt");
    
    if($arr !== FALSE) {
       #take top N addresses
       $mails = array_slice($arr,0,$per_attempt);
       foreach($mails as $mail) {
          #send email to address "$email"
       }
       #write remaining to file for next attemp
       $arr = array_diff($arr,$mails);
       $f = fopen("newsletter.txt","w");
       fwrite($f,implode("\n",$arr);
       fclose($f);
    }
    Code (markup):

    Using this way, you can get rid of opening extra mysql connections on each attempt. And save server load too.

    Let me know if you need more help. I already coded such application for a mailing list that was used for more than 260,000 mails per day, and went perfect.

    regards
     
    Vooler, Aug 2, 2008 IP