import datetime import logging from sqlalchemy import select from app.database import async_session from app.models import BotUser, BotConversation, BotMessage, BotTicket, BotTicketMessage, BotTicketStatus from app.max_api import max_api from app.settings_cache import settings_cache from app.email_sender import email_sender logger = logging.getLogger(__name__) MOSCOW_TZ = datetime.timezone(datetime.timedelta(hours=3)) def moscow_now(): return datetime.datetime.now(MOSCOW_TZ).replace(tzinfo=None) async def handle_inquiry(user_id: int, conv_id: int, text: str) -> None: async with async_session() as db: result = await db.execute( select(BotConversation).where(BotConversation.id == conv_id) ) conv = result.scalar_one_or_none() if not conv: return user_result = await db.execute(select(BotUser).where(BotUser.id == user_id)) user = user_result.scalar_one_or_none() if not user: await max_api.send_message( user_id, "Произошла ошибка при обработке запроса. Пожалуйста, попробуйте ещё раз позже.", conversation_id=conv_id, ) return conv.inquiry_text = text conv.state = "escalated" await _finalize_ticket_in_tx(db, user_id, conv, user, text) await db.commit() async def _finalize_ticket_in_tx( db, user_id: int, conv: BotConversation, user: BotUser, inquiry_text: str, ) -> None: user_name = user.first_name or user.last_name or "" ticket_title = f"Обращение от {user_name or 'клиента'} ({user_id})" if len(inquiry_text) > 100: ticket_title = inquiry_text[:97] + "..." ticket = BotTicket( user_id=user_id, title=ticket_title, description=inquiry_text, priority="normal", status="Новая", created_by="bot", contact_name=f"{user.first_name or ''} {user.last_name or ''}".strip() or None, contact_phone=user.phone, contact_email=user.email, ) db.add(ticket) await db.flush() msg = BotTicketMessage( ticket_id=ticket.id, direction="incoming", text=inquiry_text, ) db.add(msg) status_log = BotTicketStatus( ticket_id=ticket.id, new_status="Новая", changed_by="bot", ) db.add(status_log) conv.state = "completed" user.total_tickets = (user.total_tickets or 0) + 1 user_info = f"ID: {user_id}\nИмя: {user.first_name or 'не указано'} {user.last_name or ''}" contact = user.phone or "не указан" history = await _get_conversation_history(conv.id) support_email = await settings_cache.get("support_email", "zakaz@aegisone.ru") email_subject = await settings_cache.get( "email_subject", "Обращение через Виртуального помощника AegisOne Engineering", ) import asyncio loop = asyncio.get_running_loop() await loop.run_in_executor(None, lambda: email_sender.send_ticket_escalation( to=support_email, subject=email_subject, user_info=user_info, contact=contact, inquiry=inquiry_text, history=history, )) await max_api.send_message( user_id, f"Зафиксировала: {inquiry_text}\n\n" f"Ваша заявка отправлена инженеру. В ближайшее время он обязательно " f"свяжется с вами.", conversation_id=conv.id, ) async def _get_conversation_history(conv_id: int) -> str: async with async_session() as db: result = await db.execute( select(BotMessage) .where(BotMessage.conversation_id == conv_id) .order_by(BotMessage.id) ) messages = result.scalars().all() lines = [] for msg in messages: direction = "Клиент" if msg.direction == "incoming" else "Бот" time_str = msg.created_at.strftime("%d.%m.%Y %H:%M") if msg.created_at else "" lines.append(f"[{time_str}] {direction}: {msg.text or ''}") return "\n".join(lines)