561 lines
15 KiB
Markdown
561 lines
15 KiB
Markdown
# Notification Simulator API
|
|
|
|
## Overview
|
|
|
|
The Notification Simulator API provides mock endpoints that simulate external email and SMS services for testing purposes. It's integrated with the external API notification system and allows you to test notification workflows without relying on third-party services.
|
|
|
|
**Key Features:**
|
|
- ✅ **Email Simulator**: Sends real emails via Django SMTP
|
|
- ✅ **SMS Simulator**: Prints formatted SMS messages to terminal
|
|
- ✅ **Request Tracking**: Logs all requests with counters and history
|
|
- ✅ **Health Check**: Monitor simulator status and statistics
|
|
- ✅ **Easy Configuration**: Simple `.env` configuration to enable/disable
|
|
|
|
## Architecture
|
|
|
|
```
|
|
PX360 Application
|
|
↓
|
|
NotificationService.send_email_via_api()
|
|
↓
|
|
HTTP POST to Simulator API
|
|
↓
|
|
┌─────────────┬─────────────┐
|
|
│ Email Sim. │ SMS Sim. │
|
|
│ Sends │ Prints to │
|
|
│ Real Email │ Terminal │
|
|
└─────────────┴─────────────┘
|
|
```
|
|
|
|
## Endpoints
|
|
|
|
### 1. Email Simulator
|
|
|
|
**Endpoint**: `POST /api/simulator/send-email`
|
|
|
|
**Request Body**:
|
|
```json
|
|
{
|
|
"to": "recipient@example.com",
|
|
"subject": "Email subject",
|
|
"message": "Plain text message",
|
|
"html_message": "<html>Optional HTML content</html>"
|
|
}
|
|
```
|
|
|
|
**Response** (Success):
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Email sent successfully",
|
|
"data": {
|
|
"to": "recipient@example.com",
|
|
"subject": "Email subject",
|
|
"message_length": 100,
|
|
"has_html": true
|
|
}
|
|
}
|
|
```
|
|
|
|
**Behavior**:
|
|
- Validates required fields (`to`, `subject`, `message`)
|
|
- Sends real email using Django's SMTP backend
|
|
- Prints formatted output to terminal
|
|
- Logs request to file and history
|
|
|
|
### 2. SMS Simulator
|
|
|
|
**Endpoint**: `POST /api/simulator/send-sms`
|
|
|
|
**Request Body**:
|
|
```json
|
|
{
|
|
"to": "+966501234567",
|
|
"message": "SMS message text"
|
|
}
|
|
```
|
|
|
|
**Response** (Success):
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "SMS sent successfully",
|
|
"data": {
|
|
"to": "+966501234567",
|
|
"message_length": 20
|
|
}
|
|
}
|
|
```
|
|
|
|
**Behavior**:
|
|
- Validates required fields (`to`, `message`)
|
|
- Prints formatted SMS to terminal with box drawing
|
|
- Logs request to file and history
|
|
|
|
**Terminal Output Example**:
|
|
```
|
|
══════════════════════════════════════════════════════════════════════
|
|
📱 SMS SIMULATOR
|
|
══════════════════════════════════════════════════════════════════════
|
|
Request #: 1
|
|
══════════════════════════════════════════════════════════════════════
|
|
To: +966501234567
|
|
Time: 2026-01-12 18:05:00
|
|
══════════════════════════════════════════════════════════════════════
|
|
Message:
|
|
Your verification code is 123456
|
|
══════════════════════════════════════════════════════════════════════
|
|
```
|
|
|
|
### 3. Health Check
|
|
|
|
**Endpoint**: `GET /api/simulator/health`
|
|
|
|
**Response**:
|
|
```json
|
|
{
|
|
"status": "healthy",
|
|
"timestamp": "2026-01-12T18:05:00.000000",
|
|
"statistics": {
|
|
"total_requests": 5,
|
|
"email_requests": 3,
|
|
"sms_requests": 2
|
|
},
|
|
"recent_requests": [
|
|
{
|
|
"id": 5,
|
|
"channel": "sms",
|
|
"timestamp": "2026-01-12T18:05:00.000000",
|
|
"status": "sent",
|
|
"payload": {...}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### 4. Reset Simulator
|
|
|
|
**Endpoint**: `GET /api/simulator/reset`
|
|
|
|
**Response**:
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Simulator reset successfully"
|
|
}
|
|
```
|
|
|
|
**Behavior**: Clears all counters and request history.
|
|
|
|
## Configuration
|
|
|
|
### Enable Simulator
|
|
|
|
Add these settings to your `.env` file:
|
|
|
|
```bash
|
|
# Enable external API notifications
|
|
EMAIL_API_ENABLED=true
|
|
SMS_API_ENABLED=true
|
|
|
|
# Point to simulator endpoints
|
|
EMAIL_API_URL=http://localhost:8000/api/simulator/send-email
|
|
SMS_API_URL=http://localhost:8000/api/simulator/send-sms
|
|
|
|
# Simulator authentication (any value works)
|
|
EMAIL_API_KEY=simulator-test-key
|
|
SMS_API_KEY=simulator-test-key
|
|
|
|
# Authentication method
|
|
EMAIL_API_AUTH_METHOD=bearer
|
|
SMS_API_AUTH_METHOD=bearer
|
|
```
|
|
|
|
### Email Configuration
|
|
|
|
The email simulator uses Django's SMTP backend. Configure your SMTP settings in `.env`:
|
|
|
|
```bash
|
|
# Email Configuration
|
|
EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
|
|
EMAIL_HOST=smtp.gmail.com
|
|
EMAIL_PORT=587
|
|
EMAIL_USE_TLS=True
|
|
EMAIL_HOST_USER=your-email@gmail.com
|
|
EMAIL_HOST_PASSWORD=your-app-password
|
|
DEFAULT_FROM_EMAIL=noreply@px360.sa
|
|
```
|
|
|
|
**Important**: For Gmail, use an App Password instead of your regular password.
|
|
|
|
## Usage Examples
|
|
|
|
### Example 1: Send Email via Simulator
|
|
|
|
```python
|
|
from apps.notifications.services import NotificationService
|
|
|
|
# Send email - will be sent via SMTP
|
|
log = NotificationService.send_email_via_api(
|
|
message='Your account has been created successfully!',
|
|
email='user@example.com',
|
|
subject='Welcome to PX360'
|
|
)
|
|
|
|
print(f"Email status: {log.status}")
|
|
```
|
|
|
|
**Terminal Output**:
|
|
```
|
|
======================================================================
|
|
📧 EMAIL SIMULATOR - Request #1
|
|
======================================================================
|
|
To: user@example.com
|
|
Subject: Welcome to PX360
|
|
Message: Your account has been created successfully!
|
|
HTML: No
|
|
======================================================================
|
|
```
|
|
|
|
### Example 2: Send SMS via Simulator
|
|
|
|
```python
|
|
from apps.notifications.services import NotificationService
|
|
|
|
# Send SMS - will be printed to terminal
|
|
log = NotificationService.send_sms_via_api(
|
|
message='Your verification code is 123456',
|
|
phone='+966501234567'
|
|
)
|
|
|
|
print(f"SMS status: {log.status}")
|
|
```
|
|
|
|
**Terminal Output**:
|
|
```
|
|
══════════════════════════════════════════════════════════════════════
|
|
📱 SMS SIMULATOR
|
|
══════════════════════════════════════════════════════════════════════
|
|
Request #: 1
|
|
══════════════════════════════════════════════════════════════════════
|
|
To: +966501234567
|
|
Time: 2026-01-12 18:05:00
|
|
══════════════════════════════════════════════════════════════════════
|
|
Message:
|
|
Your verification code is 123456
|
|
══════════════════════════════════════════════════════════════════════
|
|
```
|
|
|
|
### Example 3: Send HTML Email
|
|
|
|
```python
|
|
from apps.notifications.services import NotificationService
|
|
|
|
# Send email with HTML content
|
|
log = NotificationService.send_email_via_api(
|
|
message='Please view this email in HTML mode.',
|
|
email='user@example.com',
|
|
subject='Welcome',
|
|
html_message='<h1>Welcome!</h1><p>Your account is ready.</p>'
|
|
)
|
|
```
|
|
|
|
### Example 4: Check Simulator Status
|
|
|
|
```bash
|
|
# Using curl
|
|
curl http://localhost:8000/api/simulator/health
|
|
```
|
|
|
|
```python
|
|
# Using requests
|
|
import requests
|
|
|
|
response = requests.get('http://localhost:8000/api/simulator/health')
|
|
print(response.json())
|
|
```
|
|
|
|
### Example 5: Reset Simulator
|
|
|
|
```bash
|
|
# Using curl
|
|
curl http://localhost:8000/api/simulator/reset
|
|
```
|
|
|
|
```python
|
|
# Using requests
|
|
import requests
|
|
|
|
response = requests.get('http://localhost:8000/api/simulator/reset')
|
|
print(response.json())
|
|
```
|
|
|
|
## Testing Workflow
|
|
|
|
### Step 1: Start Development Server
|
|
|
|
```bash
|
|
python manage.py runserver
|
|
```
|
|
|
|
### Step 2: Enable Simulator
|
|
|
|
Update `.env` file with simulator URLs (see Configuration section).
|
|
|
|
### Step 3: Run Python Script
|
|
|
|
```python
|
|
# test_simulator.py
|
|
from apps.notifications.services import NotificationService
|
|
|
|
# Test email
|
|
print("Testing email...")
|
|
email_log = NotificationService.send_email_via_api(
|
|
message='Test email from simulator',
|
|
email='your-email@example.com',
|
|
subject='Simulator Test'
|
|
)
|
|
print(f"Email: {email_log.status}")
|
|
|
|
# Test SMS
|
|
print("\nTesting SMS...")
|
|
sms_log = NotificationService.send_sms_via_api(
|
|
message='Test SMS from simulator',
|
|
phone='+966501234567'
|
|
)
|
|
print(f"SMS: {sms_log.status}")
|
|
|
|
# Check health
|
|
import requests
|
|
health = requests.get('http://localhost:8000/api/simulator/health').json()
|
|
print(f"\nStatistics: {health['statistics']}")
|
|
```
|
|
|
|
### Step 4: Verify Results
|
|
|
|
- **Email**: Check your email inbox (or mailcatcher if using console backend)
|
|
- **SMS**: Check terminal for formatted SMS output
|
|
- **Logs**: Check `logs/px360.log` for detailed logs
|
|
|
|
## Integration with External API Service
|
|
|
|
The simulator is fully integrated with the external API notification service. When you enable the simulator URLs in `.env`, the `NotificationService` automatically uses the simulator endpoints.
|
|
|
|
### Switching Between Simulator and Real APIs
|
|
|
|
**Using Simulator** (for development/testing):
|
|
```bash
|
|
EMAIL_API_ENABLED=true
|
|
EMAIL_API_URL=http://localhost:8000/api/simulator/send-email
|
|
SMS_API_ENABLED=true
|
|
SMS_API_URL=http://localhost:8000/api/simulator/send-sms
|
|
```
|
|
|
|
**Using Real APIs** (for production):
|
|
```bash
|
|
EMAIL_API_ENABLED=true
|
|
EMAIL_API_URL=https://api.yourservice.com/send-email
|
|
SMS_API_ENABLED=true
|
|
SMS_API_URL=https://api.yourservice.com/send-sms
|
|
```
|
|
|
|
**No code changes required!** Just update the URLs in `.env`.
|
|
|
|
## Request Logging
|
|
|
|
All simulator requests are logged to:
|
|
|
|
1. **Terminal**: Immediate feedback during development
|
|
2. **File Log**: `logs/px360.log` - permanent record
|
|
3. **Request History**: In-memory last 10 requests (accessible via health check)
|
|
|
|
### Log Format
|
|
|
|
```
|
|
[INFO] [Simulator] EMAIL Request #1: sent
|
|
[INFO] [Email Simulator] Sending email to user@example.com: Test Subject
|
|
[INFO] [Email Simulator] Email sent successfully to user@example.com
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
The simulator handles various error scenarios gracefully:
|
|
|
|
### Missing Fields
|
|
|
|
**Request**:
|
|
```json
|
|
{
|
|
"to": "user@example.com"
|
|
// Missing "subject" and "message"
|
|
}
|
|
```
|
|
|
|
**Response**:
|
|
```json
|
|
{
|
|
"success": false,
|
|
"error": "Missing required fields: subject, message"
|
|
}
|
|
```
|
|
|
|
### Invalid JSON
|
|
|
|
**Request**: Malformed JSON
|
|
|
|
**Response**:
|
|
```json
|
|
{
|
|
"success": false,
|
|
"error": "Invalid JSON format"
|
|
}
|
|
```
|
|
|
|
### Email Sending Errors
|
|
|
|
If Django SMTP fails to send the email, the error is caught and returned:
|
|
|
|
**Response**:
|
|
```json
|
|
{
|
|
"success": false,
|
|
"error": "SMTP error details..."
|
|
}
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Issue: Email not received
|
|
|
|
**Possible Causes**:
|
|
1. SMTP not configured correctly
|
|
2. Email in spam folder
|
|
3. Invalid recipient address
|
|
|
|
**Solutions**:
|
|
1. Check `.env` email settings
|
|
2. Check `logs/px360.log` for errors
|
|
3. Use mailcatcher for local testing:
|
|
```bash
|
|
pip install mailcatcher
|
|
mailcatcher
|
|
# Update .env: EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
|
|
# EMAIL_HOST=localhost, EMAIL_PORT=1025
|
|
```
|
|
|
|
### Issue: SMS not showing in terminal
|
|
|
|
**Possible Causes**:
|
|
1. Server not running in terminal
|
|
2. Output redirected to file
|
|
|
|
**Solutions**:
|
|
1. Ensure `python manage.py runserver` is running in visible terminal
|
|
2. Check `logs/px360.log` for SMS logs
|
|
|
|
### Issue: Simulator endpoints returning 404
|
|
|
|
**Possible Causes**:
|
|
1. Simulator app not in INSTALLED_APPS
|
|
2. URL not included in main urls.py
|
|
3. Server not restarted after adding app
|
|
|
|
**Solutions**:
|
|
1. Check `config/settings/base.py` includes `'apps.simulator'`
|
|
2. Check `config/urls.py` includes simulator URLs
|
|
3. Restart server: `python manage.py runserver`
|
|
|
|
### Issue: Health check shows 0 requests
|
|
|
|
**Possible Causes**:
|
|
1. Simulator not enabled in `.env`
|
|
2. Requests using wrong URLs
|
|
|
|
**Solutions**:
|
|
1. Check `EMAIL_API_ENABLED` and `SMS_API_ENABLED` are `true`
|
|
2. Verify URLs point to `localhost:8000/api/simulator/...`
|
|
|
|
## Advanced Usage
|
|
|
|
### Custom SMS Formatting
|
|
|
|
You can modify the SMS output format in `apps/simulator/views.py`. Look for the `sms_simulator` function and adjust the print statements.
|
|
|
|
### Request Middleware
|
|
|
|
Add custom middleware to intercept all simulator requests:
|
|
|
|
```python
|
|
# Create apps/simulator/middleware.py
|
|
class SimulatorLoggingMiddleware:
|
|
def __init__(self, get_response):
|
|
self.get_response = get_response
|
|
|
|
def __call__(self, request):
|
|
if '/api/simulator/' in request.path:
|
|
# Custom logging logic
|
|
pass
|
|
return self.get_response(request)
|
|
```
|
|
|
|
### Batch Testing
|
|
|
|
Test multiple notifications at once:
|
|
|
|
```python
|
|
from apps.notifications.services import NotificationService
|
|
|
|
test_data = [
|
|
{'email': 'user1@example.com', 'subject': 'Test 1'},
|
|
{'email': 'user2@example.com', 'subject': 'Test 2'},
|
|
]
|
|
|
|
for data in test_data:
|
|
NotificationService.send_email_via_api(
|
|
message=f'Test email for {data["email"]}',
|
|
email=data['email'],
|
|
subject=data['subject']
|
|
)
|
|
```
|
|
|
|
## Performance Considerations
|
|
|
|
- **Email Sending**: Each email makes an SMTP request (network latency)
|
|
- **SMS Printing**: Instant, no network overhead
|
|
- **Request History**: Limited to last 10 requests to prevent memory issues
|
|
- **Logging**: Rotating file handler prevents disk space issues
|
|
|
|
## Security Considerations
|
|
|
|
- **No Authentication Required**: Simulator endpoints are public by design
|
|
- **CSRF Exempt**: All endpoints exempt from CSRF checks
|
|
- **Production Use**: Disable simulator in production by not using simulator URLs
|
|
- **Sensitive Data**: Simulator logs may contain PII (phone numbers, emails)
|
|
|
|
## Best Practices
|
|
|
|
1. **Development Only**: Use simulator only in development/testing environments
|
|
2. **Environment-Specific Config**: Keep simulator URLs only in `.env.local` or `.env.development`
|
|
3. **Regular Resets**: Reset simulator counters between test runs
|
|
4. **Log Monitoring**: Check logs for any unexpected errors
|
|
5. **Test Coverage**: Include simulator tests in your test suite
|
|
|
|
## Related Documentation
|
|
|
|
- [External API Notification Service](EXTERNAL_API_NOTIFICATION.md)
|
|
- [Notification Service](../apps/notifications/README.md)
|
|
- [Environment Configuration](../config/settings/base.py)
|
|
|
|
## Support
|
|
|
|
For issues or questions:
|
|
|
|
1. Check logs: `logs/px360.log`
|
|
2. Verify `.env` configuration
|
|
3. Test endpoints with curl/Postman
|
|
4. Check simulator health: `GET /api/simulator/health`
|
|
|
|
## License
|
|
|
|
Part of the PX360 project. See project LICENSE for details.
|