from fastapi import FastAPI, Request, HTTPException from sqlmodel import Field, SQLModel, Session, create_engine, select from typing import Optional import os import httpx # --- Database Models --- class Hotel(SQLModel, table=True): id: Optional[int] = Field(default=None, primary_key=True) hotel_id: str = Field(index=True, unique=True) email: str # --- App Setup --- DATABASE_URL = "sqlite:////app/hotels.db" engine = create_engine(DATABASE_URL, echo=False) def create_db_and_tables(): SQLModel.metadata.create_all(engine) app = FastAPI() @app.on_event("startup") def on_startup(): create_db_and_tables() # --- API Endpoints --- @app.post("/contact") async def contact(request: Request): data = await request.json() hotel_id = data.get("hotel") name = data.get("name") sender_email = data.get("email") subject = data.get("subject") message = data.get("message") if not hotel_id or not message or not sender_email or not subject: raise HTTPException(status_code=400, detail="Missing required fields.") # Lookup hotel with Session(engine) as session: hotel = session.exec(select(Hotel).where(Hotel.hotel_id == hotel_id)).first() if not hotel: raise HTTPException(status_code=404, detail="Unknown hotel.") await send_brevo_email( to_email=hotel.email, from_name=name, reply_to_email=sender_email, subject=subject, message=message, ) return {"ok": True} async def send_brevo_email(to_email, from_name, reply_to_email, subject, message): api_key = os.getenv("BREVO_API_KEY") sender_email = os.getenv("BREVO_SENDER") payload = { "sender": {"name": from_name, "email": sender_email}, "replyTo": {"name": from_name, "email": reply_to_email}, "to": [{"email": to_email}], "subject": subject, "textContent": message, } async with httpx.AsyncClient() as client: r = await client.post( "https://api.brevo.com/v3/smtp/email", headers={"api-key": api_key, "accept": "application/json", "Content-Type": "application/json"}, json=payload, timeout=10, ) if r.status_code >= 400: raise HTTPException(status_code=500, detail=f"Email failed: {r.text}")