create a bulk email sender using free SMTP services like Gmail

Each service (Gmail, Outlook, Yahoo) has different SMTP settings—host, port, TLS/SSL requirements. So I should create a list of these configurations. Also, to rotate them, maybe round-robin style, each email uses the next SMTP server in the list.

Feb 4, 2025 - 12:52
Feb 4, 2025 - 12:54
 0  21
create a bulk email sender using free SMTP services like Gmail

Next, the subject lines and templates need to rotate. Maybe have a list of subjects and a list of template files. For each email, pick the next subject and template. But I should make sure that if there are more emails than subjects or templates, it loops back to the start.

I'll need to read the templates from files. Each template can have placeholders for the recipient's name or other details. Using Python's string formatting could work here, like using {name} in the template and replacing it with actual data.

For sending emails, I'll use smtplib. Each SMTP server might require logging in with a username and password. Wait, but free SMTP services usually require authentication, so each SMTP configuration needs an email and password. But the user might not want to hardcode these. Maybe they should be stored in a config file or environment variables. Oh, but the example code might just have them in variables for simplicity, with a note to secure them properly.

Handling multiple recipients: the script should read a CSV file with recipient emails, names, etc. Using the csv module in Python makes sense here. Then iterate over each row, assign the next subject, template, and SMTP server.

Error handling is important. If one SMTP server fails, maybe catch exceptions and try the next one. Also, rate limiting to avoid being flagged as spam. Maybe add delays between emails.

Rotational logic: using itertools.cycle could help cycle through the lists infinitely. So for each email, next(subjects), next(templates), next(smtp_servers).

Putting it all together:

1. Read SMTP configurations from a list of dictionaries.

2. Read subjects from a list.

3. Read templates from files in a directory.

4. Read recipients from a CSV.

5. For each recipient, select the next subject, template, SMTP server.

6. Render the template with recipient's data.

7. Send the email using the selected SMTP.

8. Handle exceptions and add delays.

Wait, but using multiple SMTP accounts might require multiple logins. Each time we switch SMTP server, we need to login with that account's credentials. So in the loop, for each email, connect to the SMTP server, login, send, then quit. But logging in each time might be slow, but with rotation, it's necessary.

Also, Gmail has limits on daily emails. So rotating different accounts could help spread the load.

Testing is important. Maybe start with a small list and test emails to myself to ensure it works.

Potential issues: SMTP servers blocking the connection if too many emails are sent quickly. So adding a delay between emails, like 1-2 seconds, might help.

Now, structuring the code:

- Import necessary modules: smtplib, csv, email modules, os, itertools, time.

- Define SMTP configurations, subjects, template directory, recipient CSV.

- Read templates from files into a list.

- Use cycle() on SMTP configs, subjects, templates.

- Read recipients from CSV.

- Iterate over each recipient, get next subject, template, SMTP.

- Render the template with recipient data.

- Create MIMEText or MIMEMultipart message.

- Connect to SMTP server, login, send, quit.

- Add try-except blocks around sending to handle errors.

- Add a delay between sends.

Wait, templates can be HTML or plain text. Maybe handle both. For simplicity, maybe assume plain text, but using MIMEText.

Another thing: some SMTP servers require TLS. So in the code, when connecting, check if TLS is needed and starttls() accordingly.

Also, the From header should match the email used to login, otherwise, the server might reject it.

So in the code, when creating the email message, set the From header to the current SMTP config's email.

Testing each step: maybe start with one SMTP account, one template, one subject, and a test recipient.

Security note: Storing email passwords in plain text is bad. The code should warn users about using app-specific passwords and not to hardcode real passwords.

Now, putting all this into code.

Here's a Python script for a bulk email sender with rotational SMTP, subject lines, and templates:

import smtplib
import csv
import os
import time
import random
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from itertools import cycle
from string import Template

# Configuration
SMTP_CONFIGS = [
    {  # Gmail
        "server": "smtp.gmail.com",
        "port": 587,
        "username": "your_email@gmail.com",
        "password": "your_app_specific_password",
        "tls": True
    },
    {  # Outlook
        "server": "smtp.office365.com",
        "port": 587,
        "username": "your_email@outlook.com",
        "password": "your_password",
        "tls": True
    },
    # Add more SMTP configurations as needed
]

