update
This commit is contained in:
379
docs/API.md
379
docs/API.md
@@ -1,214 +1,248 @@
|
||||
# API Reference
|
||||
|
||||
## Tracking Endpoints
|
||||
Complete API documentation for Munich News Daily.
|
||||
|
||||
### Track Email Open
|
||||
---
|
||||
|
||||
## Admin API
|
||||
|
||||
Base URL: `http://localhost:5001`
|
||||
|
||||
### Trigger Crawler
|
||||
|
||||
Manually fetch new articles.
|
||||
|
||||
```http
|
||||
GET /api/track/pixel/<tracking_id>
|
||||
```
|
||||
POST /api/admin/trigger-crawl
|
||||
Content-Type: application/json
|
||||
|
||||
Returns a 1x1 transparent PNG and logs the email open event.
|
||||
|
||||
**Response**: Image (image/png)
|
||||
|
||||
### Track Link Click
|
||||
|
||||
```http
|
||||
GET /api/track/click/<tracking_id>
|
||||
```
|
||||
|
||||
Logs the click event and redirects to the original article URL.
|
||||
|
||||
**Response**: 302 Redirect
|
||||
|
||||
## Analytics Endpoints
|
||||
|
||||
### Get Newsletter Metrics
|
||||
|
||||
```http
|
||||
GET /api/analytics/newsletter/<newsletter_id>
|
||||
```
|
||||
|
||||
Returns comprehensive metrics for a specific newsletter.
|
||||
|
||||
**Response**:
|
||||
```json
|
||||
{
|
||||
"newsletter_id": "2024-01-15",
|
||||
"total_sent": 100,
|
||||
"total_opened": 75,
|
||||
"open_rate": 75.0,
|
||||
"unique_openers": 70,
|
||||
"total_clicks": 45,
|
||||
"unique_clickers": 30,
|
||||
"click_through_rate": 30.0
|
||||
"max_articles": 10
|
||||
}
|
||||
```
|
||||
|
||||
### Get Article Performance
|
||||
|
||||
```http
|
||||
GET /api/analytics/article/<article_url>
|
||||
**Example:**
|
||||
```bash
|
||||
curl -X POST http://localhost:5001/api/admin/trigger-crawl \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"max_articles": 5}'
|
||||
```
|
||||
|
||||
Returns performance metrics for a specific article.
|
||||
---
|
||||
|
||||
### Send Test Email
|
||||
|
||||
Send newsletter to specific email.
|
||||
|
||||
```http
|
||||
POST /api/admin/send-test-email
|
||||
Content-Type: application/json
|
||||
|
||||
**Response**:
|
||||
```json
|
||||
{
|
||||
"article_url": "https://example.com/article",
|
||||
"total_sent": 100,
|
||||
"total_clicks": 25,
|
||||
"click_rate": 25.0,
|
||||
"unique_clickers": 20,
|
||||
"newsletters": ["2024-01-15", "2024-01-16"]
|
||||
"email": "test@example.com",
|
||||
"max_articles": 10
|
||||
}
|
||||
```
|
||||
|
||||
### Get Subscriber Activity
|
||||
|
||||
```http
|
||||
GET /api/analytics/subscriber/<email>
|
||||
**Example:**
|
||||
```bash
|
||||
curl -X POST http://localhost:5001/api/admin/send-test-email \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"email": "your@email.com"}'
|
||||
```
|
||||
|
||||
Returns activity status and engagement metrics for a subscriber.
|
||||
---
|
||||
|
||||
### Send Newsletter to All Subscribers
|
||||
|
||||
Send newsletter to all active subscribers.
|
||||
|
||||
```http
|
||||
POST /api/admin/send-newsletter
|
||||
Content-Type: application/json
|
||||
|
||||
**Response**:
|
||||
```json
|
||||
{
|
||||
"email": "user@example.com",
|
||||
"status": "active",
|
||||
"last_opened_at": "2024-01-15T10:30:00",
|
||||
"last_clicked_at": "2024-01-15T10:35:00",
|
||||
"total_opens": 45,
|
||||
"total_clicks": 20,
|
||||
"newsletters_received": 50,
|
||||
"newsletters_opened": 45
|
||||
"max_articles": 10
|
||||
}
|
||||
```
|
||||
|
||||
## Privacy Endpoints
|
||||
|
||||
### Delete Subscriber Data
|
||||
|
||||
```http
|
||||
DELETE /api/tracking/subscriber/<email>
|
||||
```
|
||||
|
||||
Deletes all tracking data for a subscriber (GDPR compliance).
|
||||
|
||||
**Response**:
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "All tracking data deleted for user@example.com",
|
||||
"deleted_counts": {
|
||||
"newsletter_sends": 50,
|
||||
"link_clicks": 25,
|
||||
"subscriber_activity": 1
|
||||
"message": "Newsletter sent successfully to 45 subscribers",
|
||||
"subscriber_count": 45,
|
||||
"max_articles": 10
|
||||
}
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
curl -X POST http://localhost:5001/api/admin/send-newsletter \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"max_articles": 10}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Get System Stats
|
||||
|
||||
```http
|
||||
GET /api/admin/stats
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"articles": {
|
||||
"total": 150,
|
||||
"with_summary": 120,
|
||||
"today": 15
|
||||
},
|
||||
"subscribers": {
|
||||
"total": 50,
|
||||
"active": 45
|
||||
},
|
||||
"rss_feeds": {
|
||||
"total": 4,
|
||||
"active": 4
|
||||
},
|
||||
"tracking": {
|
||||
"total_sends": 200,
|
||||
"total_opens": 150,
|
||||
"total_clicks": 75
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Anonymize Old Data
|
||||
**Example:**
|
||||
```bash
|
||||
curl http://localhost:5001/api/admin/stats
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Public API
|
||||
|
||||
### Subscribe
|
||||
|
||||
```http
|
||||
POST /api/tracking/anonymize
|
||||
```
|
||||
POST /api/subscribe
|
||||
Content-Type: application/json
|
||||
|
||||
Anonymizes tracking data older than the retention period.
|
||||
|
||||
**Request Body** (optional):
|
||||
```json
|
||||
{
|
||||
"retention_days": 90
|
||||
"email": "user@example.com"
|
||||
}
|
||||
```
|
||||
|
||||
**Response**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "Anonymized tracking data older than 90 days",
|
||||
"anonymized_counts": {
|
||||
"newsletter_sends": 1250,
|
||||
"link_clicks": 650
|
||||
}
|
||||
}
|
||||
**Example:**
|
||||
```bash
|
||||
curl -X POST http://localhost:5001/api/subscribe \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"email": "user@example.com"}'
|
||||
```
|
||||
|
||||
### Opt Out of Tracking
|
||||
---
|
||||
|
||||
### Unsubscribe
|
||||
|
||||
```http
|
||||
POST /api/tracking/subscriber/<email>/opt-out
|
||||
```
|
||||
POST /api/unsubscribe
|
||||
Content-Type: application/json
|
||||
|
||||
Disables tracking for a subscriber.
|
||||
|
||||
**Response**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "Subscriber user@example.com has opted out of tracking"
|
||||
"email": "user@example.com"
|
||||
}
|
||||
```
|
||||
|
||||
### Opt In to Tracking
|
||||
|
||||
```http
|
||||
POST /api/tracking/subscriber/<email>/opt-in
|
||||
**Example:**
|
||||
```bash
|
||||
curl -X POST http://localhost:5001/api/unsubscribe \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"email": "user@example.com"}'
|
||||
```
|
||||
|
||||
Re-enables tracking for a subscriber.
|
||||
---
|
||||
|
||||
**Response**:
|
||||
```json
|
||||
## Subscriber Status System
|
||||
|
||||
### Status Values
|
||||
|
||||
| Status | Description | Receives Newsletters |
|
||||
|--------|-------------|---------------------|
|
||||
| `active` | Subscribed | ✅ Yes |
|
||||
| `inactive` | Unsubscribed | ❌ No |
|
||||
|
||||
### Database Schema
|
||||
|
||||
```javascript
|
||||
{
|
||||
"success": true,
|
||||
"message": "Subscriber user@example.com has opted in to tracking"
|
||||
_id: ObjectId("..."),
|
||||
email: "user@example.com",
|
||||
subscribed_at: ISODate("2025-11-11T15:50:29.478Z"),
|
||||
status: "active" // or "inactive"
|
||||
}
|
||||
```
|
||||
|
||||
## Examples
|
||||
### How It Works
|
||||
|
||||
### Using curl
|
||||
**Subscribe:**
|
||||
- Creates subscriber with `status: 'active'`
|
||||
- If already exists and inactive, reactivates
|
||||
|
||||
**Unsubscribe:**
|
||||
- Updates `status: 'inactive'`
|
||||
- Subscriber data preserved (soft delete)
|
||||
|
||||
**Newsletter Sending:**
|
||||
- Only sends to `status: 'active'` subscribers
|
||||
- Query: `{status: 'active'}`
|
||||
|
||||
### Check Active Subscribers
|
||||
|
||||
```bash
|
||||
# Get newsletter metrics
|
||||
curl http://localhost:5001/api/analytics/newsletter/2024-01-15
|
||||
curl http://localhost:5001/api/admin/stats | jq '.subscribers'
|
||||
# Output: {"total": 10, "active": 8}
|
||||
```
|
||||
|
||||
# Delete subscriber data
|
||||
curl -X DELETE http://localhost:5001/api/tracking/subscriber/user@example.com
|
||||
---
|
||||
|
||||
# Anonymize old data
|
||||
curl -X POST http://localhost:5001/api/tracking/anonymize \
|
||||
## Workflows
|
||||
|
||||
### Complete Newsletter Workflow
|
||||
|
||||
```bash
|
||||
# 1. Check stats
|
||||
curl http://localhost:5001/api/admin/stats
|
||||
|
||||
# 2. Crawl articles
|
||||
curl -X POST http://localhost:5001/api/admin/trigger-crawl \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"retention_days": 90}'
|
||||
-d '{"max_articles": 10}'
|
||||
|
||||
# Opt out of tracking
|
||||
curl -X POST http://localhost:5001/api/tracking/subscriber/user@example.com/opt-out
|
||||
# 3. Wait for crawl
|
||||
sleep 60
|
||||
|
||||
# 4. Send newsletter
|
||||
curl -X POST http://localhost:5001/api/admin/send-newsletter \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"max_articles": 10}'
|
||||
```
|
||||
|
||||
### Using Python
|
||||
### Test Newsletter
|
||||
|
||||
```python
|
||||
import requests
|
||||
|
||||
# Get newsletter metrics
|
||||
response = requests.get('http://localhost:5001/api/analytics/newsletter/2024-01-15')
|
||||
metrics = response.json()
|
||||
print(f"Open rate: {metrics['open_rate']}%")
|
||||
|
||||
# Delete subscriber data
|
||||
response = requests.delete('http://localhost:5001/api/tracking/subscriber/user@example.com')
|
||||
result = response.json()
|
||||
print(result['message'])
|
||||
```bash
|
||||
# Send test to yourself
|
||||
curl -X POST http://localhost:5001/api/admin/send-test-email \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"email": "your@email.com", "max_articles": 3}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Error Responses
|
||||
|
||||
All endpoints return standard error responses:
|
||||
All endpoints return standard error format:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -217,7 +251,64 @@ All endpoints return standard error responses:
|
||||
}
|
||||
```
|
||||
|
||||
HTTP Status Codes:
|
||||
**HTTP Status Codes:**
|
||||
- `200` - Success
|
||||
- `400` - Bad request
|
||||
- `404` - Not found
|
||||
- `500` - Server error
|
||||
|
||||
---
|
||||
|
||||
## Security
|
||||
|
||||
⚠️ **Production Recommendations:**
|
||||
|
||||
1. **Add Authentication**
|
||||
```python
|
||||
@require_api_key
|
||||
def admin_endpoint():
|
||||
# ...
|
||||
```
|
||||
|
||||
2. **Rate Limiting**
|
||||
- Prevent abuse
|
||||
- Limit newsletter sends
|
||||
|
||||
3. **IP Whitelisting**
|
||||
- Restrict admin endpoints
|
||||
- Use firewall rules
|
||||
|
||||
4. **HTTPS Only**
|
||||
- Use reverse proxy
|
||||
- SSL/TLS certificates
|
||||
|
||||
5. **Audit Logging**
|
||||
- Log all admin actions
|
||||
- Monitor for suspicious activity
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
Use the test script:
|
||||
```bash
|
||||
./test-newsletter-api.sh
|
||||
```
|
||||
|
||||
Or test manually:
|
||||
```bash
|
||||
# Health check
|
||||
curl http://localhost:5001/health
|
||||
|
||||
# Stats
|
||||
curl http://localhost:5001/api/admin/stats
|
||||
|
||||
# Test email
|
||||
curl -X POST http://localhost:5001/api/admin/send-test-email \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"email": "test@example.com"}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
See [SETUP.md](SETUP.md) for configuration and [SECURITY.md](SECURITY.md) for security best practices.
|
||||
|
||||
Reference in New Issue
Block a user