Commit Graph

42 Commits

Author SHA1 Message Date
Kenik 19bade27b6 Напоминалки: нижняя клавиатура раздела вместо инлайн (не остаются старые кнопки)
Инлайн-клавиатура в _send_reminders_admin не заменяла нижнюю (reply) клавиатуру
предыдущего шага мастера — после создания напоминания кнопки «Разово / Каждую
неделю / …» оставались висеть внизу. Теперь раздел использует обычную нижнюю
клавиатуру get_reminders_admin_keyboard(), как и раздел «Быстрые ответы».

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-05 14:11:15 +03:00
Kenik fc79da8f83 Напоминалки: кнопка удаления списком и ФИО получателей вместо голых id
- В разделе «Напоминалки» добавлена кнопка «🗑 Удалить напоминание» с выбором
  из списка (как в разделе «Быстрые ответы»), не только текстовая команда.
- При выборе получателей и в списке напоминаний теперь показывается ФИО
  админа из VK рядом со ссылкой (если удалось получить), чтобы не кликать
  по каждой ссылке для опознания.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-05 14:08:49 +03:00
Kenik 5d88b8899e Напоминалки: фоновый планировщик отправки в срок
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 21:49:28 +03:00
Kenik 86f8115de1 Напоминалки: мастер создания, список и удаление в bot.py
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 21:44:23 +03:00
Kenik 577d342bdd Логотип: не долбить VK/лог при отказе загрузки фото (кэшируем неудачу)
В логах на каждое приветствие сыпалось [15] Access denied (у токена нет прав на
фото). Теперь неудача загрузки кэшируется — приветствие уходит без логотипа, без
повторных ошибок. (Чтобы логотип показывался — токену нужно право «Фотографии».)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 21:50:53 +03:00
Kenik f9cdaec75a Фикс: бот слал «не понял запрос» на беседы и пустые сообщения
Причина случайного фолбэка «Пока не получилось определить запрос»:
- бот реагировал на сообщения из бесед/групповых чатов (peer_id != from_id) и слал
  отправителю в ЛС фолбэк — теперь такие сообщения игнорируются (работаем только в личке);
- сообщения без текста (стикер/фото/голосовое/гифка) давали text="" → фолбэк в
  главном меню — теперь пустые сообщения игнорируются.

Тест: test_empty_message_ignored. pytest 44 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 21:45:23 +03:00
Kenik e509c0cfd1 Docker: Dockerfile + docker-compose.yml для запуска бота в контейнере
- Dockerfile (python:3.11-slim): установка зависимостей, запуск bot.py.
- docker-compose.yml: авто-перезапуск (restart: unless-stopped), настройки из .env
  (env_file), база в именованном volume (данные не теряются при пересборке).
- .dockerignore: в образ не тащим .git/тесты/докумен/базу/.env.
- bot.py: путь к БД через DB_PATH (для volume в Docker), по умолчанию — как раньше.
- requirements.txt: убраны неиспользуемые Pillow и openpyxl (образ легче).

pytest passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-26 22:32:15 +03:00
Kenik d2ca750a2d Админка: показ/скрытие кнопок меню + экстренный стоп бота (/favi-stop)
1) Кнопки меню: раздел «Кнопки меню 🧩» в админке — показать/скрыть любую кнопку
   главного меню (Подобрать/Интенсив/Цены/Вопрос/Вебинар). Флаги в БД (bot_flags),
   дефолты в config.MENU_FEATURES (вебинар по умолчанию скрыт). Скрытый раздел не
   реагирует и на кодовые слова (интенсив выкл → «лето» игнорируется). Вебинар
   получил кнопку в меню (для теста ветки) + вход по callback из поста работает всегда.

2) Экстренное отключение (только супер-админ): /favi-stop → запрос пароля → бот
   уходит в аварийный режим и молчит для всех; /favi-start возвращает. Пароль хранится
   как PBKDF2-хэш в .env (FAVI_STOP_HASH), не в коде; сравнение константное, 3 попытки.

pytest 43 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-26 10:58:54 +03:00
Kenik 24daec1c09 Фикс: пустой ряд в клавиатуре ломал отправку («Задать вопрос» молчал) + vk.ru в резолвере
1) _kb при пустых рядах создавал ПУСТОЙ первый ряд (add_line до кнопок) — VK
   отклонял такую клавиатуру, из-за чего сообщения шага «Задать вопрос»,
   «другая игра», «нужен совет» не отправлялись (состояние при этом менялось).
   Теперь add_line ставится только между реальными кнопками — пустых рядов нет.