SUBJECTS = [
    "Important Update!",
    "New Information Available",
    "Weekly Newsletter",
    "Special Announcement"
]

TEMPLATE_DIR = "email_templates"
RECIPIENTS_FILE = "recipients.csv"
DELAY_BETWEEN_EMAILS = 2  # seconds

def load_templates():
    templates = []
    for filename in os.listdir(TEMPLATE_DIR):
        with open(os.path.join(TEMPLATE_DIR, filename), 'r') as f:
            templates.append(Template(f.read()))
    return templates

def send_email(smtp_config, recipient, subject, body):
    msg = MIMEMultipart()
    msg['From'] = smtp_config['username']
    msg['To'] = recipient['email']
    msg['Subject'] = subject
    
    msg.attach(MIMEText(body, 'html' if '' in body else 'plain'))
    
    try:
        with smtplib.SMTP(smtp_config['server'], smtp_config['port']) as server:
            if smtp_config.get('tls', False):
                server.starttls()
            server.login(smtp_config['username'], smtp_config['password'])
            server.send_message(msg)
            print(f"Email sent to {recipient['email']} via {smtp_config['server']}")
        return True
    except Exception as e:
        print(f"Error sending to {recipient['email']}: {str(e)}")
        return False

def main():
    # Load components
    templates = load_templates()
    recipients = []
    
    with open(RECIPIENTS_FILE, 'r') as f:
        reader = csv.DictReader(f)
        for row in reader:
            recipients.append(row)
    
    # Create cyclers
    smtp_cycler = cycle(SMTP_CONFIGS)
    subject_cycler = cycle(SUBJECTS)
    template_cycler = cycle(templates)
    
    for recipient in recipients:
        smtp_config = next(smtp_cycler)
        subject = next(subject_cycler)
        template = next(template_cycler)
        
        # Personalize email
        body = template.safe_substitute(**recipient)
        
        # Send email
        success = send_email(smtp_config, recipient, subject, body)
        
        # Rotate SMTP only on failure
        if not success:
            smtp_config = next(smtp_cycler)
        
        time.sleep(DELAY_BETWEEN_EMAILS)

if __name__ == "__main__":
    main()

Setup Instructions:

  1. Create these directories/files:

project/
├── email_templates/
│   ├── template1.html
│   └── template2.txt
├── recipients.csv
└── email_sender.py

Email Templates:

  • Create template files in email_templates directory

  • Use placeholders like $name, $email in templates

  • Example template (template1.html):


    
        

Hello $name!


        

Thank you for subscribing!


    

Recipients CSV:

email,name,other_fields
john@example.com,John Doe
jane@example.com,Jane Smith
  1. SMTP Configuration:

    • Use app-specific passwords for Gmail

    • Enable less secure apps for other providers (not recommended)

    • Add more SMTP configurations as needed

Features:

  • Rotates through multiple SMTP servers

  • Cycles through different email subjects

  • Uses different email templates

  • Personalizes emails with recipient data

  • Includes safety delays between emails

  • Handles email sending failures

Security Notes:

  1. Never commit actual credentials to version control

  2. Use environment variables for production credentials

  3. Consider using encryption for sensitive data

  4. Follow anti-spam regulations (CAN-SPAM Act, GDPR)

  5. Respect email service providers' sending limits

Important Considerations:

  • Free SMTP services have daily sending limits

  • Sending bulk emails might trigger spam filters

  • Maintain proper email list hygiene

  • Provide unsubscribe links in your templates

  • Test thoroughly with small batches before full deployment

To Improve:

  • Add attachment support

  • Implement proper error logging

  • Add unsubscribe management

  • Include email tracking

  • Add success/failure statistics

  • Implement proper threading/pooling

Remember to test with small batches and verify delivery before scaling up. Always comply with anti-spam laws and email service provider policies.

What's Your Reaction?

like

dislike

love

funny

angry

sad

wow