101 lines
3.2 KiB
Python
101 lines
3.2 KiB
Python
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
|