from fastapi import APIRouter, Depends, HTTPException from pydantic import BaseModel, EmailStr from ...services.email_service import email_service from ...services.bounce_service import bounce_service from ...api.dependencies import get_admin_user from ...models.models import User from typing import Dict, Any, List from ...core.database import get_db from sqlalchemy.orm import Session router = APIRouter() router = APIRouter() class TestEmailRequest(BaseModel): to_email: EmailStr subject: str message: str class WelcomeEmailRequest(BaseModel): to_email: EmailStr first_name: str @router.post("/test-email") async def send_test_email( request: TestEmailRequest, current_user: User = Depends(get_admin_user), db: Session = Depends(get_db) ): """Send a test email (admin only)""" html_body = f"
{request.message}
" result = await email_service.send_email( to_email=request.to_email, subject=request.subject, html_body=html_body, text_body=request.message, db=db ) return {"success": True, "result": result} @router.post("/test-welcome-email") async def send_test_welcome_email( request: WelcomeEmailRequest, current_user: User = Depends(get_admin_user) ): """Send a test welcome email (admin only)""" result = await email_service.send_welcome_email( to_email=request.to_email, first_name=request.first_name ) return {"success": True, "result": result} @router.post("/webhooks/smtp2go/bounce") async def smtp2go_bounce_webhook( webhook_data: Dict[str, Any], db: Session = Depends(get_db) ): """ Webhook endpoint for SMTP2GO bounce notifications This endpoint should be configured in SMTP2GO webhook settings """ try: bounces_created = bounce_service.process_smtp2go_webhook(webhook_data, db) return { "success": True, "bounces_processed": len(bounces_created), "message": f"Successfully processed {len(bounces_created)} bounce events" } except Exception as e: raise HTTPException(status_code=500, detail=f"Failed to process bounce webhook: {str(e)}") @router.get("/bounces") async def get_bounce_list( skip: int = 0, limit: int = 100, current_user: User = Depends(get_admin_user), db: Session = Depends(get_db) ): """Get list of email bounces (admin only)""" from ...models.models import EmailBounce bounces = db.query(EmailBounce).offset(skip).limit(limit).all() total = db.query(EmailBounce).count() return { "bounces": [ { "id": bounce.id, "email": bounce.email, "bounce_type": bounce.bounce_type.value, "bounce_reason": bounce.bounce_reason, "bounce_date": bounce.bounce_date.isoformat(), "is_active": bounce.is_active, "smtp2go_message_id": bounce.smtp2go_message_id } for bounce in bounces ], "total": total, "skip": skip, "limit": limit } @router.get("/bounces/stats") async def get_bounce_statistics( current_user: User = Depends(get_admin_user), db: Session = Depends(get_db) ): """Get bounce statistics (admin only)""" stats = bounce_service.get_bounce_statistics(db) return stats @router.get("/bounces/{email}") async def get_bounce_history( email: str, current_user: User = Depends(get_admin_user) ): """Get bounce history for a specific email (admin only)""" bounces = bounce_service.get_bounce_history(email) return { "email": email, "bounces": [ { "id": bounce.id, "bounce_type": bounce.bounce_type.value, "bounce_reason": bounce.bounce_reason, "bounce_date": bounce.bounce_date.isoformat(), "is_active": bounce.is_active, "smtp2go_message_id": bounce.smtp2go_message_id } for bounce in bounces ] } @router.post("/bounces/cleanup") async def cleanup_old_bounces( days_old: int = 365, current_user: User = Depends(get_admin_user), db: Session = Depends(get_db) ): """Clean up old soft bounces (admin only)""" cleaned_count = bounce_service.cleanup_old_bounces(days_old, db) return { "success": True, "message": f"Cleaned up {cleaned_count} old soft bounce records" } @router.delete("/bounces/deactivate/{bounce_id}") async def deactivate_bounce( bounce_id: int, current_user: User = Depends(get_admin_user), db: Session = Depends(get_db) ): """Deactivate a bounce record (mark as resolved) (admin only)""" success = bounce_service.deactivate_bounce(bounce_id, db) if not success: raise HTTPException(status_code=404, detail="Bounce record not found") return {"success": True, "message": "Bounce record deactivated"}