from fastapi import APIRouter, Request, Form, WebSocket, WebSocketDisconnect from fastapi.responses import HTMLResponse from fastapi.templating import Jinja2Templates from fastapi.security import APIKeyHeader from dotenv import load_dotenv import os import logging from .storage import store_message, get_all_messages load_dotenv() API_KEY = os.getenv("API_KEY") api_key_header = APIKeyHeader(name="x-api-key", auto_error=False) router = APIRouter() templates = Jinja2Templates(directory="app/templates") # Live WebSocket connecties active_connections = [] async def validate_api_key(api_key: str = None): if api_key != API_KEY: raise Exception("Unauthorized") async def broadcast(msg: str): for connection in active_connections: try: await connection.send_text(msg) except: continue @router.api_route("/webhook", methods=["GET", "POST"]) async def webhook(request: Request, api_key: str = api_key_header): await validate_api_key(api_key) body = await request.body() log_entry = { "method": request.method, "headers": dict(request.headers), "body": body.decode() } logging.info(f"Webhook received: {log_entry}") store_message(log_entry) await broadcast(str(log_entry)) # stuur live update via websocket return {"status": "ok"} @router.get("/trace", response_class=HTMLResponse) async def trace_page(request: Request): return templates.TemplateResponse("trace.html", { "request": request, "messages": get_all_messages() }) @router.websocket("/ws/trace") async def websocket_endpoint(websocket: WebSocket): await websocket.accept() active_connections.append(websocket) try: while True: await websocket.receive_text() # optioneel: keep-alive ping except WebSocketDisconnect: active_connections.remove(websocket) @router.get("/send", response_class=HTMLResponse) async def send_form(request: Request): return templates.TemplateResponse("send.html", {"request": request}) @router.post("/send") async def send_post(request: Request, url: str = Form(...), body: str = Form(...), key: str = Form(...)): import httpx headers = {"x-api-key": key} try: response = httpx.post(url, content=body, headers=headers) return { "status_code": response.status_code, "response": response.text } except Exception as e: return {"error": str(e)}