Мы используем аналитику, чтобы понимать, как посетители используют сайт. Она заработает только с вашего согласия. Подробнее — в политике конфиденциальности.
Подробный разбор создания интеллектуального бота для мониторинга доступности волейбольных кортов в Лимассоле
В Лимассоле два основных волейбольных центра с возможностью бронирования кортов: Poseidonia (volleyball.org.cy) и Municipal (limassolsport.com). У обоих — веб‑сайты с календарём, но без уведомлений: чтобы поймать свободный слот, нужно вручную обновлять страницы несколько раз в день. Популярные вечерние часы разбирают за минуты.
Мы решили автоматизировать процесс: Telegram‑бот, который сам проверяет доступность и присылает уведомления, когда появляются нужные слоты.
Бот каждый час обращается к сайтам обоих кортов и собирает данные о доступных слотах на ближайшие 14 дней. У каждой площадки свой формат — Municipal использует LatePoint API (AJAX POST), Poseidonia отдаёт HTML с атрибутами data‑bookable‑minutes.
Не все слоты одинаково интересны. Бот отслеживает «целевые» часы: по будням — утро (7:00–9:00) и вечер (18:00–20:00), по выходным добавляются дневные (16:00–17:00). Новые слоты сравниваются с предыдущим сканом.
Если появились новые целевые слоты, бот отправляет сообщение в подписанные чаты. Поддерживаются «тихие часы» — ночью уведомления не приходят.
Помимо автоматического мониторинга, бот предоставляет интерактивный поиск через команду /slots:
Интерфейс построен на inline‑кнопках — никакого набора текста, всё работает в пару нажатий.
Каждая площадка потребовала своего адаптера. Municipal отвечает на AJAX‑запросы к LatePoint — один POST‑запрос на день. Poseidonia устроена сложнее: нужно сделать 4 запроса (комбинации agent × service) и собрать результаты. Для надёжности используется exponential backoff с jitter при ошибках 429/5xx.
Асинхронный Python (asyncio) на базе python‑telegram‑bot. ConversationHandler управляет пошаговым диалогом через state machine. Тяжёлые операции (HTTP‑запросы, обращения к БД) выносятся в thread pool через asyncio.to_thread(). Rate limiting — 5 запросов в минуту на пользователя.
PostgreSQL хранит доступные слоты, историю действий пользователей и список чатов. Для слотов используется уникальный ключ «дата+время+площадка» с ON CONFLICT DO NOTHING — дубликаты автоматически отсекаются. Batch‑вставка через execute_values для эффективности.
Отдельный скрипт slot_monitor.py запускается по расписанию (cron на Render.com). Он сканирует оба сайта, сравнивает найденные слоты с тем, что уже есть в базе, и при появлении новых целевых слотов рассылает уведомления. Скользящее окно 14 дней — старые слоты автоматически удаляются.
Оба сайта могут изменить вёрстку в любой момент. Парсеры написаны с защитным подходом: если структура HTML не совпадает с ожидаемой, бот логирует ошибку, но не падает. Это позволяет быстро заметить проблему и обновить адаптер.
Municipal работает через REST‑like API (LatePoint plugin), а Poseidonia отдаёт полностью серверный HTML. Унифицировать их не получится — каждый адаптер живёт отдельно с общим интерфейсом на выходе: список (дата, время, площадка).
Бот работает в Telegram‑чатах волейбольного сообщества Лимассола. Игроки получают уведомления о новых слотах в реальном времени, вместо того чтобы обновлять сайты вручную. Ежедневная статистика использования отправляется в отдельный канал — это помогает отслеживать активность и замечать проблемы с парсерами.
Проект показал, что даже простая автоматизация — бот, который раз в час проверяет два сайта — может значительно упростить жизнь сообществу, когда ручной процесс отнимает время каждый день.