From cd2ff8e61b3bf32f3d3c3c067d2257970a82bfcb Mon Sep 17 00:00:00 2001 From: AI Assistant Date: Sun, 2 Nov 2025 10:40:57 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20backend=20proxy=20=D0=B4=D0=BB=D1=8F=20=D1=81?= =?UTF-8?q?=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D1=8F=20=D0=BA=D0=BE=D0=BD?= =?UTF-8?q?=D1=82=D0=B0=D0=BA=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Проблема: - Step1Phone делал запрос НАПРЯМУЮ к n8n (палил webhook URL) - В backend логах не было видно что n8n возвращает для контакта - Нельзя было отследить contact_id, claim_id, is_new_contact Решение: ✅ Добавлен endpoint /api/n8n/contact/create в n8n_proxy.py ✅ Step1Phone.tsx теперь использует proxy вместо прямого URL ✅ Backend логирует полный response от n8n (contact_id, claim_id и тд) Теперь весь трафик к n8n идёт через backend proxy! --- backend/app/api/n8n_proxy.py | 52 +++++++++++++++++++++ frontend/src/components/form/Step1Phone.tsx | 2 +- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/backend/app/api/n8n_proxy.py b/backend/app/api/n8n_proxy.py index 801a560..1643196 100644 --- a/backend/app/api/n8n_proxy.py +++ b/backend/app/api/n8n_proxy.py @@ -18,6 +18,7 @@ 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) +N8N_CREATE_CONTACT_WEBHOOK = getattr(settings, 'n8n_create_contact_webhook', 'https://n8n.clientright.pro/webhook/511fde97-88bb-4fb4-bea5-cafdc364be27') N8N_CREATE_CLAIM_WEBHOOK = getattr(settings, 'n8n_create_claim_webhook', 'https://n8n.clientright.pro/webhook/d5bf4ca6-9e44-44b9-9714-3186ea703e7d') @@ -64,6 +65,57 @@ async def proxy_policy_check(request: Request): raise HTTPException(status_code=500, detail=f"Ошибка проверки полиса: {str(e)}") +@router.post("/contact/create") +async def proxy_create_contact(request: Request): + """ + Проксирует создание контакта к n8n webhook + + Frontend отправляет: POST /api/n8n/contact/create + Backend проксирует к: https://n8n.clientright.pro/webhook/511fde97-88bb-4fb4-bea5-cafdc364be27 + """ + if not N8N_CREATE_CONTACT_WEBHOOK: + raise HTTPException(status_code=500, detail="N8N contact webhook не настроен") + + try: + body = await request.json() + + logger.info(f"🔄 Proxy create contact: phone={body.get('phone', 'unknown')}, session_id={body.get('session_id', 'unknown')}") + + async with httpx.AsyncClient(timeout=30.0) as client: + response = await client.post( + N8N_CREATE_CONTACT_WEBHOOK, + json=body, + headers={"Content-Type": "application/json"} + ) + + if response.status_code == 200: + response_text = response.text + logger.info(f"✅ Contact created successfully. Response: {response_text[:500]}") + + if not response_text or response_text.strip() == '': + logger.error(f"❌ N8N returned empty response") + raise HTTPException(status_code=500, detail="N8N вернул пустой ответ") + + try: + return response.json() + except Exception as e: + logger.error(f"❌ Failed to parse JSON: {e}. Response: {response_text[:500]}") + raise HTTPException(status_code=500, detail=f"Ошибка парсинга ответа n8n: {str(e)}") + 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(...), diff --git a/frontend/src/components/form/Step1Phone.tsx b/frontend/src/components/form/Step1Phone.tsx index 54bc176..b4f4e0b 100644 --- a/frontend/src/components/form/Step1Phone.tsx +++ b/frontend/src/components/form/Step1Phone.tsx @@ -91,7 +91,7 @@ export default function Step1Phone({ try { addDebugEvent?.('crm', 'info', '📞 Создание контакта в CRM...', { phone }); - const crmResponse = await fetch('https://n8n.clientright.pro/webhook/511fde97-88bb-4fb4-bea5-cafdc364be27', { + const crmResponse = await fetch('/api/n8n/contact/create', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({