Telegram-бот для ветеринарной клиники с интеграцией VetManager API.
Заменяет администратора в части записи клиентов на приём, работы с расписанием врачей, управления записями, информации о товарах ветаптеки.
- Запись на приём через FSM-сценарий: телефон → имя → питомец → услуга → врач → слот
- Мои записи: просмотр, отмена с указанием причины, перенос
- Поиск товаров в ветаптеке через VetManager
- Авто-создание клиента и питомца в VetManager после первой записи
- Push-напоминания за 24 ч и 2 ч до приёма
- Записи на сегодня/завтра с возможностью отметить «Состоялась»/«Не пришёл»
- Ручная запись клиента от его имени
- Расписание врачей на сегодня
- Получение уведомлений о новых записях, отменах, переносах
- Всё, что у менеджера, плюс:
- Записи на любую дату
- Поиск клиентов и просмотр их истории
- Управление менеджерами (назначить/снять роль)
- Статистика за день/неделю/месяц + активность персонала
- Всё, что у админа, плюс:
- Управление админами
- Список сотрудников
- Включение/отключение врачей в боте
- Синхронизация врачей и услуг с VetManager
- Настройки клиники (рабочие часы, текст приветствия)
- Логи всех действий с фильтрами
- Python 3.11+
- aiogram 3.x — Telegram Bot framework
- aiohttp — HTTP-клиент для VetManager API
- aiosqlite — асинхронный SQLite
- APScheduler — напоминания клиентам
- python-dotenv — конфиг из
.env
Telegram <-> Bot (aiogram) <-> Backend-слой (api/) <-> VetManager API
|
SQLite DB
.
├── api/
│ └── vetmanager.py # обёртка над VetManager REST API (retry, timeout, status checks)
├── bot/
│ ├── handlers/
│ │ ├── start.py # /start, приветствие
│ │ ├── appointment.py # FSM-запись на приём
│ │ ├── my_appointments.py # просмотр/отмена/перенос
│ │ ├── pharmacy.py # ветаптека
│ │ └── admin.py # админ + менеджер панели
│ ├── keyboards/
│ │ ├── client_kb.py # клавиатуры клиента
│ │ └── admin_kb.py # клавиатуры админа
│ ├── filters.py # IsAdmin, IsSuperAdmin, IsManager
│ ├── middlewares.py # AuthMiddleware (с TTL-cache), FSMTimeoutMiddleware, LoggingMiddleware
│ ├── states.py # FSM-состояния
│ └── utils.py # phone normalize, html escape, truncate
├── db/
│ ├── database.py # init, PRAGMA, async context manager
│ └── queries.py # CRUD-операции
├── services/
│ ├── slots.py # расчёт свободных слотов
│ ├── notifications.py # уведомления персоналу
│ └── scheduler.py # напоминания клиентам (APScheduler)
├── config.py # загрузка .env
├── main.py # точка входа + graceful shutdown
├── requirements.txt
├── .env.example
├── .gitignore
├── LICENSE
├── CHANGELOG.md
└── README.md
git clone <repo-url>
cd vetclinic-bot
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
# Отредактируйте .env (см. ниже)
python main.pyBOT_TOKEN=123456:ABC-DEF... # Токен от @BotFather
VETMANAGER_DOMAIN=clinic.vetmanager.ru # Домен вашей VetManager-инстанции
VETMANAGER_API_KEY=xxxxxxxxxxxx # Ключ из Программа → build → services
SUPER_ADMIN_ID=123456789 # Ваш Telegram user id
CLINIC_PHONE=+7 900 000-00-00
CLINIC_NAME=Ветклиника
WORKING_HOURS_START=09:00
WORKING_HOURS_END=20:00
SLOT_DURATION_DEFAULT=30
REMINDER_HOURS=24,2 # Часы до приёма для напоминаний
DB_PATH=data/clinic.db
TIMEZONE=Europe/Moscow # tz database name
FSM_TTL_SECONDS=1800 # 0 = без таймаута FSM
USER_CACHE_TTL=60 # 0 = без кэша
CLINIC_ID=0 # 0 = не привязывать; иначе ID клиники в VetManager
LOG_PERSIST_TO_DB=true # писать каждое событие (msg/cb) в action_log БД
LOG_LEVEL=INFO # DEBUG / INFO / WARNING / ERRORНапишите боту @userinfobot — он вернёт ваш Telegram user id.
- Зайдите в админку VetManager под аккаунтом владельца клиники
- Программа → build → services
- Создайте ключ — скопируйте его в
VETMANAGER_API_KEY
python main.py/etc/systemd/system/vetclinic-bot.service:
[Unit]
Description=VetClinic Telegram Bot
After=network.target
[Service]
Type=simple
User=botuser
WorkingDirectory=/opt/vetclinic-bot
ExecStart=/opt/vetclinic-bot/.venv/bin/python main.py
Restart=on-failure
RestartSec=5
StandardOutput=append:/var/log/vetclinic-bot.log
StandardError=append:/var/log/vetclinic-bot.log
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable --now vetclinic-bot
sudo journalctl -u vetclinic-bot -fDockerfile:
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "main.py"]docker build -t vetclinic-bot .
docker run -d --name vetclinic-bot --env-file .env -v $(pwd)/data:/app/data vetclinic-bot- API-ключ VetManager хранится только в
.env(не коммитится — см..gitignore) - Все запросы к VetManager идут через серверный прокси-слой (
api/vetmanager.py) - Роли проверяются
IsManager/IsAdmin/IsSuperAdminфильтрами на router-level - Ownership-проверка записей (
_can_manage_appointment) — клиент не может управлять чужими - HTML-экранирование всех пользовательских данных (защита от XSS-подобных багов в parse_mode HTML)
- SQL LIKE-инъекции (
%/_wildcards) экранируются вsearch_clients - SSL-проверка включена в HTTP-клиенте
- Таймауты и retry на сетевых ошибках
- Telegram-токен и API-ключ не логируются
- TTL-кэш пользователей в
AuthMiddleware(default 60 сек) — снижает нагрузку на БД - WAL mode + busy_timeout=10000 в SQLite
- Конкурентные API-запросы (нет глобального lock)
- Дедупликация напоминаний через таблицу
sent_reminders
Полный аудит всех событий:
- stdout (
logger.info/warning/error):- каждое сообщение и callback (uid, content, тип)
- длительность handler'а (warn если >1s)
- все необработанные исключения с stack trace
- VetManager API ошибки/retry
- INCONSISTENCY-предупреждения при рассинхронизации БД и VM
- БД (
action_logтаблица):- команды, сообщения, callback'и, контакты
- бизнес-действия: appointment_created, role_changed, doctor_toggled, setting_changed, super_admin_promoted и т.д.
- доступно через админку
/admin → Логи действийс фильтрами
Управление: LOG_PERSIST_TO_DB=false отключает запись в БД (только stdout), LOG_LEVEL=DEBUG для подробного вывода.
python3 -m pyflakes .
python3 -c "import py_compile, pathlib; [py_compile.compile(str(p), doraise=True) for p in pathlib.Path('.').rglob('*.py')]"- Покрытие unit/integration тестами (pytest + pytest-asyncio)
- Использование
db_conn()вместоget_db()через middleware injection (один conn на handler) - Миграция БД через Alembic
- Поддержка нескольких клиник (мультиарендность)
- Web-админка
- Локализация (i18n)
MIT — см. LICENSE.
См. CHANGELOG.md.