diff --git a/bot.py b/bot.py index 20146c5..3450187 100644 --- a/bot.py +++ b/bot.py @@ -41,355 +41,11 @@ BAN_STRIKES = 3 BAN_WINDOW_SEC = 60 BAN_SEC = 600 -# Регулярные выражения для валидации -# Российский номер для нормализации 8XXX / 7XXX -> +7XXX -RU_PHONE_REGEX = re.compile(r"^\+?[78]\d{10}$") -# Международный формат (E.164): + и 10–15 цифр. Принимаем и иностранные номера. -INTL_PHONE_REGEX = re.compile(r"^\+?\d{10,15}$") -# Имя: буквы (кириллица/латиница), пробел, дефис, апостроф; длина 2–50 -NAME_REGEX = re.compile(r"^[A-Za-zА-Яа-яЁё][A-Za-zА-Яа-яЁё \-']{1,49}$") - - -def normalize_phone(text: str) -> Optional[str]: - """Очищает и нормализует телефон. Возвращает нормализованный номер или None, если формат неверен.""" - phone_cleaned = re.sub(r"[\s\-\(\)]", "", text) - - # Российские номера приводим к виду +7XXXXXXXXXX - if phone_cleaned.startswith("8") and len(phone_cleaned) == 11: - phone_cleaned = "+7" + phone_cleaned[1:] - elif phone_cleaned.startswith("7") and len(phone_cleaned) == 11: - phone_cleaned = "+" + phone_cleaned - - # Принимаем как российский, так и любой международный номер в формате E.164 - if RU_PHONE_REGEX.match(phone_cleaned) or INTL_PHONE_REGEX.match(phone_cleaned): - return phone_cleaned - return None - - -def format_phone_display(phone: str) -> str: - """Красивое отображение номера: +7 (999) 123-45-67 для РФ, иначе как есть.""" - if not phone: - return phone - digits = re.sub(r"\D", "", phone) - if len(digits) == 11 and digits[0] in ("7", "8"): - d = digits - return f"+7 ({d[1:4]}) {d[4:7]}-{d[7:9]}-{d[9:11]}" - return phone - - -def is_valid_name(text: str) -> bool: - """Имя должно состоять только из букв, пробела, дефиса или апострофа (без цифр и спецсимволов).""" - return bool(NAME_REGEX.match(text.strip())) - - -# ========================================== -# КЛАВИАТУРЫ ДЛЯ ИНТЕРФЕЙСА (UX/UI ВКонтакте) -# ========================================== - -def get_main_keyboard(is_admin: bool = False) -> str: - """Главное меню бота. Для админа добавляется кнопка «Админка ⚙️».""" - keyboard = VkKeyboard(one_time=False) - # Кнопка начать опрос (зеленая) - keyboard.add_button("Заполнить заявку 📝", color=VkKeyboardColor.PRIMARY) - keyboard.add_line() - # Карьера в ИКП (набор игроков и сотрудников) - keyboard.add_button("Карьера в ИКП 💼", color=VkKeyboardColor.POSITIVE) - keyboard.add_line() - # Кнопки FAQ и оператора - keyboard.add_button("Частые вопросы ❓", color=VkKeyboardColor.SECONDARY) - keyboard.add_button("Позвать оператора 🧑‍💼", color=VkKeyboardColor.NEGATIVE) - # Кнопка админ-панели — только для администраторов (отдельной строкой) - if is_admin: - keyboard.add_line() - keyboard.add_button("Админка ⚙️", color=VkKeyboardColor.PRIMARY) - return keyboard.get_keyboard() - - -def get_admin_keyboard(is_super: bool = False) -> str: - """Клавиатура админ-панели с разделами. Супер-админу — раздел «Администраторы».""" - keyboard = VkKeyboard(one_time=False) - keyboard.add_button("Статистика 📊", color=VkKeyboardColor.SECONDARY) - keyboard.add_button("Кандидаты 👥", color=VkKeyboardColor.SECONDARY) - keyboard.add_line() - keyboard.add_button("Управление услугами ⚙️", color=VkKeyboardColor.SECONDARY) - keyboard.add_button("Вакансии 💼", color=VkKeyboardColor.SECONDARY) - keyboard.add_line() - keyboard.add_button("Быстрые ответы 💬", color=VkKeyboardColor.SECONDARY) - keyboard.add_button("Рассылка 📣", color=VkKeyboardColor.SECONDARY) - keyboard.add_line() - if is_super: - keyboard.add_button("Администраторы 👑", color=VkKeyboardColor.NEGATIVE) - keyboard.add_line() - keyboard.add_button("В главное меню ↩️", color=VkKeyboardColor.PRIMARY) - return keyboard.get_keyboard() - - -def get_svc_admin_keyboard() -> str: - """Клавиатура раздела управления услугами (направлениями).""" - keyboard = VkKeyboard(one_time=False) - keyboard.add_button("➕ Добавить услугу", color=VkKeyboardColor.POSITIVE) - keyboard.add_line() - keyboard.add_button("✏️ Изменить услугу", color=VkKeyboardColor.SECONDARY) - keyboard.add_button("🖼 Сменить картинку", color=VkKeyboardColor.SECONDARY) - keyboard.add_line() - keyboard.add_button("🗑 Удалить услугу", color=VkKeyboardColor.NEGATIVE) - keyboard.add_line() - keyboard.add_button("В админку ↩️", color=VkKeyboardColor.PRIMARY) - return keyboard.get_keyboard() - - -def get_faq_admin_keyboard() -> str: - """Клавиатура раздела управления быстрыми ответами.""" - keyboard = VkKeyboard(one_time=False) - keyboard.add_button("➕ Добавить ответ", color=VkKeyboardColor.POSITIVE) - keyboard.add_line() - keyboard.add_button("✏️ Изменить ответ", color=VkKeyboardColor.SECONDARY) - keyboard.add_button("🗑 Удалить ответ", color=VkKeyboardColor.NEGATIVE) - keyboard.add_line() - keyboard.add_button("В админку ↩️", color=VkKeyboardColor.PRIMARY) - return keyboard.get_keyboard() - - -def get_pick_keyboard(items: list) -> str: - """Клавиатура выбора из списка пар (id, label). Кнопка отправляет '.