Search code examples
pythondjangodjango-templatesdjango-email

Creating a unsubscribe link while sending a mass email


I have a app that is going to be sending out thousands of emails. My original plan was to iterate over each record and send out one email out a time andcreate the unsubscribe link from a UUID of the record. To speed up sending out the emails I instead used EmailMultiAlternative and get_connection() to only have to build one context

 email = EmailMultiAlternatives()                           
 email.subject = email_script.subject                       
 email.from_email = DEFAULT_FROM_EMAIL                      
 template = get_template('email/email_blast_template.html') 
 ......
 body = template.render(context)                     
 connection = get_connection()                       
 connection.open()                                   
 email.bcc = list(recipients)                        
 email.body = body                                   
 email.attach_alternative(body, "text/html")         
 email.connection = connection                       
 email.send()                                        
 connection.close()   

Is there anyway I could access the email address for each email being sent so I can build a unsubscribe link? Is there information stored in request.META? I'm having some trouble seeing what is in there.

If you wish to unsubscribe click <a href={% url unsubscribe email.uuid }}>here</a>

Solution

  • I don’t see how what you’re referring to would be possible. The email you’re generating in your sample code cannot be customized per recipient as it is a single email (i.e., you are not generating unique content per recipient). The only solution I see is to create individual emails per recipient as you suggested initially.

    To do that, you could open and close the connection only once, and even render the template once, but use a loop to actually prepare and deliver the messages. This should still be more efficient than regenerating content and/or reopening connections for each message. For example:

    template = get_template('email/email_blast_template.html')
    body = template.render(context)
    
    connection = get_connection()                       
    connection.open()                                   
    
    for recipient in recipients:
        email = EmailMultiAlternatives()                           
        email.subject = email_script.subject                       
        email.from_email = DEFAULT_FROM_EMAIL                      
        email.bcc = recipient
        email.body = body.replace('{email}', recipient)
        email.attach_alternative(body.replace('{email}', recipient), "text/html")         
        email.connection = connection                       
        email.send()                                        
    
    connection.close()   
    

    Using the code above, your body template would then just need to include the “template” tag in the unsubscription link (“{email}” in the example). The example also uses the actual email address, but you could generate a unique identifier based on it if you prefer.