Skip to content

Repository files navigation

VetClinic Bot

CI Python 3.11+ License: MIT

Telegram-бот для ветеринарной клиники с интеграцией VetManager API.

Заменяет администратора в части записи клиентов на приём, работы с расписанием врачей, управления записями, информации о товарах ветаптеки.

Возможности

Для клиентов

  • Запись на приём через FSM-сценарий: телефон → имя → питомец → услуга → врач → слот
  • Мои записи: просмотр, отмена с указанием причины, перенос
  • Поиск товаров в ветаптеке через VetManager
  • Авто-создание клиента и питомца в VetManager после первой записи
  • Push-напоминания за 24 ч и 2 ч до приёма

Для менеджеров

  • Записи на сегодня/завтра с возможностью отметить «Состоялась»/«Не пришёл»
  • Ручная запись клиента от его имени
  • Расписание врачей на сегодня
  • Получение уведомлений о новых записях, отменах, переносах

Для админов

  • Всё, что у менеджера, плюс:
  • Записи на любую дату
  • Поиск клиентов и просмотр их истории
  • Управление менеджерами (назначить/снять роль)
  • Статистика за день/неделю/месяц + активность персонала

Для супер-админа

  • Всё, что у админа, плюс:
  • Управление админами
  • Список сотрудников
  • Включение/отключение врачей в боте
  • Синхронизация врачей и услуг с VetManager
  • Настройки клиники (рабочие часы, текст приветствия)
  • Логи всех действий с фильтрами

Стек

Архитектура

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.py

.env

BOT_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

Получить SUPER_ADMIN_ID

Напишите боту @userinfobot — он вернёт ваш Telegram user id.

Получить VetManager API key

  1. Зайдите в админку VetManager под аккаунтом владельца клиники
  2. Программа → build → services
  3. Создайте ключ — скопируйте его в VETMANAGER_API_KEY

Запуск

Локально

python main.py

Production (systemd)

/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.target
sudo systemctl daemon-reload
sudo systemctl enable --now vetclinic-bot
sudo journalctl -u vetclinic-bot -f

Docker

Dockerfile:

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')]"

Roadmap

  • Покрытие unit/integration тестами (pytest + pytest-asyncio)
  • Использование db_conn() вместо get_db() через middleware injection (один conn на handler)
  • Миграция БД через Alembic
  • Поддержка нескольких клиник (мультиарендность)
  • Web-админка
  • Локализация (i18n)

Лицензия

MIT — см. LICENSE.

Changelog

См. CHANGELOG.md.

About

Open source Telegram bot for veterinary clinics with VetManager API integration

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages