import json import logging from datetime import datetime from typing import Optional import aiohttp from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.models.models import BotConversation, Bot1CSyncLog, BotSetting from app.settings_cache import SettingsCache logger = logging.getLogger(__name__) async def send_to_1c(db: AsyncSession, conversation: BotConversation) -> Optional[dict]: webhook_url = SettingsCache.get("1c_webhook_url") if not webhook_url: return None user = conversation.user category = conversation.category payload = { "conversation_id": conversation.id, "user": { "max_user_id": user.max_user_id, "first_name": user.first_name, "last_name": user.last_name, "phone": user.phone, "email": user.email, }, "inquiry": { "text": conversation.inquiry_text, "category": category.name if category else "", "priority": conversation.priority, "has_attachment": conversation.has_attachment, "attachment_type": conversation.attachment_type, }, "created_at": conversation.created_at.isoformat() if conversation.created_at else "", } sync_log = Bot1CSyncLog( conversation_id=conversation.id, status="pending", request_payload=json.dumps(payload, ensure_ascii=False), ) db.add(sync_log) await db.flush() try: async with aiohttp.ClientSession() as session: async with session.post(webhook_url, json=payload, timeout=aiohttp.ClientTimeout(total=30)) as resp: response_text = await resp.text() sync_log.status = "sent" if resp.status == 200 else "error" sync_log.response_payload = response_text sync_log.sent_at = datetime.now() await db.flush() if resp.status == 200: try: return await resp.json() except Exception: return {"raw": response_text} logger.warning(f"1C webhook returned {resp.status}: {response_text[:500]}") return None except Exception as e: logger.error(f"1C webhook error: {e}") sync_log.status = "error" sync_log.response_payload = str(e) sync_log.sent_at = datetime.now() await db.flush() return None async def handle_1c_response(db: AsyncSession, data: dict) -> bool: conversation_id = data.get("conversation_id") if not conversation_id: return False result = await db.execute(select(BotConversation).where(BotConversation.id == int(conversation_id))) conv = result.scalar_one_or_none() if not conv: return False sync_log = Bot1CSyncLog( conversation_id=conv.id, status="confirmed", response_payload=json.dumps(data, ensure_ascii=False), confirmed_at=datetime.now(), ) db.add(sync_log) status = data.get("status", "") if status: conv.status = status assigned = data.get("assigned_to", "") if assigned: conv.assigned_to = assigned await db.flush() return True