Skip to content

Repository files navigation

Bulk Emailer

A Python bulk email sender with a web UI. Upload a CSV, Excel, or PDF file, write a personalized email template, and send to hundreds of recipients via Gmail SMTP — with rate limiting, resume-on-failure, and a live log stream.

Features

  • Web UI — browser-based dashboard to configure, compose, and send without touching the terminal
  • Personalized templates — use {{Name}}, {{Email}}, or any column heading as a placeholder; each recipient gets their own personalized email
  • Multi-format input — reads recipients from .xlsx, .csv, or .pdf
  • Resume on failure — tracks sent addresses; re-running skips already-sent ones
  • Rate limiting — configurable per-email delay and batch pauses to stay within Gmail limits
  • Dry-run mode — preview the recipient list without sending
  • Live log stream — watch sending progress in real time in the browser
  • Run history — view logs from previous runs inside the UI

Requirements

  • Python 3.8+
  • A Gmail account with an App Password (requires 2FA to be enabled)

Installation

pip install -r requirements.txt

Installs: flask, openpyxl, pdfplumber

Quick Start (Web UI)

1. Start the server:

python app.py

2. Open your browser:

http://localhost:5000

3. Configure SMTP — go to the Configure tab and fill in:

  • Host: smtp.gmail.com
  • Port: 465
  • Your Gmail address and 16-character App Password

4. Write your template — go to the Template tab. Upload your file first in the Send tab to see column buttons appear — click any column button to insert {{ColumnName}} at your cursor.

5. Send — go to the Send tab, upload your file, choose options, and click Start Sending.

Web UI Tabs

Tab What it does
Dashboard Sent/failed counts, list of all tracked addresses, reset button
Configure Edit SMTP settings and rate limiting — saved to config.json
Template Write your email body with column placeholders, saved to email_template.txt
Send Upload file, choose dry-run/reset options, start sending with live log output
History View the last 5 run log files

Personalized Templates

Column headings from your file become placeholders. For a file with columns Name, Email, Company:

Hello {{Name}},

We'd love to connect with you at {{Company}}.

Best regards,
Your Name

Each recipient receives their own version with real values filled in. Unknown placeholders are silently removed. Placeholders are case-insensitive ({{name}} = {{Name}}).

CLI Usage (no UI)

# Create default config and template
python bulk_emailer.py --init

# Preview recipients without sending
python bulk_emailer.py contacts.csv --dry-run

# Send emails
python bulk_emailer.py contacts.xlsx

# Use a custom config file
python bulk_emailer.py contacts.csv --config office.json

# Clear sent history and resend to everyone
python bulk_emailer.py contacts.csv --reset

CLI Arguments

Argument Description
file .xlsx, .csv, or .pdf file with email addresses
--config <path> Config file (default: config.json)
--dry-run List recipients without sending
--reset Clear sent_emails.txt and failed_emails.txt
--init Scaffold config.json and email_template.txt

SMTP Configuration

Gmail SSL (recommended)

"smtp_host": "smtp.gmail.com",
"smtp_port": 465,
"use_ssl": true

Gmail STARTTLS

"smtp_host": "smtp.gmail.com",
"smtp_port": 587,
"use_ssl": false

App Password: Go to myaccount.google.com/apppasswords → generate a password for "Mail". Use that 16-character password, not your regular Gmail password.

Rate Limiting

Setting Default Purpose
delay_seconds 2 Wait between each email
batch_size 40 Emails per batch
batch_pause_seconds 60 Pause between batches

Recommended safe settings (avoids Gmail bans):

Risk level delay batch_size batch_pause
Safest 10s 20 300s
Safe 5s 25 180s
Default 2s 40 60s

Gmail limits: ~500 emails/day (free), ~2,000/day (Workspace). Never exceed ~20 emails/minute.

Output Files

File Description
sent_emails.txt Every successfully sent address (one per line)
failed_emails.txt Rejected or errored addresses
run_YYYYMMDD_HHMMSS.log Full timestamped log per run
uploads/ Uploaded recipient files (via web UI)

Supported File Formats

Format Notes
.csv First row used as column headers for template variables
.xlsx First row of each sheet used as headers
.xls Same as .xlsx
.pdf Emails extracted by regex; no column support (no personalization)

Project Structure

bulk_emailer/
├── app.py                  # Flask web server
├── bulk_emailer.py         # Core send logic (also usable as CLI)
├── config.json             # SMTP credentials and settings
├── email_template.txt      # Email body template
├── requirements.txt        # Python dependencies
├── templates/
│   └── index.html          # Single-page web UI
└── uploads/                # Uploaded recipient files (auto-created)

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages