v1.6.0: max_bot fixes — feature keys, flush→commit, test-run, categories, broadcast page, proxy error handling, deploy scripts
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
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
|
||||
Reference in New Issue
Block a user