Arag / app /api /contact.py
AuthorBot
Add enterprise growth APIs, billing, admin UI, and test suite.
12930b5
Raw
History Blame Contribute Delete
2.41 kB
"""Author RAG β€” Contact Form API.
Route:
POST /api/contact β†’ validate form fields β†’ send email to support inbox
Replaces the fake setTimeout in the Next.js Contact component.
"""
import structlog
from fastapi import APIRouter, Depends, HTTPException, Request
from pydantic import BaseModel, EmailStr, Field
from app.config import get_settings
from app.services.email_service import EmailService
logger = structlog.get_logger(__name__)
cfg = get_settings()
router = APIRouter(prefix="/contact", tags=["Contact"])
class ContactRequest(BaseModel):
first_name: str = Field(..., min_length=1, max_length=100)
last_name: str = Field(..., min_length=1, max_length=100)
email: EmailStr
message: str = Field(..., min_length=10, max_length=5000)
# Optional β€” prefilled if they clicked "Get Started" from a specific plan
plan_interest: str | None = Field(None, max_length=50)
@router.post("/")
async def submit_contact(
body: ContactRequest,
request: Request,
):
"""Handle contact form submission from the Next.js marketing website.
Sends an email to the support inbox defined by SUPPORT_EMAIL in config.
Always returns 200 to prevent spam enumeration.
"""
subject = f"New contact: {body.first_name} {body.last_name}"
if body.plan_interest:
subject += f" [interested in {body.plan_interest}]"
body_text = (
f"Name: {body.first_name} {body.last_name}\n"
f"Email: {body.email}\n"
f"Plan interest: {body.plan_interest or 'not specified'}\n"
f"IP: {request.client.host if request.client else 'unknown'}\n\n"
f"Message:\n{body.message}"
)
try:
email_svc = EmailService()
target = cfg.SUPPORT_EMAIL or cfg.EMAIL_FROM_ADDRESS
if target:
email_svc._send(
to=str(target),
subject=subject,
body=body_text,
)
logger.info(
"Contact form submitted",
email=body.email,
plan=body.plan_interest,
)
else:
logger.warning("SUPPORT_EMAIL not configured β€” contact form email dropped")
except Exception as e:
# Log but don't surface the error to the user
logger.error("Contact form email failed", error=str(e))
return {"message": "Thanks! We'll be in touch within one business day."}