mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 11:51:10 -05:00
- Restructure API v1 with improved serializers organization - Add user deletion requests and moderation queue system - Implement bulk moderation operations and permissions - Add user profile enhancements with display names and avatars - Expand ride and park API endpoints with better filtering - Add manufacturer API with detailed ride relationships - Improve authentication flows and error handling - Update frontend documentation and API specifications
550 lines
14 KiB
Markdown
550 lines
14 KiB
Markdown
# Email Service Documentation
|
|
|
|
## Table of Contents
|
|
|
|
1. [Overview](#overview)
|
|
2. [Architecture](#architecture)
|
|
3. [Configuration](#configuration)
|
|
4. [API Usage](#api-usage)
|
|
5. [Django Email Backend](#django-email-backend)
|
|
6. [Testing](#testing)
|
|
7. [Management Commands](#management-commands)
|
|
8. [Troubleshooting](#troubleshooting)
|
|
9. [Best Practices](#best-practices)
|
|
|
|
## Overview
|
|
|
|
The Email Service is a comprehensive email delivery system built for the Django application. It provides a centralized way to send emails through the ForwardEmail API service, with support for site-specific configurations, Django email backend integration, and comprehensive testing tools.
|
|
|
|
### Key Features
|
|
|
|
- **Site-specific Configuration**: Different email settings per Django site
|
|
- **ForwardEmail Integration**: Uses ForwardEmail API for reliable email delivery
|
|
- **Django Backend Integration**: Drop-in replacement for Django's email backend
|
|
- **REST API Endpoint**: Send emails via HTTP API
|
|
- **Comprehensive Testing**: Built-in testing commands and flows
|
|
- **History Tracking**: All configurations are tracked with pghistory
|
|
- **Admin Interface**: Easy configuration management through Django admin
|
|
|
|
## Architecture
|
|
|
|
The email service consists of several key components:
|
|
|
|
```
|
|
apps/email_service/
|
|
├── models.py # EmailConfiguration model
|
|
├── services.py # Core EmailService class
|
|
├── backends.py # Django email backend implementation
|
|
├── admin.py # Django admin configuration
|
|
├── urls.py # URL patterns (legacy)
|
|
└── management/commands/ # Testing and utility commands
|
|
|
|
apps/api/v1/email/
|
|
├── views.py # Centralized API views
|
|
└── urls.py # API URL patterns
|
|
```
|
|
|
|
### Component Overview
|
|
|
|
1. **EmailConfiguration Model**: Stores site-specific email settings
|
|
2. **EmailService**: Core service class for sending emails
|
|
3. **ForwardEmailBackend**: Django email backend implementation
|
|
4. **API Views**: REST API endpoints for email sending
|
|
5. **Management Commands**: Testing and utility tools
|
|
|
|
## Configuration
|
|
|
|
### Database Configuration
|
|
|
|
Email configurations are stored in the database and managed through the Django admin interface.
|
|
|
|
#### EmailConfiguration Model
|
|
|
|
The [`EmailConfiguration`](../backend/apps/email_service/models.py:8) model stores the following fields:
|
|
|
|
- `api_key`: ForwardEmail API key
|
|
- `from_email`: Default sender email address
|
|
- `from_name`: Display name for the sender
|
|
- `reply_to`: Reply-to email address
|
|
- `site`: Associated Django site (ForeignKey)
|
|
- `created_at`: Creation timestamp
|
|
- `updated_at`: Last update timestamp
|
|
|
|
#### Creating Configuration via Admin
|
|
|
|
1. Access Django admin at `/admin/`
|
|
2. Navigate to "Email Configurations"
|
|
3. Click "Add Email Configuration"
|
|
4. Fill in the required fields:
|
|
- **Site**: Select the Django site
|
|
- **API Key**: Your ForwardEmail API key
|
|
- **From Name**: Display name (e.g., "ThrillWiki")
|
|
- **From Email**: Sender email address
|
|
- **Reply To**: Reply-to email address
|
|
|
|
### Environment Variables (Fallback)
|
|
|
|
If no database configuration exists, the system falls back to environment variables:
|
|
|
|
```bash
|
|
FORWARD_EMAIL_API_KEY=your_api_key_here
|
|
FORWARD_EMAIL_FROM=noreply@yourdomain.com
|
|
FORWARD_EMAIL_BASE_URL=https://api.forwardemail.net
|
|
```
|
|
|
|
### Django Settings
|
|
|
|
Add the email service to your Django settings:
|
|
|
|
```python
|
|
# settings.py
|
|
INSTALLED_APPS = [
|
|
# ... other apps
|
|
'apps.email_service',
|
|
]
|
|
|
|
# ForwardEmail API base URL
|
|
FORWARD_EMAIL_BASE_URL = 'https://api.forwardemail.net'
|
|
|
|
# Optional: Use custom email backend
|
|
EMAIL_BACKEND = 'apps.email_service.backends.ForwardEmailBackend'
|
|
```
|
|
|
|
## API Usage
|
|
|
|
### REST API Endpoint
|
|
|
|
The email service provides a REST API endpoint for sending emails.
|
|
|
|
#### Endpoint
|
|
|
|
```
|
|
POST /api/v1/email/send/
|
|
```
|
|
|
|
#### Request Format
|
|
|
|
```json
|
|
{
|
|
"to": "recipient@example.com",
|
|
"subject": "Email Subject",
|
|
"text": "Email body text",
|
|
"from_email": "sender@example.com" // optional
|
|
}
|
|
```
|
|
|
|
#### Response Format
|
|
|
|
**Success (200 OK):**
|
|
```json
|
|
{
|
|
"message": "Email sent successfully",
|
|
"response": {
|
|
// ForwardEmail API response
|
|
}
|
|
}
|
|
```
|
|
|
|
**Error (400 Bad Request):**
|
|
```json
|
|
{
|
|
"error": "Missing required fields",
|
|
"required_fields": ["to", "subject", "text"]
|
|
}
|
|
```
|
|
|
|
**Error (500 Internal Server Error):**
|
|
```json
|
|
{
|
|
"error": "Failed to send email: [error details]"
|
|
}
|
|
```
|
|
|
|
#### Example Usage
|
|
|
|
**cURL:**
|
|
```bash
|
|
curl -X POST http://localhost:8000/api/v1/email/send/ \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"to": "user@example.com",
|
|
"subject": "Welcome to ThrillWiki",
|
|
"text": "Thank you for joining ThrillWiki!"
|
|
}'
|
|
```
|
|
|
|
**JavaScript (fetch):**
|
|
```javascript
|
|
const response = await fetch('/api/v1/email/send/', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-CSRFToken': getCookie('csrftoken') // if CSRF protection enabled
|
|
},
|
|
body: JSON.stringify({
|
|
to: 'user@example.com',
|
|
subject: 'Welcome to ThrillWiki',
|
|
text: 'Thank you for joining ThrillWiki!'
|
|
})
|
|
});
|
|
|
|
const result = await response.json();
|
|
```
|
|
|
|
**Python (requests):**
|
|
```python
|
|
import requests
|
|
|
|
response = requests.post('http://localhost:8000/api/v1/email/send/', json={
|
|
'to': 'user@example.com',
|
|
'subject': 'Welcome to ThrillWiki',
|
|
'text': 'Thank you for joining ThrillWiki!'
|
|
})
|
|
|
|
result = response.json()
|
|
```
|
|
|
|
### Direct Service Usage
|
|
|
|
You can also use the [`EmailService`](../backend/apps/email_service/services.py:11) class directly in your Python code:
|
|
|
|
```python
|
|
from django.contrib.sites.shortcuts import get_current_site
|
|
from apps.email_service.services import EmailService
|
|
|
|
# In a view or other code
|
|
def send_welcome_email(request, user_email):
|
|
site = get_current_site(request)
|
|
|
|
try:
|
|
response = EmailService.send_email(
|
|
to=user_email,
|
|
subject="Welcome to ThrillWiki",
|
|
text="Thank you for joining ThrillWiki!",
|
|
site=site
|
|
)
|
|
return response
|
|
except Exception as e:
|
|
# Handle error
|
|
print(f"Failed to send email: {e}")
|
|
return None
|
|
```
|
|
|
|
## Django Email Backend
|
|
|
|
The email service includes a custom Django email backend that integrates with Django's built-in email system.
|
|
|
|
### Configuration
|
|
|
|
To use the custom backend, set it in your Django settings:
|
|
|
|
```python
|
|
# settings.py
|
|
EMAIL_BACKEND = 'apps.email_service.backends.ForwardEmailBackend'
|
|
```
|
|
|
|
### Usage
|
|
|
|
Once configured, you can use Django's standard email functions:
|
|
|
|
```python
|
|
from django.core.mail import send_mail
|
|
from django.contrib.sites.shortcuts import get_current_site
|
|
|
|
def send_notification(request):
|
|
site = get_current_site(request)
|
|
|
|
send_mail(
|
|
subject='Notification',
|
|
message='This is a notification email.',
|
|
from_email=None, # Will use site's default
|
|
recipient_list=['user@example.com'],
|
|
fail_silently=False,
|
|
)
|
|
```
|
|
|
|
### Backend Features
|
|
|
|
The [`ForwardEmailBackend`](../backend/apps/email_service/backends.py:7) provides:
|
|
|
|
- **Site-aware Configuration**: Automatically uses the correct site's email settings
|
|
- **Error Handling**: Proper error handling with optional silent failures
|
|
- **Multiple Recipients**: Handles multiple recipients (sends individually)
|
|
- **From Email Handling**: Automatic from email resolution
|
|
|
|
### Backend Limitations
|
|
|
|
- **Single Recipient**: ForwardEmail API sends to one recipient at a time
|
|
- **Text Only**: Currently supports text emails only (HTML support can be added)
|
|
- **Site Requirement**: Requires site context for configuration lookup
|
|
|
|
## Testing
|
|
|
|
The email service includes comprehensive testing tools to verify functionality.
|
|
|
|
### Management Commands
|
|
|
|
#### Test Email Service
|
|
|
|
Test the core email service functionality:
|
|
|
|
```bash
|
|
cd backend && uv run manage.py test_email_service
|
|
```
|
|
|
|
**Options:**
|
|
- `--to EMAIL`: Recipient email (default: test@thrillwiki.com)
|
|
- `--api-key KEY`: Override API key
|
|
- `--from-email EMAIL`: Override from email
|
|
|
|
**Example:**
|
|
```bash
|
|
cd backend && uv run manage.py test_email_service --to user@example.com
|
|
```
|
|
|
|
This command tests:
|
|
1. Site configuration setup
|
|
2. Direct EmailService usage
|
|
3. API endpoint functionality
|
|
4. Django email backend
|
|
|
|
#### Test Email Flows
|
|
|
|
Test all application email flows:
|
|
|
|
```bash
|
|
cd backend && uv run manage.py test_email_flows
|
|
```
|
|
|
|
This command tests:
|
|
1. User registration emails
|
|
2. Password change notifications
|
|
3. Email change verification
|
|
4. Password reset emails
|
|
|
|
### Manual Testing
|
|
|
|
#### API Endpoint Testing
|
|
|
|
Test the API endpoint directly:
|
|
|
|
```bash
|
|
curl -X POST http://localhost:8000/api/v1/email/send/ \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"to": "test@example.com",
|
|
"subject": "Test Email",
|
|
"text": "This is a test email."
|
|
}'
|
|
```
|
|
|
|
#### Django Shell Testing
|
|
|
|
Test using Django shell:
|
|
|
|
```python
|
|
# cd backend && uv run manage.py shell
|
|
from django.contrib.sites.models import Site
|
|
from apps.email_service.services import EmailService
|
|
|
|
site = Site.objects.get_current()
|
|
response = EmailService.send_email(
|
|
to="test@example.com",
|
|
subject="Test from Shell",
|
|
text="This is a test email from Django shell.",
|
|
site=site
|
|
)
|
|
print(response)
|
|
```
|
|
|
|
## Management Commands
|
|
|
|
### test_email_service
|
|
|
|
**Purpose**: Comprehensive testing of email service functionality
|
|
|
|
**Location**: [`backend/apps/email_service/management/commands/test_email_service.py`](../backend/apps/email_service/management/commands/test_email_service.py:12)
|
|
|
|
**Usage:**
|
|
```bash
|
|
cd backend && uv run manage.py test_email_service [options]
|
|
```
|
|
|
|
**Options:**
|
|
- `--to EMAIL`: Recipient email address
|
|
- `--api-key KEY`: ForwardEmail API key override
|
|
- `--from-email EMAIL`: Sender email override
|
|
|
|
**Tests Performed:**
|
|
1. **Site Configuration**: Creates/updates email configuration
|
|
2. **Direct Service**: Tests EmailService.send_email()
|
|
3. **API Endpoint**: Tests REST API endpoint
|
|
4. **Django Backend**: Tests Django email backend
|
|
|
|
### test_email_flows
|
|
|
|
**Purpose**: Test all application email flows
|
|
|
|
**Location**: [`backend/apps/email_service/management/commands/test_email_flows.py`](../backend/apps/email_service/management/commands/test_email_flows.py:13)
|
|
|
|
**Usage:**
|
|
```bash
|
|
cd backend && uv run manage.py test_email_flows
|
|
```
|
|
|
|
**Tests Performed:**
|
|
1. **Registration**: User registration email flow
|
|
2. **Password Change**: Password change notification
|
|
3. **Email Change**: Email change verification
|
|
4. **Password Reset**: Password reset email flow
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
#### 1. "Email configuration is missing for site"
|
|
|
|
**Cause**: No EmailConfiguration exists for the current site.
|
|
|
|
**Solution:**
|
|
1. Access Django admin
|
|
2. Create EmailConfiguration for your site
|
|
3. Or set environment variables as fallback
|
|
|
|
#### 2. "Failed to send email (Status 401)"
|
|
|
|
**Cause**: Invalid or missing API key.
|
|
|
|
**Solution:**
|
|
1. Verify API key in EmailConfiguration
|
|
2. Check ForwardEmail account status
|
|
3. Ensure API key has proper permissions
|
|
|
|
#### 3. "Could not connect to server"
|
|
|
|
**Cause**: Django development server not running or wrong URL.
|
|
|
|
**Solution:**
|
|
1. Start Django server: `cd backend && uv run manage.py runserver`
|
|
2. Verify server is running on expected port
|
|
3. Check FORWARD_EMAIL_BASE_URL setting
|
|
|
|
#### 4. "Site matching query does not exist"
|
|
|
|
**Cause**: Default site not configured properly.
|
|
|
|
**Solution:**
|
|
```python
|
|
# Django shell
|
|
from django.contrib.sites.models import Site
|
|
Site.objects.get_or_create(
|
|
id=1,
|
|
defaults={'domain': 'localhost:8000', 'name': 'localhost:8000'}
|
|
)
|
|
```
|
|
|
|
### Debug Mode
|
|
|
|
The EmailService includes debug output. Check console logs for:
|
|
- Request URL and data
|
|
- Response status and body
|
|
- API key (masked)
|
|
- Site information
|
|
|
|
### Testing Configuration
|
|
|
|
Verify your configuration:
|
|
|
|
```bash
|
|
# Test with specific configuration
|
|
cd backend && uv run manage.py test_email_service \
|
|
--api-key your_api_key \
|
|
--from-email noreply@yourdomain.com \
|
|
--to test@example.com
|
|
```
|
|
|
|
### API Response Codes
|
|
|
|
- **200**: Success
|
|
- **400**: Bad request (missing fields, invalid data)
|
|
- **401**: Unauthorized (invalid API key)
|
|
- **500**: Server error (configuration issues, network problems)
|
|
|
|
## Best Practices
|
|
|
|
### Security
|
|
|
|
1. **API Key Protection**: Store API keys securely, never in code
|
|
2. **Environment Variables**: Use environment variables for sensitive data
|
|
3. **HTTPS**: Always use HTTPS in production
|
|
4. **Rate Limiting**: Implement rate limiting for API endpoints
|
|
|
|
### Configuration Management
|
|
|
|
1. **Site-Specific Settings**: Use database configuration for multi-site setups
|
|
2. **Fallback Configuration**: Always provide environment variable fallbacks
|
|
3. **Admin Interface**: Use Django admin for easy configuration management
|
|
4. **Configuration Validation**: Test configurations after changes
|
|
|
|
### Error Handling
|
|
|
|
1. **Graceful Degradation**: Handle email failures gracefully
|
|
2. **Logging**: Log email failures for debugging
|
|
3. **User Feedback**: Provide appropriate user feedback
|
|
4. **Retry Logic**: Implement retry logic for transient failures
|
|
|
|
### Performance
|
|
|
|
1. **Async Processing**: Consider using Celery for email sending
|
|
2. **Batch Operations**: Group multiple emails when possible
|
|
3. **Connection Pooling**: Reuse HTTP connections when sending multiple emails
|
|
4. **Monitoring**: Monitor email delivery rates and failures
|
|
|
|
### Testing
|
|
|
|
1. **Automated Tests**: Include email testing in your test suite
|
|
2. **Test Environments**: Use test email addresses in development
|
|
3. **Integration Tests**: Test complete email flows
|
|
4. **Load Testing**: Test email service under load
|
|
|
|
### Monitoring
|
|
|
|
1. **Delivery Tracking**: Monitor email delivery success rates
|
|
2. **Error Tracking**: Track and alert on email failures
|
|
3. **Performance Metrics**: Monitor email sending performance
|
|
4. **API Limits**: Monitor ForwardEmail API usage limits
|
|
|
|
### Example Production Configuration
|
|
|
|
```python
|
|
# settings/production.py
|
|
EMAIL_BACKEND = 'apps.email_service.backends.ForwardEmailBackend'
|
|
FORWARD_EMAIL_BASE_URL = 'https://api.forwardemail.net'
|
|
|
|
# Use environment variables for sensitive data
|
|
import os
|
|
FORWARD_EMAIL_API_KEY = os.environ.get('FORWARD_EMAIL_API_KEY')
|
|
FORWARD_EMAIL_FROM = os.environ.get('FORWARD_EMAIL_FROM')
|
|
|
|
# Logging configuration
|
|
LOGGING = {
|
|
'version': 1,
|
|
'disable_existing_loggers': False,
|
|
'handlers': {
|
|
'email_file': {
|
|
'level': 'INFO',
|
|
'class': 'logging.FileHandler',
|
|
'filename': '/var/log/django/email.log',
|
|
},
|
|
},
|
|
'loggers': {
|
|
'apps.email_service': {
|
|
'handlers': ['email_file'],
|
|
'level': 'INFO',
|
|
'propagate': True,
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
This documentation provides comprehensive coverage of the email service functionality, from basic setup to advanced usage patterns and troubleshooting. |