Search code examples
phpforeachphpmailerunsubscribe

how to send an unsubscribe link with an unique id to the recipients with phpmailer


I am using phpmailer to send a newsletter to some subscribers. Each subscriber is part of a "Category". Before sending, i first choose the category which the subscribers belong. Each user has a unique id called $recipients_id . What happens: In the code below, each user gets all the "unscribe links"; so also of the other members. And he/she should only receive the unsubscribe with his/her own id:

// part of the script
$mail->IsHTML(true);                            //Sets message type to HTML             
$mail->Subject = "Newsletter";                  //Sets the Subject of the message
$mail->Body = $_POST["message"];
foreach($category_matches as $file) { // grab subscribers of the category
    // get data out of txt file     
    $lines = file($file, FILE_IGNORE_NEW_LINES); // set lines from matched file into an array
    $recipients_id = $lines[0]; //  id of recipients
    $recipients_name = $lines[2]; //  name of recipients
    $recipients_email = $lines[3]; //  email of the recipients                                  
    $mail->AddBCC($recipients_email, $recipients_name); //bcc to all subscribers of the category
    $mail->Body .= '<a href="http://example.com/newsletter/unsubscribe.php?id='.$recipients_id.'">Unsubscribe</a>'; //unsubscribe anchor    

    echo $recipients_id.'<br />'; // this echos me the id's of the subscribers in the category to check only 


}

if($mail->Send())           //Send an Email. Return true on success or false on error
{
    $result = '<div class="alert alert-success">Newsletter sent to subscribers of:<b> '.$recipients_category.'</b></div>';
}
else
{
    $result = 'div class="alert alert-danger">There is an Error</div>';
}

Solution

  • According to the comments above, your code should be something like this:

    // part of the script
    $mail->IsHTML(true);                            //Sets message type to HTML             
    $mail->Subject = "Newsletter";                  //Sets the Subject of the message
    foreach($category_matches as $file) { // grab subscribers of the category
        // get data out of txt file     
        $lines = file($file, FILE_IGNORE_NEW_LINES); // set lines from matched file into an array
        $recipients_id = $lines[0]; //  name of recipients
        $recipients_name = $lines[2]; //  name of recipients
        $recipients_email = $lines[3]; //  email of the recipients                              
        $mail->AddAddress($recipients_email, $recipients_name);     //Adds a "To" address
    
        try {
            $mail->Body = $_POST["message"].'<br /><br />'.'<a href="http://example.com/newsletter/unsubscribe.php?id='.$recipients_id.'">Unsubscribe</a>'; //unsubscribe anchor
            $mail->Send();  
            $result = '<div class="alert alert-success">Newsletter sent to subscribers of:<b> '.$recipients_category.'</b></div>';                  
    
        } catch (Exception $e) {
            $result = '<div class="alert alert-success">Mailer Error (' . htmlspecialchars($recipients_email) . ') ' . $mail->ErrorInfo . '</div>';
            $mail->smtp->reset(); // reset SMTP connection
        }
    
        $mail->clearAddresses(); // Clear all addresses for the next iteration
    
    }
    

    NOTE: there is only 1 $mail->Body, which includes the message and the unique_id link for unsubscribing. Bind the echo's to a var $result and echo $result outside the loop; otherwise you will get them several times, for each recipient you send