2) _resolve_vk_user_id теперь понимает домен vk.ru (и www./m.), а не только vk.com —
   ссылку https://vk.ru/screenname на добавление админа бот принимает.

Тесты: test_funnel_keyboards_no_empty_rows, test_resolve_vk_links. pytest 40 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-26 10:45:31 +03:00
Kenik 81c1162ca1 Админам: персональное отключение уведомлений от клиентов
В админ-панели кнопка «Уведомления: вкл 🔔 / выкл 🔕» — админ (в т.ч. из ADMIN_IDS/
супер-админ) может лично отключить приём уведомлений о заявках и сообщениях клиентов.
Флаг notify_muted хранится в профиле; _notify_operators пропускает замьюченных
получателей (у остальных операторов уведомления идут как обычно).

pytest 37 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-26 10:37:58 +03:00
Kenik f1c984ed69 Чистка репозитория: удалены неиспользуемые картинки + упрощён prewarm
Удалены изображения от удалённых фич (карусель услуг, карьера, веб-форма):
service_1/2/3/5/6/7.jpg, career_player/worker.jpg, bg.jpg. Остался только Logo.jpg
(приветствие). _prewarm_media упрощён — грузит только логотип.

pytest 36 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-26 10:31:51 +03:00
Kenik 348b944638 Дисциплина CS2 → «Counter-Strike 2» в текстах и кнопке выбора игры
Отображаемое название дисциплины расписано полностью: кнопка выбора игры,
приветствие, список направлений, вопрос об уровне, значение game, инфо интенсива,
описание услуги. Ввод «CS2» по-прежнему распознаётся (+ counter/strike).
Метка game_cs2 и UTM summer_intensive не тронуты (внутренние). Название продукта
«Летний интенсив CS2» оставлено как есть.

pytest 36 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-26 10:29:32 +03:00
Kenik 7caecb1c72 Тикеты заявок, «пробное занятие», доработка ветки вебинара
- Тикеты: add_lead возвращает id заявки; при передаче менеджеру клиент получает
  «🎫 Номер вашей заявки: №N», тот же номер — в карточке оператору и в письме.
  Один тикет на заход (сбрасывается при новом старте воронки/интенсива).
- Кнопка «Записаться на пробное» → «Записаться на пробное занятие» (лейблы + распознавание).
- Ветка вебинара: вход по callback-кнопке и по тексту «записаться на вебинар»,
  текст выровнен по ТЗ, после регистрации состояние FREE_CHAT — основное меню
  остаётся доступным (не блокирует продающую ветку). Дата/время — в config.

Тесты: test_baza_question_ticket, test_webinar_registration. pytest 36 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-26 10:04:19 +03:00
Kenik 7889a19744 Стата «Заявки» из воронки: запись лидов при конверсии
Воронка перестала писать в leads после ребрендинга — блок «Заявки» был всегда 0.
Теперь при конверсии (нажал оплату/пробное или передан менеджеру) бот фиксирует
заявку в leads (source=bot, имя из VK, услуга = тариф/формат/игра), один раз на заход
(флаг lead_recorded сбрасывается при новом старте воронки/интенсива). Разбивка «по
тарифу/формату» снова показывает реальные цифры.

Статистика почищена: убраны «из бота» (все заявки теперь из бота) и строка «согласны
на рассылку» (воронка не собирает это согласие) — не вводят в заблуждение.

Тест: test_baza_records_lead_once. pytest 34 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 20:27:21 +03:00
Kenik 72eeccdc3a Чистка хвостов веб-формы: убраны web_registrations и строка «с сайта» в стате
- database.py: удалены таблица web_registrations, методы add_web_registration и
  next_web_registration_id, поле from_web из get_lead_stats (форму убрали).
- bot.py: из статистики убрана строка «с сайта» (веб-заявки больше не пишутся).

pytest 33 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 20:23:36 +03:00
Kenik 12ce9c0807 Умный пропуск шагов воронки при уже сохранённых данных (§15)
- _baza_advance: воронка переходит к первому НЕзаполненному шагу, пропуская роль/
  возраст/игру/уровень, если они уже известны; формат (выбор действия) спрашивается всегда.
- На повторном входе — короткая подсказка, что известные ответы не переспрашиваются
  и их можно изменить кнопкой «Назад» (back-навигация остаётся линейной = override).
