AIDA / scripts /backfill_alert_notifications.py
destinyebuka's picture
fyp
6da2710
#!/usr/bin/env python3
"""
Backfill script to send missed alert notifications
Processes all active alerts and notifies users about matching listings they missed
"""
import asyncio
import sys
from pathlib import Path
# Add parent directory to path
sys.path.insert(0, str(Path(__file__).parent.parent))
from app.database import connect_db, disconnect_db, get_db
from app.services.alert_service import process_new_listing
from bson import ObjectId
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
async def backfill_alert_notifications():
"""Process all active listings against all active alerts"""
try:
# Connect to database
await connect_db()
db = await get_db()
# Get all active alerts
alerts = await db.search_alerts.find({"is_active": True}).to_list(length=None)
logger.info(f"Found {len(alerts)} active alerts")
if not alerts:
logger.info("No active alerts to process")
return
# Get all active listings
listings = await db.listings.find({"status": "active"}).to_list(length=None)
logger.info(f"Found {len(listings)} active listings")
if not listings:
logger.info("No active listings to process")
return
# Process each listing against all alerts
notification_count = 0
for listing in listings:
logger.info(f"Processing listing: {listing.get('title')} ({listing.get('_id')})")
try:
# Use the existing process_new_listing function which:
# - Checks all active alerts
# - Filters out owner's own alerts
# - Only notifies if last_notified_at is old enough
matches = await process_new_listing(listing)
if matches > 0:
notification_count += matches
logger.info(f" ✅ Sent {matches} notification(s)")
except Exception as e:
logger.error(f" ❌ Error processing listing {listing.get('_id')}: {e}")
continue
logger.info(f"\n{'='*60}")
logger.info(f"Backfill complete!")
logger.info(f"Processed {len(listings)} listings")
logger.info(f"Sent {notification_count} total notifications")
logger.info(f"{'='*60}\n")
except Exception as e:
logger.error(f"Backfill failed: {e}")
raise
finally:
await disconnect_db()
if __name__ == "__main__":
logger.info("Starting alert notification backfill...")
asyncio.run(backfill_alert_notifications())