Jump to content

jay5r

Clients
  • Posts

    42
  • Joined

  • Last visited

Reputation Activity

  1. Like
    jay5r got a reaction from SeNioR- in Problem with `core_stream_subscriptions` causing huge increase in load   
    I can say that 4.6.10 didn't fix the problem. It started before I did the upgrade and didn't go away with the upgrade.
    I just looked at my backup and I do have the data. I could restore it pretty easily.
  2. Like
    jay5r got a reaction from Square Wheels in Bouncing Emails   
    Honestly I don't know exactly everything EmailBouncer does, and whether it meets your requirements (maybe @stoo2000 can answer that), but if it does, the simplified version of my script boils down to this…
    <?php \define('REPORT_EXCEPTIONS', TRUE); $_SERVER['SCRIPT_FILENAME'] = __FILE__; require_once 'init.php'; header('Content-Encoding: none'); ob_implicit_flush(true); ob_end_flush(); set_time_limit(60*180); echo str_repeat(' ',1024*64.1); $hardfails = array( 'email1@host5.com', 'email2@host4.com', 'email3@host3.com', 'email4@host2.com', 'email5@host1.com' ); $softfails = array( 'email6@host0.com', 'email7@host9.com', 'email8@host8.com', 'email9@host7.com', 'email0@host6.com' ); echo '<!DOCTYPE html><html lang="en-US" dir="ltr"><head><meta charset="utf-8"></head><body>'; echo "<p>Please note: 'Email address not found' can mean two things – 1) that you have a problem because a member record could not be found, or 2) that the member has already corrected the problem. If you see just a few messages like that, it usually indicates that the member already corrected the problem.</p>"; echo "</ul><h2>".count($softfails)." Soft Fails</h2><ul>"; asort($softfails); foreach ($softfails as $fail){ list($email, $datetime) = explode(',', $fail); echo "<li>$email – "; ob_flush(); $member = \IPS\Member::load( $email, 'email' ); if( $member->member_id ) { if ($_GET['test'] != '1'){ $member->bouncerSoftBounce( $datetime ); } echo "set as soft bounce. ($datetime)"; } else { echo "<b>EMAIL ADDRESS NOT FOUND</b>"; } echo "</li>"; ob_flush(); } echo "</ul>"; echo "<h2>".count($hardfails)." Hard Fails</h2><ul>"; asort($hardfails); foreach ($hardfails as $fail){ list($email, $datetime) = explode(',', $fail); echo "<li>$email – "; ob_flush(); $member = \IPS\Member::load( $email, 'email' ); if( $member->member_id ) { if ($_GET['test'] != '1'){ $member->bouncerHardBounce( $datetime ); } echo "set as hard bounce. ($datetime)"; } else { echo "<b>EMAIL ADDRESS NOT FOUND</b>"; } echo "</li>"; } echo "</ul>"; echo "</body></html>"; ?> Take that file, save it as something like bouncing.php and then replace the email@host.com stuff in the two arrays with the list of emails you want handled. Make sure the list is  formatted the same way – quotes (or double quotes) around each email address and commas between them. And if you have no hard or soft bounces take out all the examples so it just says array();
    After you make those changes, use FTP to put the file in the root directory of your site. Then use this URL:
    https://yoursite.com/bouncing.php?test=1
    That will run through things and do everything except for actually handing the bounces. If everything looks good, then run the same URL without the ?test=1 and it will actually do the hard and/or soft bounces.
  3. Like
    jay5r got a reaction from Maxxius in Bouncing Emails   
    So here's my code… It comes with a lot of caveats… Think of it as starting point so you or your developer doesn't have to start from scratch. I'm not the best PHP programmer, so my code may not be quite as beautiful as yours, but it's better than nothing. Also, this code calls MailBouncer, so you must have an active license for that. You can put the the file anywhere and name it anything (ending in .php). The code will almost certainly need to be tweaked. For example,  my mail server is running SendMail. If your mail server is running something different the bulk of your messages may have different formatting.
    Here's what it does… Logs into your email account and scans through all the messages from postmaster@ and MAILER-DAEMON@. You can login with IMAP or POP w/ or w/o SSL. Only IMAP w/o SSL has been tested, but the code is there for the others. After processing the entire mailbox, when you repeat the process you'll probably want to do just examine the most recent period. To do that add ?days=X to the end of the URL where X is the number of days you want to examine. X can be a decimal number.
    When it scans it classifies things as 4 types:
    Indeterminate Reputation problem Hard bounce Soft bounce You won't see detailed information about hard and soft bounces, but you will if there's a reputation problem or the outcome was indeterminate.
    Reputation problems typically mean that your server got on a blacklist. You'll want to rectify this ASAP. Reputation problems are handled as soft bounces, since they're not the fault of the member.
    Indeterminate issues are when you'll probably need to tweak the code to handle the case (typically different error formatting). You can add trigger phrases to $softphrases, $hardphrases and $reputationphrases. If it's not parsing the email address that's bouncing, that's a little trickier. Or you can just manually go into the IP board admin area and do manually what Mail Bouncer does.
    It is possible to change up the code to not scan a mailbox and just handle a long list of emails you've manually put together – just replace everything inside
    if (!$mbox = imap_open($authhost, $user, $pw)){ } else {} with something that populates the $hardfails and $softfails arrays.
    At the end it does one other thing – it queries the database and finds everyone who has been banned for 8 weeks or longer and processes their email addresses as hard bounces. These people are probably mad at you and don't want your emails, and they're likely to mark your emails as spam just to spite you. So it's best to just treat the email as bad and if/when the member returns they can revalidate their email address. The SQL query is shown. You'll need to rewrite the actual pull from your IP.Board database. I use Fat Free Framework, so that's the syntax you'll see. To turn off handling of long bans permanently just comment out or delete the code. But you can also add lb=off to the end of the URL to not to it on a particular run of the script.
    With all of that said, here's the code…
    <?php //I USE FAT FREE FRAMEWORK, SO THERE'S AT LEAST ONE CASE WHERE YOU NEED TO REPLACE F3 CODE WITH YOUR OWN CODE $user = 'your_mail_username'; $pw = 'your_mail_pw'; $mailserver = 'localhost'; \define('REPORT_EXCEPTIONS', TRUE); $_SERVER['SCRIPT_FILENAME'] = __FILE__; require_once '/path/to/init.php'; //PATH TO THE INIT.PHP FILE FOR YOUR IP.BOARD INSTALL header('Content-Encoding: none'); ob_implicit_flush(true); ob_end_flush(); set_time_limit(60*180); echo str_repeat(' ',1024*64.1); $hardfails = array(); $softfails = array(); //THE FOLLOWING ARRAYS OF PHRASES DETERMINE THE TYPE OF FAILURE, EDIT THEM AS NEEDED $softphrases = array(); $softphrases[] = '(reason: 552'; //552 = Exceeded storage allocation $hardphrases[] = '<<< 552'; $softphrases[] = ' over quota'; $softphrases[] = ' inbox is full'; $softphrases[] = ' mailbox is full'; $softphrases[] = ' mailbox full'; $softphrases[] = 'Mail quota exceeded'; $softphrases[] = 'is over quota'; $hardphrases = array(); $hardphrases[] = '550 5.1.1'; $hardphrases[] = '550-5.1.1'; $hardphrases[] = '<<< 550'; //550 = Non-existent email address $softphrases[] = '(reason: 550'; $hardphrases[] = 'Status code: 550'; $hardphrases[] = ' mailbox unavailable'; $hardphrases[] = ' deactivated mailbox'; $hardphrases[] = ' Bad destination mailbox address'; $hardphrases[] = ' no valid recipients'; $hardphrases[] = 'Not a valid recipient'; $hardphrases[] = 'User unknown'; $hardphrases[] = ' Address does not exist'; $hardphrases[] = ' mailbox is disabled'; $hardphrases[] = ' user doesn\'t have a yahoo'; $hardphrases[] = 'is a deactivated mailbox'; $reputationphrases = array(); //things that indicate they just don't like/trust the email //this is a problem if you sent the email, not a problem if some spammer sent the email (pretending to be you) $reputationphrases[] = 'Relay access denied'; //https://serversitters.com/how-to-correct-554-5-7-1-relay-access-denied-email-errors-and-prevent-them-in-the-future.html $reputationphrases[] = ' blocked using '; //ONE OF THE FOLLOWING 4 LINES SHOULD BE UNCOMMENTED DEPENDING ON WHAT TYPE OF CONNECTION YOU WANT TO MAKE TO YOUR MAIL SERVER //$authhost="{".$mailserver.":995/pop3/ssl/novalidate-cert}"; //POP w/o SSL //$authhost="{".$mailserver.":110/pop3/notls}"; //POP w/ SSL $authhost="{".$mailserver.":993/imap/ssl/novalidate-cert}"; //IMAP w/o SSL (this is the only one that's been tested) //$authhost="{".$mailserver.":143/imap/notls}"; //IMAP w/ SSL echo '<!DOCTYPE html><html lang="en-US" dir="ltr"><head><meta charset="utf-8"></head><body>'; if (!$mbox = imap_open($authhost, $user, $pw)){ echo "<p>Could not connect to mail server.</p>"; } else { echo "<p>Connected to mail server.</p>"; $totalrows = imap_num_msg($mbox); echo "<p>Found $totalrows messages</p><ul>"; $result = imap_fetch_overview($mbox, "1:$totalrows", 0); foreach ($result as $overview) { $body = imap_fetchbody($mbox, $overview->msgno, "1"); $datetime = strtotime($overview->date); date_default_timezone_set("UTC"); if (stripos($body, 'https://web.de/email/senderguidelines') !== false && stripos($body, 'cs2172.mojohost.com') !== false) { //ignore these, problem was resolved } else if ($_GET['days'] > 0 && $datetime < time() - ($_GET['days'] * 86400)){ //do nothing, it doesn't meet the cutoff // echo "<li>Skipping: $datetime < ".(time() - ($f3->get('days') * 86400))."</li>"; } else if ((stripos($overview->from, 'Mailer-Daemon@') !== false || stripos($overview->from, 'postmaster@') !== false ) && ((strpos($body, '----- The following addresses had permanent fatal errors -----') !== false && strpos($body, '(reason: ') !== false) || (stripos($body, 'Final-Recipient: ') !== false) || (stripos($body, 'message couldn\'t be delivered to ') !== false) || (stripos($body, '> is a deactivated mailbox') !== false) || (strpos($body, ' to these recipients or groups:') !== false && strpos($body, 'The recipient\'s mailbox is full') !== false))) { //PARSE THE EMAIL ADDRESS THAT'S HAVING A PROBLEM $bademail = ''; if (strpos($body, '----- The following addresses had permanent fatal errors -----') !== false) { $pos1 = strpos($body, '----- The following addresses had permanent fatal errors -----'); $pos1 = $pos1 + strlen('----- The following addresses had permanent fatal errors -----'); $pos2 = strpos($body, '(reason: ', $pos1); if ($pos2 > 0) { $bademail = str_replace('<', '', str_replace('>', '', trim(substr($body, $pos1, $pos2 - $pos1)))); } } else if (stripos($body, 'Final-Recipient: ') !== false){ //The syntax of the field is as follows: // "Final-Recipient" ":" address-type ";" generic-address // i.e. Final-Recipient: rfc822; skijanje-zg@net.hr $pos1 = strpos($body, 'Final-Recipient: '); $pos1 = $pos1 + strlen('Final-Recipient: '); $pos2 = strpos($body, "\r", $pos1); if (strpos($body, "\n", $pos1) < $pos2){ $pos2 = strpos($body, "\n", $pos1); } if ($pos2 > 0) { $bademail = substr($body, $pos1, $pos2 - $pos1); $pos3 = strpos($bademail, ';'); if ($pos3 !== false){ $bademail = substr($bademail, $pos3 + 1); } $bademail = trim($bademail); } } else if (strpos($body, ' to these recipients or groups:') !== false && strpos($body, 'The recipient\'s mailbox is full') !== false){ $pos1 = strpos($body, ' to these recipients or groups:'); $pos1 = $pos1 + strlen(' to these recipients or groups:'); $pos2 = strpos($body, 'The recipient\'s mailbox is full', $pos1); if ($pos2 > 0) { $bademail = trim(substr($body, $pos1, $pos2 - $pos1)); if (strpos($bademail, '<') !== false && strpos($bademail, '>') !== false){ $bademail = substr($bademail, strpos($bademail, '<') + 1); $bademail = substr($bademail, 0, strpos($bademail, '>')); } } } else if(stripos($body, '> is a deactivated mailbox') !== false){ $bademail = substr($body, 0, stripos($body, '> is a deactivated mailbox')); $bademail = substr($bademail, strrpos($bademail, '<') + 1); } else if(stripos($body, 'message couldn\'t be delivered to ') !== false){ $bademail = substr($body, stripos($body, 'message couldn\'t be delivered to ') + strlen('message couldn\'t be delivered to ')); $bademail = substr($bademail, 0, strpos($bademail, '. ')); } //CLEAN UP THE EMAIL ADDRESS if (stripos($bademail, 'mailto:') === 0){ $bademail = substr($bademail, strlen('mailto:')); } if (!filter_var($bademail, FILTER_VALIDATE_EMAIL)) { echo "<li><b>ERROR: PARSED THE EMAIL $bademail BUT IT IS NOT A VALID EMAIL ADDRESS</b></li>"; $bademail = ''; } //EVALUATE DIFFERENT TYPES OF PROBLEMS $result = 'Indeterminate'; if ($result == 'Indeterminate'){ //reputation problems foreach($reputationphrases as $phrase){ if ($result == 'Indeterminate' && stripos($body, $phrase) !== false) { $result = 'Reputation Problem'; } } } if ($result == 'Indeterminate'){ //hard bounces foreach($hardphrases as $phrase){ if ($result == 'Indeterminate' && stripos($body, $phrase) !== false) { $result = 'hard'; } } } if ($result == 'Indeterminate'){ //soft bounces foreach($softphrases as $phrase){ if ($result == 'Indeterminate' && stripos($body, $phrase) !== false) { $result = 'soft'; } } } if ($result == 'Indeterminate' || $bademail == '') { echo "<li>{$overview->msgno}<ul>"; echo "<li>Sent: {$overview->date}</li><li>From: " . htmlspecialchars($overview->from) . "</li><li> Subject: {$overview->subject}</li>"; echo "<li><pre>" . htmlspecialchars(substr($body, 0, 10240)) . "</pre></li>"; echo "<li><b>Bad Email: $bademail</b></li>"; echo "<li>Date/Time: $datetime</li>"; echo "<li><b>Result: $result</b></li>"; echo "</ul></li>"; } elseif ($result == 'Reputation Problem') { echo "<li>{$overview->msgno}<ul>"; echo "<li>Sent: {$overview->date}</li><li>From: " . htmlspecialchars($overview->from) . "</li><li> Subject: {$overview->subject}</li>"; echo "<li><pre>" . htmlspecialchars(substr($body, 0, 10240)) . "</pre></li>"; echo "<li><b>Bad Email: $bademail</b></li>"; echo "<li>Date/Time: $datetime</li>"; echo "<li><b>Result: Reputation Problem (handled as a soft bounce)</b></li>"; echo "</ul></li>"; $exists = false; for($i = 0; $i < count($softfails); $i++){ list($temp_email, $temp_dt) = explode(',', $softfails[$i]); if ($temp_email == $bademail){ $exists = true; if ($temp_dt < $datetime){ $softfails[$i] = "$bademail,$datetime"; //update date time } } } if ($exists === false){ $softfails[] = "$bademail,$datetime"; } } elseif ($result == 'hard' && array_search("$bademail,$datetime", $hardfails) === false) { $exists = false; for($i = 0; $i < count($hardfails); $i++){ list($temp_email, $temp_dt) = explode(',', $hardfails[$i]); if ($temp_email == $bademail){ $exists = true; if ($temp_dt < $datetime){ $hardfails[$i] = "$bademail,$datetime"; //update date time } } } if ($exists === false){ $hardfails[] = "$bademail,$datetime"; } } elseif ($result == 'soft' && array_search("$bademail,$datetime", $softfails) === false) { $exists = false; for($i = 0; $i < count($softfails); $i++){ list($temp_email, $temp_dt) = explode(',', $softfails[$i]); if ($temp_email == $bademail){ $exists = true; if ($temp_dt < $datetime){ $softfails[$i] = "$bademail,$datetime"; //update date time } } } if ($exists === false){ $softfails[] = "$bademail,$datetime"; } } } else if (stripos($overview->subject, "Mail delivery failed") !== false) { echo "<li>{$overview->msgno}<ul>"; echo "<li>Sent: {$overview->date}</li><li>From: " . htmlspecialchars($overview->from) . "</li><li> Subject: {$overview->subject}</li>"; echo "<li><pre>" . htmlspecialchars(substr($body, 0, 10240)) . "</pre></li>"; echo "</ul></li>"; } else if (stripos($overview->subject, "Delivery Status Notification (Failure)") !== false) { //hotmale sends ones like this… echo "<li>{$overview->msgno}<ul>"; echo "<li>Sent: {$overview->date}</li><li>From: " . htmlspecialchars($overview->from) . "</li><li> Subject: {$overview->subject}</li>"; echo "<li><pre>" . htmlspecialchars(substr($body, 0, 10240)) . "</pre></li>"; echo "</ul></li>"; } else if (stripos($overview->subject, "Undeliverable: ") !== false) { //outlook sends ones like this… echo "<li>{$overview->msgno}<ul>"; echo "<li>Sent: {$overview->date}</li><li>From: " . htmlspecialchars($overview->from) . "</li><li> Subject: {$overview->subject}</li>"; echo "<li><pre>" . htmlspecialchars(substr($body, 0, 10240)) . "</pre></li>"; echo "</ul></li>"; } else if (stripos($overview->from, 'postmaster@') === 0) { //catch all echo "<li>{$overview->msgno}<ul>"; echo "<li>Sent: {$overview->date}</li><li>From: " . htmlspecialchars($overview->from) . "</li><li> Subject: {$overview->subject}</li>"; echo "<li><pre>" . htmlspecialchars(substr($body, 0, 10240)) . "</pre></li>"; echo "</ul></li>"; } else if (stripos($overview->from, 'Mailer-Daemon@') === 0) { //catch all echo "<li>{$overview->msgno}<ul>"; echo "<li>Sent: {$overview->date}</li><li>From: " . htmlspecialchars($overview->from) . "</li><li> Subject: {$overview->subject}</li>"; echo "<li><pre>" . htmlspecialchars(substr($body, 0, 10240)) . "</pre></li>"; echo "</ul></li>"; } } //end foreach echo "</ul>"; imap_close($mbox); } //connected ob_flush(); //NOW HAVE ARRAYS OF HARD AND SOFT FAILS, NEED TO PROCESS THEM… echo "<p>Please note: 'Email address not found' can mean two things – 1) that you have a problem because a member record could not be found, or 2) that the member has already corrected the problem. If you see just a few messages like that, it usually indicates that the member already corrected the problem.</p>"; echo "</ul><h2>".count($softfails)." Soft Fails</h2><ul>"; asort($softfails); foreach ($softfails as $fail){ list($email, $datetime) = explode(',', $fail); echo "<li>$email – "; ob_flush(); $member = \IPS\Member::load( $email, 'email' ); if( $member->member_id ) { $member->bouncerSoftBounce( $datetime ); echo "set as soft bounce. ($datetime)"; } else { echo "<b>EMAIL ADDRESS NOT FOUND</b>"; } echo "</li>"; ob_flush(); } echo "</ul>"; echo "<h2>".count($hardfails)." Hard Fails</h2><ul>"; asort($hardfails); foreach ($hardfails as $fail){ list($email, $datetime) = explode(',', $fail); echo "<li>$email – "; ob_flush(); $member = \IPS\Member::load( $email, 'email' ); if( $member->member_id ) { $member->bouncerHardBounce( $datetime ); echo "set as hard bounce. ($datetime)"; } else { echo "<b>EMAIL ADDRESS NOT FOUND</b>"; } echo "</li>"; } echo "</ul>"; if ($_GET['lb'] != 'off'){ $sql = "SELECT `email` FROM `core_members` WHERE `temp_ban` = -1 OR `temp_ban` > NOW() + INTERVAL 8 WEEK"; $results = $bzDB->exec($sql); //REPLACE THIS WITH A SQL QUERY TO YOUR IP.BOARD DATABASE echo "<h2>".count($results)." Long Bans (set as hard bounces)</h2><ul>"; foreach($results as $result){ $email = $result['email']; echo "<li>$email – "; ob_flush(); $member = \IPS\Member::load( $email, 'email' ); if( $member->member_id ) { $member->bouncerHardBounce( time() ); echo "set as hard bounce."; } else { echo "<b>EMAIL ADDRESS NOT FOUND</b>"; } echo "</li>"; } } echo "</body></html>"; ?>  
  4. Like
    jay5r reacted to stoo2000 in Bouncing Emails   
    You hit the nail on the head there. This is the primary reason why I also do not want to get into supporting manual bounce management. The dedicated email gateways do a much better job of categorising and dealing with bounces.
  5. Thanks
    jay5r got a reaction from bfarber in Bouncing Emails   
    I completed writing my routine to parse the messages in an email inbox, figure out the type of bounce, and then submit it to Mail Bouncer. I'll post the code in a few days. I want to see if I encounter any issues with it before sharing it with folks.
    It will not be a supported code and will come with no warranty. (Use at your own risk!) The error messages from mail hosts are just too unpredictable for me to want to deal with all the weird cases other people will encounter. Rather, think of it as a starting point for people with some knowledge of PHP programming – something you can tweak to suit your own needs, that means you don't have to start from scratch.
    And I should mention that it can be modified pretty easily to handle lists you may have of emails that need to be disabled.
  6. Like
    jay5r got a reaction from Maxxius in Bouncing Emails   
    I completed writing my routine to parse the messages in an email inbox, figure out the type of bounce, and then submit it to Mail Bouncer. I'll post the code in a few days. I want to see if I encounter any issues with it before sharing it with folks.
    It will not be a supported code and will come with no warranty. (Use at your own risk!) The error messages from mail hosts are just too unpredictable for me to want to deal with all the weird cases other people will encounter. Rather, think of it as a starting point for people with some knowledge of PHP programming – something you can tweak to suit your own needs, that means you don't have to start from scratch.
    And I should mention that it can be modified pretty easily to handle lists you may have of emails that need to be disabled.
  7. Like
    jay5r reacted to Dean_ in Bouncing Emails   
    Might suit some but as I said with Zapier, I refuse to pay yet another subscription to which I think could be a core feature in IPS. I’ve looked into a lot of mail services but it’s far to expensive for my needs and would be wasted on me.
    Even more so with the recent spam problem with email sharing were me and few others had over 1M emails sent... God knows how much that would’ve cost me!
  8. Like
    jay5r reacted to stoo2000 in Bouncing Emails   
    If you wanted to, you could still combine/integrate this with Mail Bouncer.
    You could do something like this...
    <?php ... your code... include '/ips4path/init.php'; \IPS\Dispatcher\External::i(); $bounce = 'hard'; $email = 'exampleemail@gmail.com'; $member = \IPS\Member::load( $email, 'email' ); /* Check it's a real account */ if( $member->member_id ) { if( $bounce == 'hard' ) { $member->bouncerHardBounce( time() ); //or use the time from the bounce itself } elseif ( $bounce == 'soft' ) { $member->bouncerSoftBounce( time() ); //or use the time from the bounce itself } elseif( $bounce == 'spam' ) { $member->bouncerSpam( time() ); //or use the time from the bounce itself } } Alternatively, if you're processing a lot of bounces at the same time (i.e. a periodic sweep of a mailbox) you can queue the bounces instead and let the app process them in the background.
    <?php .... your code include '/ips4path/init.php'; \IPS\Dispatcher\External::i(); foreach( $bounces as $bounce ) { /* Create Bounce */ $bounce = new \IPS\bouncer\Bounce; $bounce->email = $event['email']; $bounce->classification = $bounce['type']; // 'hard', 'soft', 'spam' $bounce->reason = $bounce['reason']; $bounce->timestamp = $bounce['timestamp']; $bounce->save(); } /* Queue the process */ \IPS\Task::queue( 'bouncer', 'ProcessBounces', array( 'class' => 'placeholder' ), 5, array('class') );  
  9. Like
    jay5r reacted to Maxxius in Bouncing Emails   
    I was asking myself the same thing 🙂
  10. Like
    jay5r reacted to Dean_ in Bouncing Emails   
    Why is something like this not part of IPS, is there no way of having this within the software if it detects a bounce back and setting that member accordingly?
  11. Like
    jay5r got a reaction from Maxxius in Bouncing Emails   
    Unless someone comes up with a better idea, here's what I'm thinking of doing…
    Writing something in PHP to scan the email inbox that receives the bounce notifications. I'll use key phrases in the email to determine if it's a case of a invalid email address or a full mailbox. For now I'll ignore the ones that are basically "we don't like you".
    I'll then make a SQL connection to my IP.Board database and modify the email address. I'll append ".hf"  to the hard fails (invalid email address), and .YYYYMMDD.sf to the ones where their mailbox is full.
    IP.Board will still attempt to send the email, but it will fail. But it will fail in a way that won't bother legit email servers. That will preserve my reputation with those email providers.
    The YYYYMMDD in the soft fails will indicate the date of the last failure. I can then write a routine that will go through and search for all the ".sf" email addresses, and if they're more than a week old, I'll strip off the .YYYYMMDD.sf which will let mail be sent to them again. If their mailbox is still full, then the process repeats itself.
    I'll also (try to) write a Javascript that I'll include on each page that inserts a warning banner at the top of the page if the user's email ends in .hf or .sf warning them that action is needed on their part.
    But seriously, Invision should make this an easier process. It's a bit ridiculous that we can't just specify a list of email addresses that need their emails turned off (except for validation emails).
×
×
  • Create New...