update
This commit is contained in:
@@ -11,8 +11,17 @@ from pathlib import Path
|
||||
from jinja2 import Template
|
||||
from pymongo import MongoClient
|
||||
import os
|
||||
import sys
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# Add backend directory to path for importing tracking service
|
||||
backend_dir = Path(__file__).parent.parent / 'backend'
|
||||
sys.path.insert(0, str(backend_dir))
|
||||
|
||||
# Import tracking modules
|
||||
from services import tracking_service
|
||||
from tracking_integration import inject_tracking_pixel, replace_article_links, generate_tracking_urls
|
||||
|
||||
# Load environment variables from backend/.env
|
||||
backend_dir = Path(__file__).parent.parent / 'backend'
|
||||
env_path = backend_dir / '.env'
|
||||
@@ -40,6 +49,11 @@ class Config:
|
||||
MAX_ARTICLES = int(os.getenv('NEWSLETTER_MAX_ARTICLES', '10'))
|
||||
HOURS_LOOKBACK = int(os.getenv('NEWSLETTER_HOURS_LOOKBACK', '24'))
|
||||
WEBSITE_URL = os.getenv('WEBSITE_URL', 'http://localhost:3000')
|
||||
|
||||
# Tracking
|
||||
TRACKING_ENABLED = os.getenv('TRACKING_ENABLED', 'true').lower() == 'true'
|
||||
TRACKING_API_URL = os.getenv('TRACKING_API_URL', 'http://localhost:5001')
|
||||
TRACKING_DATA_RETENTION_DAYS = int(os.getenv('TRACKING_DATA_RETENTION_DAYS', '90'))
|
||||
|
||||
|
||||
# MongoDB connection
|
||||
@@ -117,15 +131,20 @@ def get_active_subscribers():
|
||||
return [doc['email'] for doc in cursor]
|
||||
|
||||
|
||||
def render_newsletter_html(articles):
|
||||
def render_newsletter_html(articles, tracking_enabled=False, pixel_tracking_id=None,
|
||||
link_tracking_map=None, api_url=None):
|
||||
"""
|
||||
Render newsletter HTML from template
|
||||
Render newsletter HTML from template with optional tracking integration
|
||||
|
||||
Args:
|
||||
articles: List of article dictionaries
|
||||
tracking_enabled: Whether to inject tracking pixel and replace links
|
||||
pixel_tracking_id: Tracking ID for the email open pixel
|
||||
link_tracking_map: Dictionary mapping original URLs to tracking IDs
|
||||
api_url: Base URL for the tracking API
|
||||
|
||||
Returns:
|
||||
str: Rendered HTML content
|
||||
str: Rendered HTML content with tracking injected if enabled
|
||||
"""
|
||||
# Load template
|
||||
template_path = Path(__file__).parent / 'newsletter_template.html'
|
||||
@@ -142,11 +161,23 @@ def render_newsletter_html(articles):
|
||||
'article_count': len(articles),
|
||||
'articles': articles,
|
||||
'unsubscribe_link': f'{Config.WEBSITE_URL}/unsubscribe',
|
||||
'website_link': Config.WEBSITE_URL
|
||||
'website_link': Config.WEBSITE_URL,
|
||||
'tracking_enabled': tracking_enabled
|
||||
}
|
||||
|
||||
# Render HTML
|
||||
return template.render(**template_data)
|
||||
html = template.render(**template_data)
|
||||
|
||||
# Inject tracking if enabled
|
||||
if tracking_enabled and pixel_tracking_id and api_url:
|
||||
# Inject tracking pixel
|
||||
html = inject_tracking_pixel(html, pixel_tracking_id, api_url)
|
||||
|
||||
# Replace article links with tracking URLs
|
||||
if link_tracking_map:
|
||||
html = replace_article_links(html, link_tracking_map, api_url)
|
||||
|
||||
return html
|
||||
|
||||
|
||||
def send_email(to_email, subject, html_content):
|
||||
@@ -246,14 +277,14 @@ def send_newsletter(max_articles=None, test_email=None):
|
||||
'error': 'No active subscribers'
|
||||
}
|
||||
|
||||
# Render newsletter
|
||||
print("\nRendering newsletter HTML...")
|
||||
html_content = render_newsletter_html(articles)
|
||||
print("✓ Newsletter rendered")
|
||||
# Generate newsletter ID (date-based)
|
||||
newsletter_id = f"newsletter-{datetime.now().strftime('%Y-%m-%d')}"
|
||||
|
||||
# Send to subscribers
|
||||
subject = f"Munich News Daily - {datetime.now().strftime('%B %d, %Y')}"
|
||||
print(f"\nSending newsletter: '{subject}'")
|
||||
print(f"Newsletter ID: {newsletter_id}")
|
||||
print(f"Tracking enabled: {Config.TRACKING_ENABLED}")
|
||||
print("-" * 70)
|
||||
|
||||
sent_count = 0
|
||||
@@ -262,6 +293,34 @@ def send_newsletter(max_articles=None, test_email=None):
|
||||
|
||||
for i, email in enumerate(subscribers, 1):
|
||||
print(f"[{i}/{len(subscribers)}] Sending to {email}...", end=' ')
|
||||
|
||||
# Generate tracking data for this subscriber if tracking is enabled
|
||||
if Config.TRACKING_ENABLED:
|
||||
try:
|
||||
tracking_data = generate_tracking_urls(
|
||||
articles=articles,
|
||||
newsletter_id=newsletter_id,
|
||||
subscriber_email=email,
|
||||
tracking_service=tracking_service
|
||||
)
|
||||
|
||||
# Render newsletter with tracking
|
||||
html_content = render_newsletter_html(
|
||||
articles=articles,
|
||||
tracking_enabled=True,
|
||||
pixel_tracking_id=tracking_data['pixel_tracking_id'],
|
||||
link_tracking_map=tracking_data['link_tracking_map'],
|
||||
api_url=Config.TRACKING_API_URL
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"⚠ Tracking error: {e}, sending without tracking...", end=' ')
|
||||
# Fallback: send without tracking
|
||||
html_content = render_newsletter_html(articles)
|
||||
else:
|
||||
# Render newsletter without tracking
|
||||
html_content = render_newsletter_html(articles)
|
||||
|
||||
# Send email
|
||||
success, error = send_email(email, subject, html_content)
|
||||
|
||||
if success:
|
||||
@@ -310,12 +369,11 @@ def preview_newsletter(max_articles=None, hours=None):
|
||||
today_date = datetime.now().strftime('%B %d, %Y')
|
||||
return f"<h1>No articles from today found</h1><p>No articles published today ({today_date}). Run the crawler with Ollama enabled to get fresh content.</p>"
|
||||
|
||||
return render_newsletter_html(articles)
|
||||
# Preview without tracking
|
||||
return render_newsletter_html(articles, tracking_enabled=False)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
|
||||
# Parse command line arguments
|
||||
if len(sys.argv) > 1:
|
||||
command = sys.argv[1]
|
||||
|
||||
Reference in New Issue
Block a user