from fastapi import APIRouter, Depends, HTTPException, Request from pydantic import BaseModel from sqlalchemy.orm import Session from database import get_db, DiscountCode import datetime import logging from gmail_service import GmailService import re router = APIRouter(prefix="/api/publish-request", tags=["publish-request"]) logger = logging.getLogger("publish-request") class CodesUpload(BaseModel): codes: str # comma separated @router.get("/stats") def get_stats(db: Session = Depends(get_db)): total = db.query(DiscountCode).count() used = db.query(DiscountCode).filter(DiscountCode.is_used == 1).count() available = total - used return {"total": total, "used": used, "available": available} @router.post("/codes") def upload_codes(data: CodesUpload, db: Session = Depends(get_db)): codes_list = [c.strip() for c in data.codes.split(",") if c.strip()] added = 0 for code in set(codes_list): existing = db.query(DiscountCode).filter(DiscountCode.code == code).first() if not existing: new_code = DiscountCode(code=code, is_used=0) db.add(new_code) added += 1 db.commit() return {"status": "success", "added": added} class WebhookData(BaseModel): email: str @router.post("/webhook") async def handle_webhook(request: Request, db: Session = Depends(get_db)): # Try to parse JSON from Google Forms webhook try: data = await request.json() except: raise HTTPException(status_code=400, detail="Invalid JSON") # We expect {"email": "..."} or similar from the Google Apps Script email = data.get("email") or data.get("Email") if not email: logger.error(f"Webhook received without email: {data}") return {"status": "error", "message": "Email not found in webhook payload"} email = email.strip().lower() # Check if this email already got a code already_assigned = db.query(DiscountCode).filter(DiscountCode.assigned_to_email == email).first() if already_assigned: logger.info(f"Email {email} already received code {already_assigned.code}") return {"status": "success", "message": "Already sent"} # Get a free code free_code = db.query(DiscountCode).filter(DiscountCode.is_used == 0).first() if not free_code: logger.error("NO FREE DISCOUNT CODES LEFT!") # Fallback logic: Notify admin? return {"status": "error", "message": "No codes available"} # Mark as used free_code.is_used = 1 free_code.assigned_to_email = email free_code.used_at = datetime.datetime.utcnow() db.commit() # Send Thank You Email with GmailService service = GmailService(db) subject = "Dankeschön für Eure Freigabe & Euer Rabattcode" # HTML Signature from frontend SIGNATURE_HTML = """


Liebe Grüße,
Euer Team von Kinderfotos Erding

Zierl Fotografen GmbH
Anton-Bruckner-Straße 5
85435 Erding

www.kinderfotos-erding.de

""" body_html = f"""

Hallo,

vielen Dank für Eure Unterstützung und das Ausfüllen der Freigabe!

Als kleines Dankeschön hier Euer 25 € Rabattcode für Eure Bestellung:

{free_code.code}

Bitte wartet mit Eurer Bestellung, falls Ihr noch nicht bestellt habt, bis Ihr diesen Code an der Kasse einlösen könnt.

{SIGNATURE_HTML} """ try: success = service.send_email(email, subject, body_html) if success: logger.info(f"Successfully sent code {free_code.code} to {email}") return {"status": "success", "message": "Email sent"} else: logger.error(f"Failed to send email to {email}") free_code.is_used = 0 free_code.assigned_to_email = None free_code.used_at = None db.commit() return {"status": "error", "message": "Failed to send email"} except Exception as e: logger.exception("Error sending webhook email") free_code.is_used = 0 free_code.assigned_to_email = None free_code.used_at = None db.commit() return {"status": "error", "message": str(e)}