Files
Munich-news/docs/ADMIN_API.md
2025-11-11 17:58:12 +01:00

8.1 KiB

Admin API Reference

Admin endpoints for testing and manual operations.

Overview

The admin API allows you to trigger manual operations like crawling news and sending test emails directly through HTTP requests.

How it works: The backend container has access to the Docker socket, allowing it to execute commands in other containers via docker exec.


API Endpoints

Trigger Crawler

Manually trigger the news crawler to fetch new articles.

POST /api/admin/trigger-crawl

Request Body (optional):

{
  "max_articles": 10
}

Parameters:

  • max_articles (integer, optional): Number of articles to crawl per feed (1-100, default: 10)

Response:

{
  "success": true,
  "message": "Crawler executed successfully",
  "max_articles": 10,
  "output": "... crawler output (last 1000 chars) ...",
  "errors": ""
}

Example:

# Crawl 5 articles per feed
curl -X POST http://localhost:5001/api/admin/trigger-crawl \
  -H "Content-Type: application/json" \
  -d '{"max_articles": 5}'

# Use default (10 articles)
curl -X POST http://localhost:5001/api/admin/trigger-crawl

Send Test Email

Send a test newsletter to a specific email address.

POST /api/admin/send-test-email

Request Body:

{
  "email": "test@example.com",
  "max_articles": 10
}

Parameters:

  • email (string, required): Email address to send test newsletter to
  • max_articles (integer, optional): Number of articles to include (1-50, default: 10)

Response:

{
  "success": true,
  "message": "Test email sent to test@example.com",
  "email": "test@example.com",
  "output": "... sender output ...",
  "errors": ""
}

Example:

# Send test email
curl -X POST http://localhost:5001/api/admin/send-test-email \
  -H "Content-Type: application/json" \
  -d '{"email": "your-email@example.com"}'

# Send with custom article count
curl -X POST http://localhost:5001/api/admin/send-test-email \
  -H "Content-Type: application/json" \
  -d '{"email": "your-email@example.com", "max_articles": 5}'

Send Newsletter to All Subscribers

Send newsletter to all active subscribers in the database.

POST /api/admin/send-newsletter

Request Body (optional):

{
  "max_articles": 10
}

Parameters:

  • max_articles (integer, optional): Number of articles to include (1-50, default: 10)

Response:

{
  "success": true,
  "message": "Newsletter sent successfully to 45 subscribers",
  "subscriber_count": 45,
  "max_articles": 10,
  "output": "... sender output ...",
  "errors": ""
}

Example:

# Send newsletter to all subscribers
curl -X POST http://localhost:5001/api/admin/send-newsletter \
  -H "Content-Type: application/json"

# Send with custom article count
curl -X POST http://localhost:5001/api/admin/send-newsletter \
  -H "Content-Type: application/json" \
  -d '{"max_articles": 15}'

Notes:

  • Only sends to subscribers with status: 'active'
  • Returns error if no active subscribers found
  • Includes tracking pixels and click tracking
  • May take several minutes for large subscriber lists

Get System Statistics

Get overview statistics of the system.

GET /api/admin/stats

Response:

{
  "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
  }
}

Example:

curl http://localhost:5001/api/admin/stats

Workflow Examples

Test Complete System

# 1. Check current stats
curl http://localhost:5001/api/admin/stats

# 2. Trigger crawler to fetch new articles
curl -X POST http://localhost:5001/api/admin/trigger-crawl \
  -H "Content-Type: application/json" \
  -d '{"max_articles": 5}'

# 3. Wait a moment for crawler to finish, then check stats again
sleep 30
curl http://localhost:5001/api/admin/stats

# 4. Send test email to yourself
curl -X POST http://localhost:5001/api/admin/send-test-email \
  -H "Content-Type: application/json" \
  -d '{"email": "your-email@example.com"}'

Send Newsletter to All Subscribers

# 1. Check subscriber count
curl http://localhost:5001/api/admin/stats | jq '.subscribers'

# 2. Crawl fresh articles
curl -X POST http://localhost:5001/api/admin/trigger-crawl \
  -H "Content-Type: application/json" \
  -d '{"max_articles": 10}'

# 3. Wait for crawl to complete
sleep 60

# 4. Send newsletter to all active subscribers
curl -X POST http://localhost:5001/api/admin/send-newsletter \
  -H "Content-Type: application/json" \
  -d '{"max_articles": 10}'

Quick Test Newsletter

# Send test email with latest articles
curl -X POST http://localhost:5001/api/admin/send-test-email \
  -H "Content-Type: application/json" \
  -d '{"email": "your-email@example.com", "max_articles": 3}'

Fetch Fresh Content

# Crawl more articles from each feed
curl -X POST http://localhost:5001/api/admin/trigger-crawl \
  -H "Content-Type: application/json" \
  -d '{"max_articles": 20}'

Daily Newsletter Workflow

# Complete daily workflow (can be automated with cron)

# 1. Crawl today's articles
curl -X POST http://localhost:5001/api/admin/trigger-crawl \
  -H "Content-Type: application/json" \
  -d '{"max_articles": 15}'

# 2. Wait for crawl and AI processing
sleep 120

# 3. Send to all subscribers
curl -X POST http://localhost:5001/api/admin/send-newsletter \
  -H "Content-Type: application/json" \
  -d '{"max_articles": 10}'

# 4. Check results
curl http://localhost:5001/api/admin/stats

Error Responses

All endpoints return standard error responses:

{
  "success": false,
  "error": "Error message here"
}

Common HTTP Status Codes:

  • 200 - Success
  • 400 - Bad request (invalid parameters)
  • 500 - Server error

Security Notes

⚠️ Important: These are admin endpoints and should be protected in production!

Recommendations:

  1. Add authentication/authorization
  2. Rate limiting
  3. IP whitelisting
  4. API key requirement
  5. Audit logging

Example protection (add to routes):

from functools import wraps
from flask import request

def require_api_key(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        api_key = request.headers.get('X-API-Key')
        if api_key != os.getenv('ADMIN_API_KEY'):
            return jsonify({'error': 'Unauthorized'}), 401
        return f(*args, **kwargs)
    return decorated_function

@admin_bp.route('/api/admin/trigger-crawl', methods=['POST'])
@require_api_key
def trigger_crawl():
    # ... endpoint code


Newsletter API Summary

Available Endpoints

Endpoint Purpose Recipient
/api/admin/send-test-email Test newsletter Single email (specified)
/api/admin/send-newsletter Production send All active subscribers
/api/admin/trigger-crawl Fetch articles N/A
/api/admin/stats System stats N/A

Subscriber Status

The system uses a status field to determine who receives newsletters:

  • active - Receives newsletters
  • inactive - Does not receive newsletters

See SUBSCRIBER_STATUS.md for details.

Quick Examples

Send to all subscribers:

curl -X POST http://localhost:5001/api/admin/send-newsletter \
  -H "Content-Type: application/json" \
  -d '{"max_articles": 10}'

Send test email:

curl -X POST http://localhost:5001/api/admin/send-test-email \
  -H "Content-Type: application/json" \
  -d '{"email": "test@example.com"}'

Check stats:

curl http://localhost:5001/api/admin/stats | jq '.subscribers'

Testing

Use the test script:

./test-newsletter-api.sh