Files
site_aegisone/max_bot/app/handlers/contact.py
T

92 lines
3.9 KiB
Python

"""
Обработчик контактов пользователя.
Принимает контакты (телефон, email) через:
- sharing контакта из мессенджера (VCF)
- ручной ввод текстом
"""
import datetime
import re
import logging
from sqlalchemy import select
from app.database import async_session
from app.models import BotUser, BotConversation, BotMessage
from app.max_api import max_api
logger = logging.getLogger(__name__)
PHONE_PATTERN = re.compile(r"^(\+7|8|7)?[\s\-]?\(?\d{3}\)?[\s\-]?\d{3}[\s\-]?\d{2}[\s\-]?\d{2}$")
EMAIL_PATTERN = re.compile(r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$")
async def handle_contact_received(user_id: int, conv_id: int, contact_text: str) -> None:
"""Обработка контакта из мессенджера: парсинг телефона/email, переход к заявке."""
async with async_session() as db:
result = await db.execute(select(BotUser).where(BotUser.id == user_id))
user = result.scalar_one_or_none()
if user:
if PHONE_PATTERN.match(contact_text):
user.phone = contact_text
elif EMAIL_PATTERN.match(contact_text):
user.email = contact_text
result = await db.execute(
select(BotConversation).where(BotConversation.id == conv_id)
)
conv = result.scalar_one_or_none()
if conv:
conv.state = "awaiting_inquiry"
if conv.intent == "unknown" or not conv.intent:
await _ask_inquiry(user_id, conv)
else:
await _ask_inquiry_with_context(user_id, conv)
await db.commit()
async def handle_manual_contact(user_id: int, conv_id: int, text: str) -> None:
"""Обработка ручного ввода контакта: валидация телефона/email, отказ → consent_refused."""
text = text.strip()
text_lower = text.lower()
refuse_words = ["нет", "не хочу", "отмена", "отказ", "no", "cancel"]
if any(w in text_lower for w in refuse_words):
async with async_session() as db:
conv = await db.get(BotConversation, conv_id)
if conv:
conv.state = "consent_refused"
await db.commit()
from app.handlers.consent import handle_refused_again
await handle_refused_again(user_id, conv_id, text)
return
if PHONE_PATTERN.match(text) or EMAIL_PATTERN.match(text):
await handle_contact_received(user_id, conv_id, text)
else:
await max_api.send_message(
user_id,
"Пожалуйста, введите корректный номер телефона (например, +7 (861) 203-33-30) "
"или адрес электронной почты. Или напишите «Отмена» чтобы вернуться назад.",
conversation_id=conv_id,
)
async def _ask_inquiry(user_id: int, conv: BotConversation) -> None:
await max_api.send_message(
user_id,
"Опишите, пожалуйста, ваш вопрос или задачу. "
"Расскажите подробнее, чем мы можем вам помочь.",
conversation_id=conv.id,
)
async def _ask_inquiry_with_context(user_id: int, conv: BotConversation) -> None:
intent_label = "вопрос" if conv.intent == "question" else "заявку на услугу" if conv.intent == "ticket" else "обращение"
await max_api.send_message(
user_id,
f"Ранее вы упомянули, что хотите оставить {intent_label}. "
"Опишите подробнее суть вашего обращения, чтобы я могла передать "
"информацию специалисту.",
conversation_id=conv.id,
)