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:
2026-05-24 07:50:38 +03:00
parent bd048ea23d
commit 493e0b37a1
127 changed files with 6082 additions and 65 deletions
+100
View File
@@ -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