87 lines
2.6 KiB
Python

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)
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
# TODO have some domain list lying around somewhere on the server and pass it to containers
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Or specify your frontend domain(s)
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@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}")