- Интенсив: известный возраст (из подбора) не переспрашивается — сразу уровень CS2.
- Данные из ветки «лето» сохраняются и переиспользуются в подборе, и наоборот.

Тесты: test_baza_smart_skip_known_fields, test_baza_intensive_skips_known_age. pytest 33 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 20:10:15 +03:00
Kenik 4095b2ec61 Чистка «лишнего»: остатки ИКП→БАЗА, мёртвый код, новый логотип
- Пользовательские сообщения и подписи с «ИКП» переименованы в «Кибершкола БАЗА»
  (права админа, стартовый пинг, отправитель писем, докстроки).
- Удалён мёртвый код: метод _notify_allowed + связанные _last_notify/NOTIFY_COOLDOWN_SEC
  (нигде не вызывались), осиротевшие комментарии-заголовки от удалённой карьеры,
  лишние пустые строки.
- Удалена скрытая фича «Наши соцсети» (нет в ТЗ, вела на старые ИКП-ссылки) + её клавиатура.
- Обновлён логотип приветствия (help_img/Logo.jpg).

Не тронуто намеренно: веб-форма (form/server.py) — отдельный компонент; слой БД.
pytest 31 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 20:04:55 +03:00
Kenik a5a96f31f5 Фикс: убран дубликат «Спасибо! Передаю запрос менеджеру» в ветке «Другая игра»
Полный прогон всех веток по ТЗ: тексты/кнопки/подтверждения на месте. Единственная
находка — двойное «Спасибо! Передаю запрос менеджеру» при выборе другой игры; второе
сообщение заменено на нейтральное уведомление о передаче менеджеру.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 19:48:24 +03:00
Kenik 261e5c2da0 Тексты воронки по ТЗ + смена ссылок из админки
Тексты:
- «Сколько лет игроку?» (было «…будущему ученику?») во всех местах;
- сообщение для «Младше 12 лет» приведено дословно к ТЗ (§4);
- убраны отсебятины-преамбулы, которых нет в ТЗ (приветствие, старт воронки,
  цены «Что дальше?», интенсив «Хотите записаться?»); кнопка младше-12 «Вернуться назад».

Смена ссылок в админке:
- таблица bot_links (key, url) + методы get_link/get_all_links/set_link;
- _link(key): БД-переопределение → дефолт из config/.env; используется на шагах оплаты;
- раздел «Ссылки 🔗» в админ-панели: список текущих адресов + «✏️ Изменить ссылку»
  (выбор из 8 кнопок → ввод URL с валидацией http/https). UTM добавляются автоматически.

Тесты: добавлен test_admin_edit_link. pytest 31 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 19:45:47 +03:00
Kenik fac2e3808b Фикс запуска: bot.py сам добавляет свою папку в sys.path
py -3.11 на машине резолвится в sandbox-сборку Python (ExamPython311), которая не
добавляет директорию скрипта в sys.path — из-за этого при запуске через start_bot.bat
падало «ModuleNotFoundError: No module named 'database'». Теперь bot.py в самом начале
вставляет свой каталог в sys.path, поэтому запускается любым Python и из любой папки.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 19:24:55 +03:00
Kenik 741a89f458 Ссылки БАЗА: реальные URL записи/оплаты + сохранение якоря в UTM
- Кнопки записи/оплаты ведут на форму сайта infocyber.pro (service_id web_1..web_5);
  тарифы — на главную с якорем #prices; пробное и интенсив — на общую форму записи
  (отдельной страницы интенсива на сайте пока нет).
