Ghazanfar Mir
Ghazanfar Mir

Reputation: 3543

PHPMailer: Error handing with BCC

I couldn't find the answer to my specific scenario.

I am developing a system to send out publication to a mailing list from database. I have managed to do it using normal loop code.

However, I want to use loop only to add recipients using BCC and also maintain error handling if anyone has missed it something like:

foreach($array as $user){
    $mail->AddBCC( $user['email'], $user['customerName']);
}

try{
    $mail->AltBody    = "To view the message, please use an HTML compatible email viewer!"; // optional, comment
    $mail->AddReplyTo("[email protected]","Company Name");
    $mail->SetFrom('[email protected]', 'Company Name');
    $mail->Subject    = "Company| E-Zine";
    $mail->MsgHTML($ezineContent);              

if(!$mail->Send()) {

    //show error msg

} else {

   //show successful msg
}


}catch (phpmailerException $e) {

     //show error msg

}catch (Exception $e) {

     //show error msg
}

$mail->ClearAddresses();

Then I want to send the e-mail to all recipients added above using one call.

Is it possible to do error handling and find if anyone hasn't received it because the address wasn't correct??

Upvotes: 0

Views: 1075

Answers (1)

Jens Bradler
Jens Bradler

Reputation: 1497

A common practice of tracking the success of mailing operations is to use the "Return-Path" header of an email.

Example of an email and its header:

Return-Path: [email protected]
Received: from localhost (mx-1-1 [127.0.0.1])
    by mx-1.xyz.com (Postfix) with ESMTP id 3F81556754
    for <[email protected]>; Wed,  2 May 2012 12:27:18 +0200 (CEST)
To: [email protected]
Subject: test mailing
From: Jens <[email protected]>
Message-Id: <[email protected]>
Date: Wed,  2 May 2012 12:27:17 +0200 (CEST)

Hi Folks, ...

Whereby the "From" header is your choice of real name and email address that you want the reader to see, the primary purpose of the "Return-Path" is to designate the address to which messages indicating non-delivery or other mail system failures are to be sent ([see RFC 2821 for more details][1]).

So basically this header is the right position to start fetching non-delivery reports.

How I would do this:

  1. create a unique subdomain to fetch all non-delivery reports (e.g. return.xyz.com)
  2. set-up a inbox to catch all emails sent to the above subdomain (regardless of the local part of the email address, e.g. *@return.xyz.com)
  3. make emails unique => one recipient one unique email (no use of BCC)
  4. use recipient id (e.g. numeric id of your recipient data base) and email or campaign id to generate the local part of the future (e.g. {campaign_id}-{recipient_id})
  5. use new Return-Path: Return-Path: {campaign_id}-{recipient_id}@return.xyz.com
  6. create some tools to fetch incoming mail and filter out real non-delivery reports from SPAM and temporary notifications (e.g. out-of-office messages)

Here an example with a unique Return-Path:

Return-Path: [email protected]
Received: from localhost (mx-1-1 [127.0.0.1])
    by mx-1.xyz.com (Postfix) with ESMTP id 3F81556754
    for <[email protected]>; Wed,  2 May 2012 12:27:18 +0200 (CEST)
To: [email protected]
Subject: test mailing
From: Jens <[email protected]>
Message-Id: <[email protected]>
Date: Wed,  2 May 2012 12:27:17 +0200 (CEST)

Hi Folks, ...

That's it.

Edit - How to implement that via phpMailer:

/* define domain name for non-delivery reports */
define('RETURN_PATH_DOMAIN', 'return.xyz.com');

/* get current campaign id */
$campaignId = 123;

/* loop recipient list and send email */
foreach ($array as $userId => $user) {
  try{
    $mail = new PHPMailer();
    $mail->HeaderLine('Return-Path', $userId . '-' $campaignId . '@' . RETURN_PATH_DOMAIN);
    $mail->To($user['email'], $user['customerName']);
    $mail->AltBody = "To view the message, please use an HTML compatible email viewer!"; 
    $mail->AddReplyTo("[email protected]","Company Name");
    $mail->SetFrom('[email protected]', 'Company Name');
    $mail->Subject = "Company| E-Zine";
    $mail->MsgHTML($ezineContent);         
    if(!$mail->Send()) {
      // show log
    } else {
      //show successful msg
    }
  } catch (Exception $e) {
    // show error
  }
}

As far as I remember we had problems by using the local sendmail. The header Return-Path was replaced by some configurations of the local MTA. If this is the case try to use SMTP to a usable relay host instead.

Upvotes: 5

Related Questions