This is a quick script to process email bounces, for example from a mailing list so that users can be flagged up or unsubscribed when they have too many failures.
The actual bounce identification will be done by Chris Fortune’s Bounce Handler, which you can download from:
http://anti-spam-man.com/php_bouncehandler/
We require 3 files from that package:
bounce_driver.class.php
bounce_responses.php
rfc1893.error.codes.php
What this script does is get the bounced emails from a specified mailbox and counts up how many failed emails there are per email address – if the number is at least as many as your threshold value (called $delete), then (you insert your code to unsubscribe the email address or whatever etc. and) the bounced emails are then deleted. You can run the script as a cronjob or call from your mailing list script to tidy up subscriptions.
<?php
# define variables
$mail_box = '{mail.domain.com:143/novalidate-cert}'; //imap example
$mail_user = 'username'; //mail username
$mail_pass = 'password'; //mail password
$delete = '5'; //deletes emails with at least this number of failures
# connect to mailbox
$conn = imap_open ($mail_box, $mail_user, $mail_pass) or die(imap_last_error());
$num_msgs = imap_num_msg($conn);
# start bounce class
require_once('bounce_driver.class.php');
$bouncehandler = new Bouncehandler();
# get the failures
$email_addresses = array();
$delete_addresses = array();
for ($n=1;$n<=$num_msgs;$n++) {
$bounce = imap_fetchheader($conn, $n).imap_body($conn, $n); //entire message
$multiArray = $bouncehandler->get_the_facts($bounce);
if (!empty($multiArray[0]['action']) && !empty($multiArray[0]['status']) && !empty($multiArray[0]['recipient']) ) {
if ($multiArray[0]['action']=='failed') {
$email_addresses[$multiArray[0]['recipient']]++; //increment number of failures
$delete_addresses[$multiArray[0]['recipient']][] = $n; //add message to delete array
} //if delivery failed
} //if passed parsing as bounce
} //for loop
# process the failures
foreach ($email_addresses as $key => $value) { //trim($key) is email address, $value is number of failures
if ($value>=$delete) {
/*
do whatever you need to do here, e.g. unsubscribe email address
*/
# mark for deletion
foreach ($delete_addresses[$key] as $delnum) imap_delete($conn, $delnum);
} //if failed more than $delete times
} //foreach
# delete messages
imap_expunge($conn);
# close
imap_close($conn);
?>
Works, thanks.
Regards from México.
Works fine, I look for a script like this.
Thanks
Regards from Holland
This line saved my life:
$bounce = imap_fetchheader($conn, $n).imap_body($conn, $n); //entire message
Thanks for your good work
My pleasure 🙂
Your bounce checker works great, but I’ve come up stuck on one thing. If I send out a bulk mailing with multiple people on a BCC (as opposed to separate emails), I get a single reply back with all of the failed addresses, and the class doesn’t parse them. Any ideas on how I’d go about pulling the multiple addresses out? The answer may be to move away from BCC’ing multiple recipients to ensure a single address per bounce notification, but I figured it was worth throwing the question out there.
Here’s an example:
A message that you sent could not be delivered to one or more of its recipients. This is a permanent error. The following address(es) failed:
dsaflh@mydomain.com
(generated from dsaflh@mydomain.com)
No such person at this address
347234jsldfkj@mydomain.com
(generated from 347234jsldfkj@mydomain.com)
No such person at this address
sljsdkf@mydomain.com
No such person at this address
aasdlkj2@mydomain.com
No such person at this address
Hi, I didn’t write the class myself, but you could
explode()
the recipient section using carriage returns and then parse each exploded line as a potential email into a separate iteration of the handler… make sense? 🙂Dude, *exactly* what l needed! Thank you so much!
Worked perfectly for me just as written. Thanks!!
Pingback: PHP - dealing with bounced mails » Wegeberg
Works perfectly, thanks. Any idea how I can extend this to get additional headers out of the email – I need to get ‘Return-Path’ for example.
The plugin is written specifically to identify bounces – your best bet would be to parse the email for a return-path header after the entire message is read into the $bounce variable – so do a preg_match(‘/return-path.+\n|\r/’, $bounce) or something (that expression’s totally untested!).
Ah! so this is how to check for the bounces!
been looking for this script.. been wondering for a long time how those software do it.
Thanks!
Will it work for POP
Really a lifesaver! The spam can continue
I get the following error:
Warning: iconv_mime_decode() [function.iconv-mime-decode]: Malformed string in xxx/xxx/xxx/bounce_driver.class.php on line 454
Line 454 is:
$hash[‘Subject’] = iconv_mime_decode($hash[‘Subject’], 0, “ISO-8859-1”);
I have played around with it but can’t seem to fix the problem. Has anyone else ran into this error or know how to fix it?
Great Code, would like to know, what is the optimal value used to eliminate email bounce.
$ delete = ‘5 ‘
I have read this article
https://www.mailjet.com/support/what-is-an-acceptable-bounce-rate, 76.htm
And I believe that maximum 3 emails bounce is the best. What do you think?
Thanks for sharing
Thanks dude! After 2 days of searching how to get the list of problem mails. Saves me!
Hi, does anyone have the required files?
bounce_driver.class.php
bounce_responses.php
rfc1893.error.codes.php
The link is dead. =(
Hi, I would need the script too.
Anyone has it?
Thanks,
Francisco
Andree, the new link is here:
https://github.com/shepik/PHP-Bounce-Handler
https://github.com/cfortune/PHP-Bounce-Handler
https://github.com/cfortune/PHP-Bounce-Handler
Andree:
https://github.com/cfortune/PHP-Bounce-Handler
Pingback: Answer for Bounce inactive emails from php newsletter - Tech Magazine