This commit is contained in:
2025-11-11 14:09:21 +01:00
parent bcd0a10576
commit 1075a91eac
57 changed files with 5598 additions and 1366 deletions

View File

@@ -0,0 +1,127 @@
"""
Analytics routes for email tracking metrics and subscriber engagement.
"""
from flask import Blueprint, jsonify, request
from services.analytics_service import (
get_newsletter_metrics,
get_article_performance,
get_subscriber_activity_status,
update_subscriber_activity_statuses
)
from database import subscriber_activity_collection
analytics_bp = Blueprint('analytics', __name__)
@analytics_bp.route('/api/analytics/newsletter/<newsletter_id>', methods=['GET'])
def get_newsletter_analytics(newsletter_id):
"""
Get comprehensive metrics for a specific newsletter.
Args:
newsletter_id: Unique identifier for the newsletter batch
Returns:
JSON response with newsletter metrics including:
- total_sent, total_opened, open_rate
- total_clicks, unique_clickers, click_through_rate
"""
try:
metrics = get_newsletter_metrics(newsletter_id)
return jsonify(metrics), 200
except Exception as e:
return jsonify({'error': str(e)}), 500
@analytics_bp.route('/api/analytics/article/<path:article_url>', methods=['GET'])
def get_article_analytics(article_url):
"""
Get performance metrics for a specific article.
Args:
article_url: The original article URL (passed as path parameter)
Returns:
JSON response with article performance metrics including:
- total_sent, total_clicks, click_rate
- unique_clickers, newsletters
"""
try:
performance = get_article_performance(article_url)
return jsonify(performance), 200
except Exception as e:
return jsonify({'error': str(e)}), 500
@analytics_bp.route('/api/analytics/subscriber/<email>', methods=['GET'])
def get_subscriber_analytics(email):
"""
Get activity status and engagement metrics for a specific subscriber.
Args:
email: Subscriber email address
Returns:
JSON response with subscriber activity data including:
- status, last_opened_at, last_clicked_at
- total_opens, total_clicks
- newsletters_received, newsletters_opened
"""
try:
# Get current activity status
status = get_subscriber_activity_status(email)
# Get detailed activity record from database
activity_record = subscriber_activity_collection.find_one(
{'email': email},
{'_id': 0} # Exclude MongoDB _id field
)
if activity_record:
# Convert datetime objects to ISO format strings
if activity_record.get('last_opened_at'):
activity_record['last_opened_at'] = activity_record['last_opened_at'].isoformat()
if activity_record.get('last_clicked_at'):
activity_record['last_clicked_at'] = activity_record['last_clicked_at'].isoformat()
if activity_record.get('updated_at'):
activity_record['updated_at'] = activity_record['updated_at'].isoformat()
return jsonify(activity_record), 200
else:
# Return basic status if no detailed record exists yet
return jsonify({
'email': email,
'status': status,
'last_opened_at': None,
'last_clicked_at': None,
'total_opens': 0,
'total_clicks': 0,
'newsletters_received': 0,
'newsletters_opened': 0
}), 200
except Exception as e:
return jsonify({'error': str(e)}), 500
@analytics_bp.route('/api/analytics/update-activity', methods=['POST'])
def update_activity_statuses():
"""
Trigger batch update of subscriber activity statuses.
Updates the subscriber_activity collection with current engagement
metrics for all subscribers.
Returns:
JSON response with count of updated records
"""
try:
updated_count = update_subscriber_activity_statuses()
return jsonify({
'success': True,
'updated_count': updated_count,
'message': f'Updated activity status for {updated_count} subscribers'
}), 200
except Exception as e:
return jsonify({'error': str(e)}), 500