12 KiB
Email Sending Fix - Complete Summary
Problem Identified
Emails were not being sent in the development environment due to conflicting email backend configurations:
Configuration Conflict
-
.envfile: Configured to use SMTP backendEMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend -
config/settings/base.py: Read EMAIL_BACKEND from .env → SMTP -
config/settings/dev.py: OVERRRODE with console backendEMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' -
Simulator API: Attempted to use Django's
send_mail()which used console backend, but then tried to send via SMTP server that doesn't support STARTTLS
Result
- Emails printed to console instead of being sent via simulator API
- SMTP connection errors: "STARTTLS extension not supported by server"
- All email requests failed with 500 status
Solution Implemented
1. Updated config/settings/dev.py
Changed: Commented out console backend override to allow simulator API to work
# Email backend for development
# Use simulator API for email (configured in .env with EMAIL_API_ENABLED=true)
# Emails will be sent to http://localhost:8000/api/simulator/send-email
# and displayed in terminal with formatted output
# EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' # Disabled for simulator API
Effect: Now uses the configuration from .env which enables EMAIL_API
2. Updated apps/notifications/services.py
Changed: Modified send_email() and send_sms() to check for API enabled first
@staticmethod
def send_email(email, subject, message, html_message=None, related_object=None, metadata=None):
# Check if Email API is enabled and use it (simulator or external API)
email_api_config = settings.EXTERNAL_NOTIFICATION_API.get('email', {})
if email_api_config.get('enabled', False):
return NotificationService.send_email_via_api(...)
# Fallback to Django email backend if API disabled
...
Effect: Prioritizes API-based sending when enabled, falls back to Django's send_mail() otherwise
3. Updated apps/simulator/views.py
Changed: Modified email simulator to BOTH display formatted output AND send real emails via SMTP
# Display formatted email to terminal
print(f"\n{'╔' + '═'*68 + '╗'}")
print(f"║{' ' * 15}📧 EMAIL SIMULATOR{' ' * 34}║")
# ... formatted output ...
print(f"╚{'═'*68}╝\n")
# Send real email via Django SMTP
send_mail(
subject=subject,
message=message,
from_email=settings.DEFAULT_FROM_EMAIL,
recipient_list=[to_email],
html_message=html_message,
fail_silently=False
)
Effect: Simulator displays emails in terminal with beautiful formatted output AND sends real emails via SMTP
4. Updated .env File
Changed: Disabled TLS for SMTP server
# Before
EMAIL_USE_TLS=True
# After
EMAIL_USE_TLS=False
Effect: Allows connection to SMTP server at 10.10.1.110:2225 which doesn't support STARTTLS
Current Email Flow (Development)
NotificationService.send_email()
↓
Checks EMAIL_API_ENABLED in settings
↓
If enabled → Uses send_email_via_api()
↓
Sends POST request to http://localhost:8000/api/simulator/send-email
↓
Simulator receives request
↓
Displays formatted email in terminal
↓
Sends real email via SMTP (10.10.1.110:2225)
↓
Returns 200 OK with success response
↓
NotificationLog created with status='sent'
Test Results
All tests passed successfully:
1. Testing plain text email... ✅
Log ID: 476a0fce-9a26-4244-877c-62e696c64169
Recipient: test@example.com
2. Testing HTML email... ✅
Log ID: f2bd7cbf-b5ee-4f02-9717-a3c61b46f88d
Recipient: test@example.com
3. Testing SMS sending... ✅
Log ID: edc987b6-aca6-4368-b3e3-8d42b3eb9dd5
Recipient: +966501234567
Server Log Output
INFO [Email Simulator] Sending email to test@example.com: Test Email - Plain Text
INFO [Email Simulator] Email sent via SMTP to test@example.com
INFO [Email Simulator] Email sent successfully to test@example.com
INFO [Simulator] EMAIL Request #1: sent
INFO "POST /api/simulator/send-email HTTP/1.1" 200 170
Formatted Output Example
Email Simulator Output
╔════════════════════════════════════════════════════════════════════╗
║ 📧 EMAIL SIMULATOR ║
╠════════════════════════════════════════════════════════════════════╣
║ Request #: 1 ║
╠════════════════════════════════════════════════════════════════════╣
║ To: test@example.com ║
║ Subject: Test Email - Plain Text ║
╠════════════════════════════════════════════════════════════════════╣
║ Message: ║
║ This is a test email sent via simulator API. ║
╚════════════════════════════════════════════════════════════════════╝
SMS Simulator Output
╔════════════════════════════════════════════════════════════════════╗
║ 📱 SMS SIMULATOR ║
╠════════════════════════════════════════════════════════════════════╣
║ Request #: 1 ║
╠════════════════════════════════════════════════════════════════════╣
║ To: +966501234567 ║
║ Time: 2026-01-12 18:57:13 ║
╠════════════════════════════════════════════════════════════════════╣
║ Message: ║
║ This is a test SMS sent via simulator API. ║
╚════════════════════════════════════════════════════════════════════╝
Configuration
Required .env Settings
# Email Configuration
EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
EMAIL_HOST=10.10.1.110
EMAIL_PORT=2225
EMAIL_USE_TLS=False # Disabled for this SMTP server
EMAIL_HOST_USER=
EMAIL_HOST_PASSWORD=
DEFAULT_FROM_EMAIL=noreply@px360.sa
# Enable Email API (simulator or external)
EMAIL_API_ENABLED=true
# Email Simulator API URL
EMAIL_API_URL=http://localhost:8000/api/simulator/send-email
EMAIL_API_KEY=simulator-test-key
EMAIL_API_AUTH_METHOD=bearer
# Enable SMS API (simulator or external)
SMS_API_ENABLED=true
# SMS Simulator API URL
SMS_API_URL=http://localhost:8000/api/simulator/send-sms
SMS_API_KEY=simulator-test-key
SMS_API_AUTH_METHOD=bearer
Usage
Send Email (Plain Text)
from apps.notifications.services import NotificationService
log = NotificationService.send_email(
email='user@example.com',
subject='Welcome to PX360',
message='Thank you for registering!'
)
Send Email (HTML)
html_message = """
<html>
<body>
<h1>Welcome!</h1>
<p>Thank you for registering with <strong>PX360</strong>.</p>
</body>
</html>
"""
log = NotificationService.send_email(
email='user@example.com',
subject='Welcome to PX360',
message='Plain text version',
html_message=html_message
)
Send SMS
log = NotificationService.send_sms(
phone='+966501234567',
message='Your survey is ready. Please complete it today!'
)
Benefits
- Dual-Mode Operation: Displays formatted output AND sends real emails
- No SMTP Errors: Fixed STARTTLS issue by disabling TLS for development
- Formatted Output: Beautiful terminal display for both email and SMS
- Logged to Database: All notifications logged in NotificationLog table
- API-First Architecture: Easy to switch to external APIs (SendGrid, Twilio) in production
- Retry Logic: Built-in retry with exponential backoff for API failures
- Testing Friendly: Easy to verify emails are being sent
Production Configuration
To use actual email/SMS providers in production:
# Email (e.g., SendGrid)
EMAIL_API_ENABLED=true
EMAIL_API_URL=https://api.sendgrid.com/v3/mail/send
EMAIL_API_KEY=your-sendgrid-api-key
EMAIL_API_AUTH_METHOD=bearer
# SMS (e.g., Twilio)
SMS_API_ENABLED=true
SMS_API_URL=https://api.twilio.com/2010-04-01/Accounts/{AccountSid}/Messages.json
SMS_API_KEY=your-twilio-api-key
SMS_API_AUTH_METHOD=basic
Testing
Run the test script to verify email sending:
python test_email_sending.py
Expected output:
======================================================================
Testing Email Sending via Simulator API
======================================================================
1. Testing plain text email... ✅ Plain text email sent successfully!
2. Testing HTML email... ✅ HTML email sent successfully!
3. Testing SMS sending... ✅ SMS sent successfully!
======================================================================
Test Complete!
======================================================================
Files Modified
config/settings/dev.py- Disabled console backend overrideapps/notifications/services.py- Updated to prioritize API sendingapps/simulator/views.py- Changed to print formatted output AND send via SMTP.env- Disabled TLS for SMTP servertest_email_sending.py- Created test scriptdocs/EMAIL_SENDING_FIX.md- Complete documentation
Next Steps
- Consider implementing email templates for better formatting
- Add email preview functionality in admin panel
- Implement email tracking and analytics
- Add bounce and complaint handling for production
- Set up webhook notifications for delivery status
- Configure a more secure SMTP server for production with TLS enabled
Troubleshooting
Emails still not sending?
- Check
.envfile hasEMAIL_API_ENABLED=true - Verify server is running on port 8000
- Check logs:
tail -f logs/px360.log - Test simulator directly:
curl http://localhost:8000/api/simulator/health-check - Verify SMTP server is accessible:
telnet 10.10.1.110 2225
Can't see formatted output?
The formatted output is printed to the terminal where the Django development server is running, not to the log file. Make sure you're watching the correct terminal.
Email sent but not received?
- Check spam/junk folder
- Verify email address is correct
- Check SMTP server logs
- Verify
DEFAULT_FROM_EMAILis properly configured - Some email providers may reject emails from certain senders
Date
Fixed on: January 12, 2026 Updated: January 12, 2026 - Added real SMTP sending capability