- _utm(): UTM вставляется ДО якоря (?utm...#prices), иначе браузер не доскроллит
  до раздела. Значения ссылок вынесены в .env / задокументированы в .env.example.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 19:12:20 +03:00
Kenik 7a59b035ce Воронка БАЗА: приведение к ТЗ (метки, сохранённые данные, тексты, шаги)
Закрыты расхождения с ТЗ:
- Метки (§12) переименованы под спецификацию: role_player, game_dota2, format_help,
  interest_trial, interest_summer_intensive, manager_requested, source_main_menu,
  source_keyword_summer; убраны служебные age_*/level_* метки.
- Сохранённые данные (§13): кодовое слово, дата запуска бота (started_at), дата
  передачи менеджеру (manager_at), интересы (пробное/интенсив). Карточка менеджеру
  дополнена этими полями, заголовок «Новый запрос из бота».
- «Пока не знаю, нужен совет» (§7): показ собранных данных + свободный текст → менеджеру.
- «Задать вопрос» (§9): промпт «напишите одним сообщением» → BAZA_QUESTION → передача.
- Летний интенсив: свой набор уровней (§10.3), экран младше-12 (Передать менеджеру/
  Другие тренировки), двухшаговая оплата (Оплатить интенсив → ссылка) (§10.4),
  различение запуска по кодовому слову vs меню.
- Индивидуальная ветка без «пробного» (§6). Fallback-текст дословно по §15.
- «Выбрать абонемент» ведёт на страницу тарифов ссылкой (§8). Тексты веток — по ТЗ.

Тесты воронки обновлены и дополнены (интенсив-оплата, младше-12 интенсив, свободный
вопрос, «нужен совет»). pytest 30 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 13:55:34 +03:00
Kenik 74a855819d Чистка старого ИКП-флоу: удалены форма-заявка, карьера/вакансии, меню FAQ и осиротевшая админка
Из ТЗ Кибершколы БАЗА эти сценарии заменены воронкой подбора, поэтому убран мёртвый код:
- клиентские FSM: FORM_* (форма-заявка, возвращающийся клиент, редактирование, согласия,
  выбор услуги, карусель) и VAC_* (карьера: игроки/сотрудники);
- меню «Частые вопросы» и config.FAQ_ANSWERS;
- осиротевшая админка: управление услугами + карусель, вакансии, кандидаты
  (в панели и в мастере ADMIN_SVC_*/ADMIN_VAC_*), блок статистики по откликам;
- старый _handoff_to_operator и _notify_operator_about_lead (заменены _baza_to_manager);
- неиспользуемые клавиатуры (форма/услуги/вакансии/согласия) и импорты (validators, random, string).

Оставлено (используется/по ТЗ): воронка БАЗА, быстрые ответы (custom_faq), стата по лидам,
рассылка, управление админами, чат с оператором, логотип. Слой БД не тронут — существующие
установки не ломаются (таблицы services/applications/vacancy_options просто не используются).

bot.py: -1490 строк. Тесты: pytest 28 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 18:36:38 +03:00
Kenik 60199fb47b Ребрендинг БАЗА: новое меню + воронка подбора, интенсив, оплата, карточка менеджеру
Меню Кибершколы БАЗА (4 кнопки): Подобрать тренировку / Летний интенсив CS2 /
Посмотреть цены / Задать вопрос.

Воронка «Подобрать тренировку» (FSM BAZA_*): для кого → возраст → игра → уровень →
формат → групповые / индивидуальные / нужен совет. На каждом шаге — «Назад» и «В
главное меню», ветки: младше 12 и «другая игра» уводят к менеджеру.

Ветка «Летний интенсив CS2»: инфо → возраст → уровень → оплата. Запуск по кнопке и
по кодовым словам (лето/интенсив), основные триггеры и приветствие — из config.

Шаг оплаты: инлайн-кнопка «Перейти к оплате» (ссылки-плейсхолдеры из config.LINKS +
UTM), «Проблема с оплатой» и «Задать вопрос менеджеру» уводят к оператору.

Карточка менеджеру собирается из профиля воронки (пустые поля пропускаются) + метки;
дублируется на почту. Данные не переспрашиваются, после передачи менеджеру бот не
вмешивается (OPERATOR_CHAT). Тесты воронки — pytest (30 passed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 18:20:59 +03:00
Kenik 26b6df77ef удаление документа "Dogovor_oferty_kibersport_versia_izmenennaya.docx" и добавление новых изображений для помощи в сервисе. 2026-06-26 17:00:41 +03:00
Kenik f14b8769e5 Добавление админа по ссылке VK (не только числовой ID)
Бот принимает ссылку (https://vk.com/gruzdevas), короткое имя (gruzdevas),
@имя или числовой ID и сам определяет user_id (короткое имя — через VK API
users.get). Резолвер _resolve_vk_user_id применён к добавлению и удалению админа.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 19:06:45 +03:00
Kenik 0ec849d80f Соцсети: добавлена кнопка-ссылка на сайт infocyber.pro
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 14:21:52 +03:00
Kenik fc3361c7ea Фикс клавиатуры возвращающегося клиента + защита от двух экземпляров
- Возвращающийся клиент: «Да/Отмена» — нижняя клавиатура, а «Сменить имя/
  телефон/Заполнить заново» — отдельные инлайн-кнопки под сообщением (ровно 3,
  как просил).
- start_bot.bat: перед запуском убивает старые экземпляры бота — устраняет
  «рандомные» цвета от нескольких параллельных longpoll-инстансов.
- Маска телефона в приветствии возвращающегося клиента.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 09:14:57 +03:00
Kenik 60ef76024e Правки кнопок + VK-имя в уведомлении о заявке
- Админка — всегда зелёная (POSITIVE).
- Меню изменения данных: «Назад к проверке» — красная.
- Возвращающийся клиент: «Да/Сменить имя/телефон/Заполнить заново/Отмена» —
  инлайн-кнопки под сообщением.
- Уведомление оператору: добавлено реальное имя из VK с флагом «не совпадает
  с введённым» — помогает отсеивать рандомные/фейковые данные (профиль VK уже был).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 09:00:06 +03:00
Kenik 33906e7e7d Возврат исходной палитры кнопок: убран зелёный POSITIVE
Зелёного цвета (POSITIVE) в оригинальных клавиатурах не было — он появился
при добавлении карьеры и админ-разделов. Заменён на PRIMARY (синий) во всех
7 местах, чтобы вернуть исходную палитру (PRIMARY/SECONDARY/NEGATIVE).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 08:20:56 +03:00
Kenik 667ca4d4f0 Предзагрузка всех картинок при старте + многопоточный веб-сервер
- _prewarm_media грузит ВСЕ *.jpg из help_img при старте (кроме bg.jpg),
  чтобы смена картинок услуг не подгружалась лениво в момент сообщения.
- Веб-форма: ThreadingHTTPServer — медленный запрос не блокирует остальные;
  приём заявки сериализован _submit_lock (без гонок в SQLite/Excel).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 21:58:22 +03:00
Kenik ba0f43169c Рефакторинг (этап 1): валидаторы и клавиатуры вынесены в модули
bot.py разгружен: чистые функции вынесены без изменения поведения:
- validators.py — регэкспы, normalize_phone, format_phone_display, is_valid_name
- keyboards.py — все get_*_keyboard

Поведение проверено регрессионным прогоном (полный флоу заявки, админка, меню).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 21:41:21 +03:00
Kenik 30a02cf09b Предзагрузка картинок услуг service_*.jpg (карусель не тормозит)
Картинки дисциплин теперь хранятся как service_<id>.jpg (после смены через
админку). Предзагрузка медиа при старте теперь подхватывает их по маске,
чтобы первая карусель открывалась мгновенно.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 21:35:17 +03:00
Kenik 564581decf Правки админки: инлайн-кнопки, отмена рассылки, FAQ в меню, вакансии в БД
- Отмена в «Заявке»/«Карьере» возвращает меню с кнопкой «Админка» для админов.
- Рассылка: инлайн-кнопки «Отправить»/«Отмена» в предпросмотре.
- Управление админами — инлайн-кнопки «Добавить»/«Удалить» (без текстовых команд),
  выбор удаляемого админа кнопкой.
- Быстрые ответы из админки показываются в «Частые вопросы» инлайн-кнопками.
- Вакансии «Карьеры» перенесены в БД (vacancy_options): направления игроков и
  должности сотрудников редактируются из админки (раздел «Вакансии»), а в опросе
  показываются инлайн-кнопками из БД.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 19:36:53 +03:00
Kenik 755e364d42 Кнопочное управление услугами (+смена картинок) и быстрыми ответами
- Приём фото-вложений от админа (handle_message получает attachments).
- Раздел «Услуги»: кнопки Добавить / Изменить / Удалить / Сменить картинку.
  Картинка скачивается, обрезается под 13:8 (650×400) и сохраняется как
  service_<id>.jpg; карусель берёт её приоритетно. Мастера на состояниях ADMIN_*.
- Раздел «Быстрые ответы»: кнопки Добавить / Изменить / Удалить с выбором.
- Контекст мастеров в памяти (_admin_ctx), отмена из любого шага.

Заметка: CRUD «Карьеры» (направления игроков/должности) — отдельным заходом,
т.к. опции там пока захардкожены и требуют перевода на БД.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 18:50:47 +03:00
Kenik 29097a18c3 Супер-админ, выбор даты/времени звонка, инлайн-документы, маска телефона
- Супер-админ (config.SUPER_ADMIN_IDS, только через код): добавляет/удаляет
  обычных админов из бота (раздел «Администраторы 👑»), таблица admins.
  _is_admin теперь учитывает супер-админов, .env и добавленных из бота.
- «Когда удобно созвониться» → выбор конкретного дня (кнопки на ближайшие даты)
  и времени (слоты), сохраняется как «День, ЧЧ:ММ».
- Шаг согласия: инлайн-кнопки со ссылками на оферту и политику ПД (PDF), затем
  подтверждение. Старое вложение .docx убрано.
- Маска отображения телефона: +7 (999) 123-45-67 в карточке и уведомлениях.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 18:39:19 +03:00
Kenik 3d709267ff Админка, защита и UX: быстрые ответы, статусы кандидатов, мульти-операторы, бан, прогресс-бар
Бот:
- Прогресс-бар (▰▰▱ Шаг N из 3) в шагах заявки
- Быстрые ответы по ключевым словам (таблица custom_faq) — отвечают до зова оператора;
  редактирование через админ-панель (раздел «Быстрые ответы»: добавить/список/удалить)
- Отклики в статистике: счётчик игроков/сотрудников по дисциплинам и должностям
- Статусы кандидатов (новый/на собесе/отказ/принят) — раздел «Кандидаты» в админке
- Несколько операторов: уведомления уходят всем из OPERATOR_PEER_IDS
- Часы работы (WORK_HOUR_START/END): вне часов хендофф сообщает «ответим утром»
- Временный бан при повторном флуде (усиление анти-DDoS)
- Старт-пинг администратору «бот запущен» (лёгкий healthcheck)

Док и зависимости:
- README.md (запуск, .env, автозапуск, админ-команды, структура)
- requirements.txt

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 10:00:56 +03:00
Kenik 377188a015 Админ-панель в боте: кнопка «Админка» и разделы кнопками
- В главном меню у администраторов появляется кнопка «Админка ⚙️»
  (видна только в сообщениях админу; не-админа код всё равно не пускает).
- Админ-панель с кнопками: Статистика, Управление услугами, Рассылка,
  В главное меню — вместо запоминания текстовых команд.
- Доступ строго по config.ADMIN_IDS на сервере.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 07:40:04 +03:00
Kenik 40479c8b7a Карусель «Карьеры»: картинки игрока и сотрудника
Добавлены career_player.jpg и career_worker.jpg (13:8, 650×400),
карточки в разделе «Карьера» теперь с фото. Картинки добавлены
в предзагрузку медиа при старте.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 22:04:51 +03:00
Kenik 80c95d6edc Устойчивый цикл LongPoll: переподключение при обрыве сети
Обрыв longpoll-соединения (RemoteDisconnected) больше не роняет бота —
цикл ловит сетевые ошибки, ждёт и переподключается. Ошибка обработки
одного сообщения тоже не останавливает работу.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 21:58:21 +03:00
Kenik 79cc1ba38d Доработка VK-бота ИКП: контент, новые функции, защита и визуал
Контент и брендинг:
- Реальные данные ИКP (infocyber.pro): услуги CS2/Dota 2/WoT, цены, FAQ, контакты, площадки
- Приветствие и тексты приведены к бренду ИКП

Новые функции:
- Раздельные согласия (152-ФЗ): маркетинговая рассылка — отдельный необязательный шаг
- Шаг «удобное время звонка» в форме заявки
- Раздел «Карьера в ИКП»: набор игроков и сотрудников (таблица applications)
- Админ-команды: статистика (стата) и рассылка по подписчикам с троттлингом и отпиской
- Журнал заявок leads, «бот помнит клиента», международные телефоны, валидация имени
- Email-уведомления о заявках и откликах (mailer.py); HR-адрес через HR_MAIL_TO

Защита:
- Анти-флуд по пользователю и кулдаун уведомлений оператору (анти-DDoS)
- Веб-форма: серверная валидация, honeypot, рейт-лимит, CORS по ALLOWED_ORIGIN, SQLite-first

Визуал:
- Убрана Markdown-разметка (VK её не рендерит)
- Логотип в приветствии, карусели услуг и «Карьеры» (фото 13:8), предзагрузка медиа
- Кнопки-ссылки на соцсети
- Веб-форма: анимации, конфетти на успехе

Промокоды добавлены, но пока ВЫКЛЮЧЕНЫ флагом PROMO_ENABLED (по умолчанию false).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 21:54:31 +03:00
a.gruzdev f38324645e Пробую ещё раз залить, т.к. прошлый раз залилось с ошибкой 2026-06-15 09:16:37 +03:00