{"id":27261461,"url":"https://github.com/supratimrk/web-bulk-email-sender","last_synced_at":"2025-10-24T11:04:58.590Z","repository":{"id":287236761,"uuid":"964049146","full_name":"SupratimRK/web-bulk-email-sender","owner":"SupratimRK","description":"✉️ Bulk Email Sender Web UI A clean, modern Flask app to send beautiful bulk or manual emails using CSV or custom inputs. Upload templates or draft your own, preview live, attach files, and blast away — no code changes needed. Fast, flexible, and actually fun to use!","archived":false,"fork":false,"pushed_at":"2025-04-10T16:49:23.000Z","size":62,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-10T18:09:12.038Z","etag":null,"topics":["automailer","begginer-friendly","bulk-email","bulk-email-sender","custom-templates","dynamic-email-send","email-automation","email-ui","flask-app","html-email","python","send-email-with-attachment","smtp-client","web-utility"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SupratimRK.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-04-10T15:58:18.000Z","updated_at":"2025-04-10T16:49:26.000Z","dependencies_parsed_at":"2025-04-10T18:09:16.892Z","dependency_job_id":"a1121029-3b91-4203-b0b3-efe61df20489","html_url":"https://github.com/SupratimRK/web-bulk-email-sender","commit_stats":null,"previous_names":["supratimrk/web-bulk-email-sender"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SupratimRK%2Fweb-bulk-email-sender","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SupratimRK%2Fweb-bulk-email-sender/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SupratimRK%2Fweb-bulk-email-sender/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SupratimRK%2Fweb-bulk-email-sender/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SupratimRK","download_url":"https://codeload.github.com/SupratimRK/web-bulk-email-sender/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248347783,"owners_count":21088743,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automailer","begginer-friendly","bulk-email","bulk-email-sender","custom-templates","dynamic-email-send","email-automation","email-ui","flask-app","html-email","python","send-email-with-attachment","smtp-client","web-utility"],"created_at":"2025-04-11T05:32:11.845Z","updated_at":"2025-10-24T11:04:58.584Z","avatar_url":"https://github.com/SupratimRK.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 📬 Bulk Email Sender Web UI\n\nA sleek, modern, and feature-rich web UI for sending personalized emails, either individually or in bulk. Perfect for newsletters, notifications, marketing campaigns, or any scenario requiring customized email distribution. Users can **upload HTML/Markdown/Text templates** or **craft emails directly** using a powerful rich-text editor with an HTML source view.\n\nBuilt with **Flask**, **Bootstrap 5**, **Quill.js**, and **Marked.js**.\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/SupratimRK/web-bulk-email-sender/refs/heads/main/screenshot.png\" alt=\"Live Screenshot of App\" style=\"border-radius: 10px; max-width: 100%; box-shadow: 0 4px 8px rgba(0,0,0,0.1);\"\u003e\n\u003c/p\u003e\n\n---\n\n## ✨ Key Features\n\n*   **⚙️ Flexible Email Content Creation**:\n    *   **Upload Templates**: Use existing `.html`, `.htm`, `.md`, or `.txt` files. Markdown is automatically converted to HTML. Plain text is wrapped nicely.\n    *   **Draft In-App**: Utilize the **Quill Rich Text Editor** for easy formatting or switch to the **HTML Source** tab for precise control.\n*   **📧 Multiple Recipient Modes**:\n    *   **Bulk Sending**: Upload a `.csv` file. Requires an email column (looks for `email`, `email address`, etc., case-insensitive).\n    *   **Single Recipient**: Quickly send a test or one-off email by typing the address directly.\n*   **🎨 Dynamic Personalization**:\n    *   Use placeholders like `$name` or `${header}` in your subject and email body (matching your CSV column headers) for personalized messages. **(See 'Using Variables' section below)**\n*   **🖼️ Live Email Preview**:\n    *   Instantly see how your drafted or uploaded content will render before sending. (Note: Placeholders are not substituted in the preview).\n*   **📎 Attachment Support**:\n    *   Easily attach one or more files to your emails.\n*   **👤 Custom Sender Name**:\n    *   Optionally override the default sender display name (set in `.env`) for specific campaigns.\n*   **✉️ HTML \u0026 Plain Text**:\n    *   Automatically generates both HTML and plain text versions of your email for compatibility across different email clients using `html2text`.\n*   **🔐 Secure Configuration**:\n    *   Keep your SMTP credentials safe using a `.env` file. No hardcoding needed.\n    *   Supports standard SMTP servers and ports, including TLS.\n*   **📊 Detailed Results \u0026 Logging**:\n    *   Redirects to a results page after sending, showing a summary (Sent, Failed, Skipped) and a detailed log for each attempted email.\n    *   Clear success/failure/info icons for quick status assessment.\n*   **💡 Smart \u0026 Responsive UI**:\n    *   Built with Bootstrap 5 for a clean look on all devices.\n    *   Form sections dynamically show/hide based on selected options.\n    *   Navbar status indicator provides real-time feedback during processing and shows the final result.\n    *   Loading indicator prevents accidental double-sends.\n*   **✅ Robust Error Handling**:\n    *   Validates file types, checks for required inputs, handles CSV parsing errors, and provides informative SMTP error messages.\n\n## 💻 Tech Stack\n\n*   **Backend**: Flask (Python)\n*   **Frontend**: HTML, CSS, JavaScript\n*   **Styling**: Bootstrap 5, Bootstrap Icons\n*   **Rich Text Editor**: Quill.js\n*   **Markdown Parsing**: Marked.js (Frontend Preview), Python-Markdown (Backend Processing)\n*   **Email Generation**: Standard Python `email` library, `smtplib`\n*   **HTML to Text**: `html2text`\n*   **Environment Variables**: `python-dotenv`\n\n## 🛠️ Setup \u0026 Installation\n\nFollow these steps to get the application running on your local machine.\n\n### ✅ Prerequisites\n\n*   **Python**: Version 3.7 or newer recommended (due to Flask 2.x+ dependencies).\n*   **pip**: Python package installer (usually comes with Python).\n*   **Git**: For cloning the repository.\n*   **(Optional but Recommended)** A Python virtual environment manager (`venv`).\n\n### 🚀 Installation Steps\n\n1.  **Clone the Repository**:\n    ```bash\n    git clone https://github.com/SupratimRK/web-bulk-email-sender.git\n    cd web-bulk-email-sender\n    ```\n\n2.  **Create and Activate a Virtual Environment**:\n    *   **macOS / Linux**:\n        ```bash\n        python3 -m venv venv\n        source venv/bin/activate\n        ```\n    *   **Windows (Command Prompt/PowerShell)**:\n        ```bash\n        python -m venv venv\n        .\\venv\\Scripts\\activate\n        ```\n    *(Your terminal prompt should now indicate you're in the `(venv)`)*\n\n3.  **Install Dependencies**:\n    ```bash\n    pip install -r requirements.txt\n    ```\n\n4.  **Configure Environment Variables**:\n    *   **Copy the example file**:\n        ```bash\n        cp .env.example .env\n        ```\n        *(On Windows, you might use `copy .env.example .env`)*\n    *   **Edit the `.env` file** with your actual SMTP credentials and desired default display name. See the section below for details.\n\n### 🔒 Environment Variables (`.env` File)\n\nCreate a file named `.env` in the project root directory (where `app.py` is located) and add the following variables:\n\n```dotenv\n# .env - DO NOT COMMIT THIS FILE TO GIT!\n\n# Display Name shown in the 'From' field by default (can be overridden in UI)\ndisplay_name=\"Your Default Sender Name\"\n\n# Your sending email address (must match SMTP login)\nsender_email=\"your_email@example.com\"\n\n# Your email account password or an App Password (Recommended!)\npassword=\"your_password_or_app_password\"\n\n# SMTP Server Configuration (Examples below)\nMAILER_HOST=\"smtp.yourprovider.com\" # e.g., smtp.gmail.com, smtp.mailersend.net\nMAILER_PORT=\"587\"                   # Common ports: 587 (TLS), 465 (SSL), 25 (Insecure)\n\n# Flask Secret Key (for session management, flash messages)\n# Change this to a random string for better security\nFLASK_SECRET_KEY=\"a_default_but_less_secure_key_please_change_me\"\n```\n\n**Important Notes**:\n\n*   **Security**: **NEVER** commit your `.env` file to version control (Git). The `.gitignore` file should ideally prevent this, but always be cautious.\n*   **App Passwords**: If using Gmail or some other providers, it's highly recommended (or required) to enable 2-Factor Authentication (2FA) and generate an **App Password** specifically for this application instead of using your main account password.\n    *   [Gmail App Passwords Guide](https://support.google.com/accounts/answer/185833?hl=en)\n*   **SMTP Settings**: Ensure `MAILER_HOST` and `MAILER_PORT` are correct for your email provider. The code currently uses STARTTLS for port 587. If using port 465 (implicit SSL), the `smtplib.SMTP_SSL` class might be needed instead (requires code adjustment).\n\n## 🚀 How to Use\n\n1.  **Start the Flask Application**:\n    ```bash\n    python app.py\n    ```\n    The application will start, usually on `http://127.0.0.1:5000/` or `http://0.0.0.0:5000/` (accessible on your local network). Open the URL in your web browser.\n\n2.  **Choose Content Source**:\n    *   Select \"Draft Email Below\" to use the editor.\n    *   Select \"Upload Template File\" to browse for an `.html`, `.md`, or `.txt` file.\n\n3.  **Create/Upload Email Content**:\n    *   **If Drafting**: Use the Rich Text Editor or switch to the \"HTML Source\" tab.\n    *   **If Uploading**: Select your template file.\n\n4.  **Set Subject \u0026 Sender Name**:\n    *   Enter the **Email Subject**. You can use placeholders here (e.g., `Welcome, $name!`). See **\"How the Subject is Determined\"** below.\n    *   Optionally, enter a **Sender Display Name** to override the default from `.env`.\n\n5.  **Choose Recipient Method**:\n    *   Select \"Bulk (Upload CSV)\".\n    *   Select \"Single Recipient\".\n\n6.  **Provide Recipients**:\n    *   **If Bulk**: Upload your `.csv` file. See **\"Example CSV File\"** below.\n    *   **If Single**: Enter the recipient's email address in the input field.\n\n7.  **Add Attachments (Optional)**:\n    *   Click \"Choose Files\" and select one or more files to attach.\n\n8.  **Preview (Recommended)**:\n    *   Click the \"Preview\" button to see how the email body will look. Check formatting, especially if using Markdown or complex HTML. (Placeholders are not replaced in the preview).\n\n9.  **Send**:\n    *   Click the \"Send Email(s)\" button. A loading indicator will appear.\n\n10. **Review Results**:\n    *   You'll be redirected to the results page.\n    *   Check the summary status in the flash message and the navbar.\n    *   Review the detailed log for the status of each individual email (Success, Failed, Skipped). Error messages will be shown for failures.\n\n11. **Go Back**: Click \"Go Back \u0026 Send More\" to return to the main form.\n\n## 📄 Example CSV File for Bulk Sending\n\nWhen using the \"Bulk (Upload CSV)\" option, your CSV file structure is crucial.\n\n*   **Required Header**: It **MUST** contain a column header for email addresses. The application looks for common names like `email`, `email address`, `email_address`, `e-mail`, or `recipient` (case-insensitive). It will also try to find any header containing `mail` if the common ones aren't present.\n*   **Optional Headers**: Any other column headers can be used as variables for personalization in your subject and email body.\n*   **Encoding**: UTF-8 encoding (with or without BOM) is recommended. Latin-1 is supported as a fallback.\n*   **Delimiter**: Standard comma (`,`) delimiter is expected. The app attempts to sniff the dialect but defaults to comma-separated.\n\n**Example `recipients.csv` file:**\n\n```csv\nEmail,FirstName,LastName,Product,DiscountCode\nalice@example.com,Alice,Smith,SuperWidget,SUMMER20\nbob@domain.org,Bob,Jones,MegaGadget,WELCOME10\ncharlie@email.net,Charlie,Brown,TurboTool,\ndiana@sample.co,Diana,Prince,SuperWidget,SAVEBIG5\n,\"\",\"\",,\"\"  # Example of a potentially empty row (will be skipped)\nfrank@test.io,Frank,,,SAVE15 # Example with missing data\n```\n\n**Key points from the example:**\n\n*   The `Email` column is present and contains the recipient addresses.\n*   `FirstName`, `LastName`, `Product`, `DiscountCode` are optional headers used for personalization.\n*   Some rows might have missing data (like Charlie's DiscountCode or Frank's LastName/Product). The corresponding placeholder will be replaced with an empty string.\n*   Empty rows are skipped automatically.\n\n## 🔑 Understanding Variables \u0026 Personalization\n\nYou can personalize both the **Subject** and the **Email Body** using data from your CSV file (when in Bulk mode).\n\n*   **Syntax**: Use `$` followed by the header name (e.g., `$firstname`) OR `${header_name}` (e.g., `${product}`). The curly brace syntax `${...}` is useful if the placeholder is immediately followed by other characters that could be mistaken as part of the name (e.g., `${product}s`).\n*   **Matching**: The placeholder name **MUST** exactly match a column header in your CSV file, but the match is **case-insensitive**. So, `$firstname`, `$FirstName`, and `${FIRSTNAME}` will all correctly pull data from the `FirstName` column in the example CSV above.\n*   **Replacement**: Before sending each email, the application replaces every placeholder it finds with the corresponding value from that recipient's row in the CSV.\n*   **Missing Data**: If a placeholder exists in your template but the corresponding column is missing in the CSV or the cell is empty for a specific recipient, the placeholder will be replaced with an empty string (nothing).\n\n**Example Usage (based on the CSV above):**\n\n*   **Subject Input**: `Special Offer for $FirstName on ${Product}!`\n    *   For Alice: `Special Offer for Alice on SuperWidget!`\n    *   For Bob: `Special Offer for Bob on MegaGadget!`\n*   **Email Body Content (HTML example)**:\n    ```html\n    \u003cp\u003eHi $FirstName $LastName,\u003c/p\u003e\n    \u003cp\u003eThanks for your interest in the ${Product}. As a valued customer, use code \u003cstrong\u003e$DiscountCode\u003c/strong\u003e for a special discount!\u003c/p\u003e\n    \u003cp\u003eBest regards,\u003cbr\u003eThe Team\u003c/p\u003e\n    ```\n    *   For Alice: Renders with \"Hi Alice Smith,\" ... \"code SUMMER20...\"\n    *   For Charlie: Renders with \"Hi Charlie Brown,\" ... \"code ...\" (empty string for DiscountCode)\n\n**Important**: Variables are **NOT** replaced in the live Preview. The preview shows the raw template with placeholders intact.\n\n## 🤔 How the Email Subject is Determined\n\nThe application follows this logic to set the subject line for each email:\n\n1.  **User Input Field**: If you type anything into the \"Email Subject\" field on the form, that text is used as the template. Placeholders (like `$FirstName`) within this input *will* be processed using the CSV data for each recipient.\n2.  **`\u003ctitle\u003e` Tag (HTML Upload/Draft)**: If the \"Email Subject\" field is **left empty** AND the email content is determined to be HTML (either uploaded `.html`/`.htm` or drafted HTML), the application looks for a `\u003ctitle\u003eYour Subject Here\u003c/title\u003e` tag within the HTML content. If found, the text inside the title tag is used as the subject. Placeholders are *not* processed if the subject is extracted this way.\n3.  **First Non-Empty Line (Markdown/Text Upload or Fallback)**: If the subject field is empty AND no `\u003ctitle\u003e` tag is found (or the content is Markdown/Text), the application attempts to use the first non-empty, non-HTML-tag-like line from the email content as the subject. Placeholders are *not* processed if the subject is extracted this way.\n4.  **Default Subject**: If none of the above methods yield a subject (e.g., the content starts immediately with HTML tags and has no title, and the subject field was empty), a generic default subject like `\"Your Default Sender Name Information\"` (using the `display_name` from `.env` or the custom one) will be used.\n\n**Recommendation**: For maximum control and personalization, **always specify your desired subject in the \"Email Subject\" form field**, using placeholders as needed.\n\n## 📁 Project Structure\n\n```\nweb-bulk-email-sender/\n├── .env                 # Your SMTP config \u0026 secrets (!!! NOT COMMITTED !!!)\n├── .env.example         # Example environment file structure\n├── app.py               # Main Flask application logic (routing, email sending)\n├── requirements.txt     # Python package dependencies\n├── readme.md            # This file\n└── templates/\n    ├── index.html       # Main form UI (editor, options, preview)\n    └── result.html      # Status/result log page\n```\n\n## 🏃 Running the App\n\n```bash\n# Ensure you are in the project directory and your virtualenv is active\npython app.py\n```\n\nBy default, it runs on `http://127.0.0.1:5000`. The `host='0.0.0.0'` setting in `app.py` makes it accessible from other devices on your local network using your computer's local IP address (e.g., `http://192.168.1.100:5000`).\n\n## 🤝 Contributing \u0026 Future Development\n\nWe welcome contributions from the community! Whether it's fixing a bug, improving documentation, adding a new feature, or suggesting an idea, your help is appreciated.\n\n### How to Contribute\n\n1.  **Find an Issue or Feature**: Look through the existing [GitHub Issues](https://github.com/SupratimRK/web-bulk-email-sender/issues) or propose a new idea. Discussing your plan in an issue first is often a good idea.\n2.  **Fork the Repository**: Create your own copy of the project on GitHub ([https://github.com/SupratimRK/web-bulk-email-sender](https://github.com/SupratimRK/web-bulk-email-sender)).\n3.  **Create a Branch**: Make a new branch in your fork for your changes:\n    ```bash\n    git checkout -b feature/your-awesome-feature  # Or fix/address-specific-bug\n    ```\n4.  **Develop \u0026 Test**: Make your code changes. Add tests if applicable. Ensure the application runs correctly and your changes integrate well. Follow existing code style.\n5.  **Commit Your Changes**: Use clear and descriptive commit messages:\n    ```bash\n    git commit -m \"feat: Add template saving functionality\" -m \"Implemented feature X, allowing users to save drafts...\"\n    ```\n6.  **Push to Your Fork**:\n    ```bash\n    git push origin feature/your-awesome-feature\n    ```\n7.  **Open a Pull Request (PR)**: Go to the original repository ([https://github.com/SupratimRK/web-bulk-email-sender](https://github.com/SupratimRK/web-bulk-email-sender)) and open a PR from your branch to the `main` branch.\n8.  **Describe Your PR**: Clearly explain the purpose of your changes, what issue it fixes (e.g., `Closes #123`), and any specific testing instructions.\n\n### 💡 Potential Future Ideas \u0026 Roadmap\n\nThis project has room to grow! Here are some ideas that contributors could tackle:\n\n*   **📨 Template Management**: Allow users to save, load, and manage email templates directly within the UI.\n*   **🚦 Rate Limiting Control**: Add UI options to configure delays between sending emails to respect SMTP server limits.\n*   **✅ Enhanced CSV Validation/Preview**: Show a preview of parsed CSV data before sending, highlighting potential issues or the identified 'email' column.\n*   **🐳 Dockerization**: Create `Dockerfile` and `docker-compose.yml` for easier setup and deployment.\n*   **🎨 UI Themes/Customization**: Add options for different visual themes or allow minor UI tweaks.\n*   **👥 Simple Contact List Management**: Beyond single CSV uploads, potentially add basic list storage/management.\n\nIf you're interested in working on any of these, please open an issue on the [GitHub repository](https://github.com/SupratimRK/web-bulk-email-sender/issues) to discuss the approach first!\n\n## 🙏 Credits \u0026 Acknowledgements\n\n*   **Original Concept Inspiration**: [aahnik/bulk-email-sender](https://github.com/aahnik/bulk-email-sender)\n*   **Framework**: [Flask](https://flask.palletsprojects.com/)\n*   **Frontend Styling**: [Bootstrap](https://getbootstrap.com/), [Bootstrap Icons](https://icons.getbootstrap.com/)\n*   **Rich Text Editor**: [Quill.js](https://quilljs.com/)\n*   **Markdown Rendering**: [Marked.js](https://marked.js.org/), [Python-Markdown](https://python-markdown.github.io/)\n*   **HTML to Text**: [html2text](https://github.com/Alir3z4/html2text)\n\n## 📄 License\n\nThis project is licensed under the **MIT License**. See the LICENSE file (if included) or the standard MIT License text for details. Feel free to use, modify, and distribute it as you see fit, but please provide attribution.\n\n---\n\n### Happy Emailing! 🚀","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsupratimrk%2Fweb-bulk-email-sender","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsupratimrk%2Fweb-bulk-email-sender","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsupratimrk%2Fweb-bulk-email-sender/lists"}