# EmailSender

A flexible, lightweight Python library for sending HTML email notifications via SMTP. Perfect for sending notifications, alerts, and messages from your applications.

## Features

- 📧 Send HTML-formatted emails with ease
- 🎨 Two operation modes:
  - **Wrap Mode**: Automatically wrap messages with professional HTML styling
  - **Direct Mode**: Send custom pre-formatted HTML content
- ⚙️ Configurable SMTP server (defaults to Gmail)
- 🔐 Support for app passwords and secure authentication
- 🔄 Backward compatible with legacy failure notification methods
- ✅ Comprehensive error handling

## Installation

```bash
pip install email-sender-lib
```

## Quick Start

### Basic Usage (Wrap Mode)

```python
from email_sender import EmailSender

# Initialize the email sender
sender = EmailSender(
    sender_email="your-email@gmail.com",
    sender_password="your-app-password",
    recipient_email="recipient@example.com"
)

# Send a simple notification
sender.send_notification(
    subject="Process Completed",
    message="Your task has been completed successfully!"
)

# Send with details
sender.send_notification(
    subject="Deployment Report",
    message="Application deployed successfully",
    details={
        "Version": "1.2.0",
        "Environment": "Production",
        "Duration": "2m 34s"
    }
)
```

### Advanced Usage (Direct HTML Mode)

```python
from email_sender import EmailSender

sender = EmailSender(
    sender_email="your-email@gmail.com",
    sender_password="your-app-password",
    recipient_email="recipient@example.com"
)

# Send with custom HTML
custom_html = """
<html>
<head>
    <style>
        body { font-family: Arial, sans-serif; }
        .header { background-color: #28a745; color: white; padding: 15px; }
    </style>
</head>
<body>
    <div class="header"><h2>Custom HTML Email</h2></div>
    <p>Your custom content here</p>
</body>
</html>
"""

sender.send_notification(
    subject="Custom Notification",
    html_content=custom_html
)
```

### Using Custom SMTP Server

```python
sender = EmailSender(
    sender_email="your-email@example.com",
    sender_password="your-password",
    recipient_email="recipient@example.com",
    smtp_server="smtp.outlook.com",  # Outlook/Office 365
    smtp_port=587
)

# Now you can send emails via any SMTP server
sender.send_notification(
    subject="Hello",
    message="Email via Outlook"
)
```

### Send to Different Recipients

```python
# Send to a specific recipient (overrides default)
sender.send_notification(
    subject="Important Update",
    message="This is for a specific recipient",
    recipient="other-user@example.com"
)
```

## Configuration

### Gmail Setup (Recommended)

To use Gmail with this library, you need to create an **App Password**:

