Metadata-Version: 2.4
Name: bulk-email-sender
Version: 0.2.1
Summary: A modular, state-persisting mass email sender library using SMTP — supports multi-account rotation, daily limits, and attachments
Author-email: Jeferson Oliveira Madeira <jeffoliveira977@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/jeffoliveira977/Bulk-email-sender
Project-URL: Repository, https://github.com/jeffoliveira977/Bulk-email-sender
Project-URL: Issues, https://github.com/jeffoliveira977/Bulk-email-sender/issues
Project-URL: Changelog, https://github.com/jeffoliveira977/Bulk-email-sender/releases
Keywords: email,smtp,bulk,sender,automation,newsletter,mass-email
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: End Users/Desktop
Classifier: Topic :: Communications :: Email
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Operating System :: OS Independent
Classifier: Natural Language :: English
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# Bulk Email Sender

[![PyPI version](https://img.shields.io/pypi/v/bulk-email-sender?color=blue)](https://pypi.org/project/bulk-email-sender/)
[![Python](https://img.shields.io/pypi/pyversions/bulk-email-sender)](https://pypi.org/project/bulk-email-sender/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

A modular, robust, and state-persisting mass email sender library for Python. It supports multiple sender accounts with round-robin rotation, personalized recipient names, automatic daily safety caps, cooldown intervals between emails, attachments, and automatic daily counter resets.

---

## Quick Start

```bash
# 1. Install
pip install bulk-email-sender

# 2. Initialise workspace — creates a config.json template in the current directory
bulk-email-sender

# 3. Edit config.json with your credentials, leads file, subject, body, etc.

# 4. Run the campaign
bulk-email-sender

# 5. (Optional) Reset progress state and start over
bulk-email-sender --reset
```

You can also run the package directly as a Python module:

```bash
python -m bulk_email_sender [--reset]
```

Or import and drive it programmatically:

```python
from bulk_email_sender import BulkEmailSender

config = {
    "provider": "gmail",
    "senders": [{"email": "you@gmail.com", "password": "app-password", "name": "You"}],
    "leads_path": "leads.txt",
    "subject": "Hello!",
    "body_path": "body.txt",
    "attachment_path": "resume.pdf",   # optional
    "interval_seconds": 60,
    "daily_limit": 450,
}

BulkEmailSender(config).run()
```



## Configuration

Configurations are loaded from `config.json` in the root workspace.

### Example `config.json`

```json
{
  "provider": "gmail",
  "senders": [
    {
      "email": "sender1@gmail.com",
      "password": "app-password-1",
      "name": "Marcos (Account 1)"
    },
    {
      "email": "sender2@yahoo.com",
      "password": "app-password-2",
      "name": "Marcos (Account 2)",
      "provider": "yahoo"
    }
  ],
  "leads_path": "leads.txt",
  "subject": "Your Subject Here",
  "body_path": "body.txt",
  "attachment_path": "document.pdf",
  "interval_seconds": 60,
  "daily_limit": 450
}
```

*Note: Environment variables `GMAIL_SENDER` and `GMAIL_APP_PASSWORD` will override `"senders"` in the configuration on execution if they are set.*

---

## Per-Sender Provider Overrides

Individually configured senders in the `"senders"` list can override the global campaign provider by defining their own `"provider"`, `"smtp_host"`, or `"smtp_port"` keys. 

If a sender specifies a provider override, the library automatically closes the active connection and establishes a session with the correct hostname/port for the new provider.

### SMTP Providers Presets

Built-in presets automatically configure the host and port depending on your chosen `"provider"`:

| Provider Name | Default Host | Port |
| :--- | :--- | :--- |
| `"gmail"` | `smtp.gmail.com` | `587` |
| `"yahoo"` | `smtp.mail.yahoo.com` | `587` |
| `"icloud"` | `smtp.mail.me.com` | `587` |
| `"ZOHO"` | `smtp.zoho.com` | `587` |
| `"GMX"` | `smtp.gmx.com` | `587` |
| `"YANDEX"` | `smtp.yandex.com` | `587` |
| `"AOL"` | `smtp.aol.com` | `587` |
---

## Round-Robin Account Rotation

The library automatically rotates through the configured accounts in `"senders"` round-robin style (1st email from account 1, 2nd email from account 2, 3rd from account 1, etc.).

If a new account is chosen in the rotation, the SMTP connection automatically disconnects and re-establishes session credentials to make sending look natural and stay within safety boundaries.

---

## Customizing Email Body

The email body is loaded dynamically from the file specified in the `"body_path"` key (default: `body.txt`). 
Any newlines (`\n`) in `body.txt` are automatically converted to HTML line break tags (`<br>`) before sending.

### Example `body.txt`

```text
I hope this message finds you well.

I am writing to express my interest in potential job opportunities in IT. Please find attached my curriculum vitae for your consideration.

Thank you for your time and review.
```

---

## Email Attachments (Optional)

An optional file attachment can be sent with every email by configuring the `"attachment_path"` key in `config.json`.

*   **Supported Formats:** Any file type (e.g., `.pdf`, `.docx`, `.xlsx`, `.zip`). The sender automatically encodes and attaches it using standard MIME Base64 encoding.
*   **Size Limit Validation:** The program checks the file size before starting the campaign. If the attachment exceeds the **25 MB limit**, the campaign is aborted to prevent failures.
*   **Missing Files:** If the specified file does not exist, the campaign will abort immediately with an error log.
*   **No Attachment:** If you do not want to send an attachment, simply leave `"attachment_path": ""` as an empty string or omit it.

---

## Auto-Generated Files

The following files are generated automatically in the execution directory and do not need to be configured:
*   `email_state.json`: Tracks campaign progress, daily counts, and failed indexes. Allows resuming if interrupted.
*   `email_sender.log`: Logs sending statuses, warnings, and errors.

---

## Defining Recipient Leads (TXT or CSV)

### 1. Plain Text Format (`.txt`)
Name and email separated by a comma (`,`) or semicolon (`;`). The name is optional:

```text
another-recipient@example.com      # Generic greeting: "Hello,"
Jane Doe; jane.doe@example.com     # Personalised greeting: "Hello Jane Doe,"
```

### 2. CSV Format (`.csv`)
Requires an `email` column, and optional `name` column:

```csv
name,email
Jane,jane.doe@gmail.com
,another-recipient@example.com
```

If the name is missing, it defaults to a generic `"Hello,"` greeting.

---
