""" N8N Webhook Proxy Router Безопасное проксирование запросов к n8n webhooks. Frontend не знает прямых URL webhooks! """ import httpx import logging from fastapi import APIRouter, HTTPException, File, UploadFile, Form, Request from fastapi.responses import JSONResponse from typing import Optional from ..config import settings logger = logging.getLogger(__name__) router = APIRouter(prefix="/api/n8n", tags=["n8n-proxy"]) # URL webhooks из .env (будут добавлены) N8N_POLICY_CHECK_WEBHOOK = getattr(settings, 'n8n_policy_check_webhook', None) N8N_FILE_UPLOAD_WEBHOOK = getattr(settings, 'n8n_file_upload_webhook', None) @router.post("/policy/check") async def proxy_policy_check(request: Request): """ Проксирует проверку полиса к n8n webhook Frontend отправляет: POST /api/n8n/policy/check Backend проксирует к: https://n8n.clientright.pro/webhook/{uuid} """ if not N8N_POLICY_CHECK_WEBHOOK: raise HTTPException(status_code=500, detail="N8N webhook не настроен") try: # Получаем JSON body от фронтенда body = await request.json() logger.info(f"🔄 Proxy policy check: {body.get('policy_number', 'unknown')}") # Проксируем запрос к n8n async with httpx.AsyncClient(timeout=30.0) as client: response = await client.post( N8N_POLICY_CHECK_WEBHOOK, json=body, headers={"Content-Type": "application/json"} ) if response.status_code == 200: logger.info(f"✅ Policy check success") return response.json() else: logger.error(f"❌ N8N returned {response.status_code}: {response.text}") raise HTTPException( status_code=response.status_code, detail=f"N8N error: {response.text}" ) except httpx.TimeoutException: logger.error("⏱️ N8N webhook timeout") raise HTTPException(status_code=504, detail="Таймаут подключения к n8n") except Exception as e: logger.error(f"❌ Error proxying to n8n: {e}") raise HTTPException(status_code=500, detail=f"Ошибка проверки полиса: {str(e)}") @router.post("/upload/file") async def proxy_file_upload( file: UploadFile = File(...), claim_id: Optional[str] = Form(None), voucher: Optional[str] = Form(None), session_id: Optional[str] = Form(None), file_type: Optional[str] = Form(None) ): """ Проксирует загрузку файла к n8n webhook Frontend отправляет: POST /api/n8n/upload/file (multipart/form-data) Backend проксирует к: https://n8n.clientright.pro/webhook/{uuid} """ if not N8N_FILE_UPLOAD_WEBHOOK: raise HTTPException(status_code=500, detail="N8N upload webhook не настроен") try: logger.info(f"🔄 Proxy file upload: {file.filename} for claim {claim_id}") # Читаем файл file_content = await file.read() # Формируем multipart/form-data для n8n files = { 'file': (file.filename, file_content, file.content_type) } data = {} if claim_id: data['claim_id'] = claim_id if voucher: data['voucher'] = voucher if session_id: data['session_id'] = session_id if file_type: data['file_type'] = file_type # Проксируем запрос к n8n async with httpx.AsyncClient(timeout=60.0) as client: response = await client.post( N8N_FILE_UPLOAD_WEBHOOK, files=files, data=data ) if response.status_code == 200: logger.info(f"✅ File upload success") return response.json() else: logger.error(f"❌ N8N returned {response.status_code}: {response.text}") raise HTTPException( status_code=response.status_code, detail=f"N8N error: {response.text}" ) except httpx.TimeoutException: logger.error("⏱️ N8N webhook timeout") raise HTTPException(status_code=504, detail="Таймаут загрузки файла") except Exception as e: logger.error(f"❌ Error proxying file to n8n: {e}") raise HTTPException(status_code=500, detail=f"Ошибка загрузки файла: {str(e)}")