1. **Enable 2-Factor Authentication** on your Google Account:
   - Go to [myaccount.google.com](https://myaccount.google.com)
   - Click "Security" in the left sidebar
   - Enable "2-Step Verification"

2. **Create an App Password**:
   - Go to [myaccount.google.com/apppasswords](https://myaccount.google.com/apppasswords)
   - Select "Mail" and "Windows Computer" (or your device)
   - Google will generate a 16-character password
   - Copy this password and use it as `sender_password` in the library

3. **Example with Gmail**:
   ```python
   sender = EmailSender(
       sender_email="your-email@gmail.com",
       sender_password="xxxx xxxx xxxx xxxx",  # 16-char app password
       recipient_email="recipient@example.com"
   )
   ```

### Other SMTP Providers

**Outlook/Office 365:**
```python
sender = EmailSender(
    sender_email="your-email@outlook.com",
    sender_password="your-password",
    recipient_email="recipient@example.com",
    smtp_server="smtp.office365.com",
    smtp_port=587
)
```

**SendGrid:**
```python
sender = EmailSender(
    sender_email="apikey",  # Use 'apikey' as username
    sender_password="SG.xxxxx...",  # Your SendGrid API key
    recipient_email="recipient@example.com",
    smtp_server="smtp.sendgrid.net",
    smtp_port=587
)
```

**Custom SMTP Server:**
```python
sender = EmailSender(
    sender_email="your-email@company.com",
    sender_password="your-password",
    recipient_email="recipient@example.com",
    smtp_server="mail.company.com",
    smtp_port=587
)
```

## API Reference

### EmailSender

#### `__init__(sender_email, sender_password, recipient_email, smtp_server="smtp.gmail.com", smtp_port=587)`

Initialize the email sender.

**Parameters:**
- `sender_email` (str): Email address to send from
- `sender_password` (str): Email password or app password
- `recipient_email` (str): Default recipient email address
- `smtp_server` (str, optional): SMTP server address (default: "smtp.gmail.com")
- `smtp_port` (int, optional): SMTP port (default: 587)

**Raises:**
- `ValueError`: If any required parameter is empty

#### `send_notification(subject, message=None, html_content=None, details=None, recipient=None)`

Send a notification email.

**Parameters:**
- `subject` (str): Email subject line
- `message` (str, optional): Main notification message (used in wrap mode)
- `html_content` (str, optional): Pre-formatted HTML content (used in direct mode, takes precedence)
- `details` (dict, optional): Dictionary with additional details (used in wrap mode)
- `recipient` (str, optional): Recipient email (uses default if not provided)

**Returns:**
- `bool`: True if email sent successfully, False otherwise

**Modes:**
- **Wrap Mode**: Provide `message` and optional `details` for automatic HTML wrapping
- **Direct Mode**: Provide `html_content` for custom HTML (takes precedence over `message`)

**Examples:**
```python
# Wrap mode with details
sender.send_notification(
    subject="Alert",
    message="Something happened",
    details={"Status": "Critical", "Time": "12:34"}
)

# Direct mode with custom HTML
sender.send_notification(
    subject="Alert",
    html_content="<html>...</html>"
)

# Send to different recipient
sender.send_notification(
    subject="Alert",
    message="Hello",
    recipient="user@example.com"
)
```

#### `send_failure_notification(subject, message, details=None, recipient=None)` (Legacy)

Send a failure notification email. This method is deprecated but maintained for backward compatibility.

**Parameters:**
- `subject` (str): Email subject line
- `message` (str): Main failure message
- `details` (dict, optional): Dictionary with failure details
- `recipient` (str, optional): Recipient email (uses default if not provided)

**Returns:**
- `bool`: True if email sent successfully, False otherwise

## Error Handling

The library handles common SMTP errors gracefully:

```python
from email_sender import EmailSender

sender = EmailSender(
    sender_email="your-email@gmail.com",
    sender_password="wrong-password",
    recipient_email="recipient@example.com"
)

# This will print error messages and return False
success = sender.send_notification(
    subject="Test",
    message="Test message"
)

if not success:
    print("Failed to send email")
```

Common errors:
- **Authentication failed**: Check credentials and app password
- **Connection error**: Verify SMTP server and port settings
- **Invalid email**: Ensure email addresses are properly formatted

## Use Cases

- 📢 Send application alerts and notifications
- ✅ Deploy confirmations and status updates
- 🔔 User notifications and reminders
- 📊 Report delivery and data summaries
- ⚠️ Error and failure notifications
- 📧 Newsletter and bulk email (with rate limiting)

## Requirements

- Python 3.7+
- No external dependencies (uses only standard library)

## License

MIT License - see LICENSE file for details

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## Support

For issues, questions, or suggestions, please open an issue on GitHub.

---

**Note**: Keep your app password secure. Never commit it to version control. Use environment variables instead:

```python
import os
from email_sender import EmailSender

sender = EmailSender(
    sender_email=os.environ.get("EMAIL_ADDRESS"),
    sender_password=os.environ.get("EMAIL_PASSWORD"),
    recipient_email=os.environ.get("DEFAULT_RECIPIENT")
)
```
