Введение

В этом пошаговом гайде вы с нуля создадите полностью рабочего Telegram-бота, который автоматически мониторит список прокси, измеряет время отклика, обнаруживает смену IP после ротации, проверяет геолокацию через сервис ip-api.com и шлет заметные уведомления в Telegram при проблемах и деградации. Мы шаг за шагом пройдем путь от идеи до деплоя на VPS с автозапуском, историей в SQLite и простым dashboard со статистикой uptime и экспортом логов.

Гайд рассчитан на начинающих с элементами для продвинутых. Если вы никогда не писали бота, не переживайте: мы разберем каждый шаг, объясним, зачем он нужен, и как проверить результат. К концу вы получите стабильный инструмент мониторинга прокси, который работает по расписанию каждые 5–15 минут, умеет группировать прокси по регионам и типам, а также присылает информативные алерты в ваш Telegram.

Перед стартом полезно знать, как открыть терминал, как устанавливать программы, и как создавать папки и файлы. Все остальное объясним. На выполнение всех шагов потребуется ориентировочно от 4 до 8 часов, включая настройку окружения, написание кода, тесты и деплой. Если у вас уже есть VPS и базовые навыки в Python, уложитесь быстрее.

К концу руководства вы получите: работающего Telegram-бота на aiogram 3, асинхронный модуль проверок на aiohttp, планировщик APScheduler для периодических задач, базу данных SQLite с логами и статистикой, простой web-dashboard с основными показателями и выгрузкой CSV, инструкции по обслуживанию и расширению функционала.

Совет: Лучше проходить гайд последовательно, не пропуская шаги. После каждого этапа мы добавили проверки, чтобы вы сразу убедились, что все работает.

Предварительная подготовка

Перед тем как писать код, подготовим все необходимые инструменты и окружение. Это избавит от случайных ошибок и сэкономит время.

Необходимые инструменты, программы и доступы

  • Telegram-аккаунт для создания бота и получения уведомлений.
  • VPS или локальный компьютер с Linux (Ubuntu 22.04 или 24.04 предпочтительно). На Windows и macOS тоже можно, но деплой покажем на Ubuntu.
  • Python 3.11 или новее. Версию проверим командой python3 --version.
  • Терминал и базовые права sudo для установки пакетов.
  • Список прокси для мониторинга, в формате host:port, плюс логин и пароль, если требуется. Поддержим HTTP, HTTPS и SOCKS5.

Системные требования

  • 1 CPU, 512–1024 MB RAM достаточно для 50–200 прокси при интервале 5–15 минут. Для тысяч прокси лучше 2 CPU и 2 GB RAM.
  • Свободное место на диске от 1 GB. SQLite легковесна, но логи растут.
  • Открытый выход в интернет. Доступ к Telegram API и к вашим прокси обязателен. Для ip-api.com нужен исходящий HTTP доступ.

Что нужно установить

  • Python 3.11+ и venv для виртуального окружения.
  • pip для установки зависимостей.
  • Библиотеки: aiogram версии 3, aiohttp, APScheduler, aiosqlite, python-dotenv (для удобной конфигурации), uvloop (опционально для Linux), yarl (часто идет как зависимость).

Создание резервных копий

На старте резервное копирование не критично. После запуска бота обязательно настроим простую резервную копию базы SQLite с логами и настройками. Это позволит откатиться при ошибочном обновлении или повреждении файла.

⚠️ Внимание: SQLite — это один файл. Если он повредится при неожиданном отключении питания, можно потерять свежие записи. Поэтому на VPS включите автоматическое ежедневное копирование файла базы с помощью cron или systemd timers. Мы покажем простой скрипт для этого в конце.

Базовые понятия

Чтобы не путаться, договоримся о ключевых терминах и принципах работы.

  • Прокси (Proxy) — сервер-посредник, через который идут ваши запросы. Бывают HTTP, HTTPS и SOCKS5. Прокси может требовать авторизацию логин:пароль или работу по IP-биндингу.
  • Latency (задержка) — время, за которое мы делаем запрос через прокси и получаем ответ. Измеряем в миллисекундах. Чем меньше, тем лучше.
  • Ротация IP — некоторые прокси периодически меняют внешний IP-адрес. Наш бот должен отслеживать эти изменения и уведомлять, если IP поменялся неожиданно или не совпадает с ожидаемым регионом.
  • Геолокация (Geo) — страна, город и оператор IP-адреса. Получаем через сервис ip-api.com по IP. Это поможет убедиться, что ваш прокси в нужной стране.
  • Деградация — прокси отвечает, но сильно медленнее нормы или с частыми ошибками. Мы будем различать DOWN (полностью недоступен) и DEGRADED (работает, но плохо).
  • aiogram 3 — современная асинхронная библиотека для Telegram-ботов. Простая, быстрая, поддерживает все актуальные фичи Telegram в 2026 году.
  • aiohttp — асинхронные HTTP-запросы с тайм-аутами и прокси-поддержкой.
  • APScheduler — планировщик задач, который запустит проверки по расписанию каждые N минут.
  • SQLite — встроенная база данных. Один файл, быстро и без серверной установки. Отлично подходит для локального лога и статистики.

Принцип работы бота такой: по расписанию бот берет список прокси, выполняет быстрые тестовые запросы через каждый прокси, измеряет время, получает внешний IP и геоданные, сохраняет результаты в SQLite. Если прокси упал или заметно деградировал, бот формирует аккуратное сообщение и шлет в Telegram. Дополнительно бот реагирует на команды из чата: показать статус, аптайм, последние ошибки, выгрузить CSV, добавить или отключить прокси, изменить интервал.

Совет: Чтобы не превысить лимиты ip-api.com (обычно 45 запросов в минуту для бесплатного уровня), мы внедрим кэш геоданных и ограничение параллельных запросов геолокации. Это не замедлит работу, но защитит от блокировки.

Шаг 1: Создаем бота в Telegram и настраиваем доступ

Цель этапа

Получить токен Telegram-бота и создать приватный чат для уведомлений, чтобы позже бот мог отправлять сообщения об инцидентах.

Пошаговая инструкция

  1. Откройте приложение Telegram на телефоне или компьютере.
  2. В строке поиска введите BotFather и откройте официальный аккаунт с синей галочкой.
  3. Нажмите Start или введите команду /start, затем введите /newbot.
  4. Придумайте имя бота. Например: ProxyMonitorBot.
  5. Придумайте уникальное имя пользователя бота, оканчивающееся на bot. Например: proxy_monitor_helper_bot.
  6. Скопируйте выданный токен. Он выглядит как набор символов и цифр, разделенных двоеточием.
  7. Создайте приватный чат или группу, куда бот будет высылать уведомления. Добавьте туда бота.
  8. Напишите в чат любое сообщение, чтобы чат появился в списке для вашего аккаунта.
  9. Откройте у бота диалог и нажмите Start, чтобы активировать его.

Важные моменты: Токен храните в секрете. Никому не передавайте. При утечке токена злоумышленник сможет управлять вашим ботом. Если токен скомпрометирован, в BotFather выберите /revoke и получите новый.

Совет: Создайте отдельную группу для алертов, где будете только вы и бот. Так уведомления не потеряются среди других сообщений.

✅ Проверка: Вы получили токен и добавили бота в нужный чат. Бот отвечает на команду /start в личном диалоге.

Возможные проблемы и решения

  • Проблема: Бот не отвечает на /start. Причина: Вы не нажали Start или токен введен неверно в коде. Решение: Проверьте, что бот активирован и позже мы правильно укажем токен в .env файле.
  • Проблема: Не видите чат ID. Причина: Мы его пока не получали. Решение: Позже команда в боте покажет chat_id автоматически.

Шаг 2: Подготавливаем окружение Python и структуру проекта

Цель этапа

Создать рабочую папку проекта, виртуальное окружение Python 3.11+, установить зависимости, настроить конфигурацию и структуру каталогов.

Пошаговая инструкция

  1. Откройте терминал на вашей машине или подключитесь к VPS через SSH.
  2. Проверьте версию Python командой: python3 --version. Если версия ниже 3.11, установите актуальную.
  3. На Ubuntu выполните: sudo apt update; sudo apt install -y python3.11 python3.11-venv python3-pip.
  4. Создайте папку проекта: mkdir proxy-monitor-bot; cd proxy-monitor-bot.
  5. Создайте виртуальное окружение: python3.11 -m venv .venv.
  6. Активируйте окружение: source .venv/bin/activate.
  7. Обновите pip: pip install --upgrade pip.
  8. Установите зависимости: pip install aiogram aiohttp aiosqlite APScheduler python-dotenv uvloop.
  9. Создайте структуру папок: mkdir app app/modules app/db app/bot app/web.
  10. Создайте файлы: touch app/__init__.py app/config.py app/main.py app/modules/proxy_checker.py app/db/models.py app/db/migrations.py app/bot/handlers.py app/bot/notifications.py app/scheduler.py app/web/server.py .env .env.example README.md.

Базовая конфигурация

Откройте файл .env и добавьте ключи (замените значения на свои):

BOT_TOKEN=ваш_токен_из_BotFather TELEGRAM_CHAT_ID=число_или_оставьте_пустым DB_PATH=./data/monitor.db PROBE_TIMEOUT=8 PROBE_RETRIES=2 CHECK_INTERVAL_MINUTES=10 GEO_CACHE_TTL_HOURS=24 IP_API_URL=http://ip-api.com/json PROXY_CONCURRENCY=20 GEO_CONCURRENCY=10 DASHBOARD_HOST=0.0.0.0 DASHBOARD_PORT=8080

Скопируйте .env в .env.example и удалите секреты, чтобы было удобно делиться проектом без токенов.

Совет: Храните файл .env вне системы контроля версий. Добавьте .env в .gitignore, чтобы случайно не загрузить токен в репозиторий.

Минимальная структура кода

Файл app/config.py будет читать переменные окружения и предоставлять конфиг. Файл app/main.py будет запускать бота, планировщик и web-dashboard. Модуль proxy_checker.py выполнит все проверки. В папке db разместим модели и миграции SQLite. В bot напишем обработчики команд и отправку уведомлений. В web запустим простой web-сервер со статистикой и выгрузкой.

✅ Проверка: У вас есть виртуальное окружение, установлены зависимости, создан файл .env, и структура проекта соответствует перечисленной. Команда python -c "import aiogram, aiohttp, aiosqlite; print('ok')" выводит ok.

Возможные проблемы и решения

  • Проблема: pip сообщает об ошибке SSL или недоступности. Причина: Нет доступа в интернет. Решение: Проверьте сеть или используйте локальное зеркало pip.
  • Проблема: Python 3.11 недоступен. Причина: Старая ОС. Решение: Обновите систему или установите Python через deadsnakes PPA или pyenv.

Шаг 3: Пишем модуль проверки прокси: подключение, latency, IP, геолокация

Цель этапа

Создать асинхронный модуль, который быстро и надежно проверяет прокси: умеет делать тестовый HTTP-запрос через прокси, измерять задержку, узнавать внешний IP, выполнять запрос к ip-api.com, кэшировать геоданные и корректно обрабатывать ошибки.

Ключевые идеи

  • Для проверки доступности делаем запрос к легкому ресурсу, например к https://api.ipify.org или к любому быстрому echo-эндпоинту. Мы выберем получение IP через сервис, а затем гео через ip-api.com. Можно и наоборот.
  • Тайм-аут ставим 8 секунд по умолчанию, попыток 2. Эти параметры настраиваются через .env.
  • aiohttp удобно работает с прокси: передаем параметр proxy в ClientSession.request.
  • Для geolocation кэшируем данные на 24 часа по IP, чтобы не тратить лимит.
  • Параллелим проверки, но ограничиваем одновременность семафором, чтобы не перегружать соединения и не упираться в лимиты ip-api.

Детальная инструкция

  1. Откройте файл app/modules/proxy_checker.py.
  2. Опишите модель прокси как словарь: id, label, type (http, https, socks5), endpoint (host:port), username, password, region, group, expected_country, last_ip.
  3. Создайте асинхронную функцию build_proxy_url, которая из type, host, port и опционально username:password формирует строку вида scheme://user:pass@host:port.
  4. Создайте асинхронную функцию fetch_ip(session, proxy_url) для получения внешнего IP через прокси. Используйте url https://api.ipify.org?format=json или аналогичный сервис, который возвращает ваш IP в JSON. Засекайте время до вызова и после ответа, чтобы получить latency.
  5. Создайте кэш геоданных: словарь в памяти и таблицу в SQLite, чтобы между перезапусками не терять кэш. Ключ — IP, значение — JSON страны, города, организации и времени кеширования.
  6. Создайте функцию fetch_geo(session, ip), которая делает GET запрос к ip-api.com/json/{ip}?fields=status,country,countryCode,regionName,city,org,query. При статусе fail верните признак ошибки. При успехе верните геоданные.
  7. Реализуйте функцию check_proxy(proxy) с логикой: построить proxy_url, попытаться получить IP с тайм-аутом, измерить latency, затем получить геоданные (из кэша или сети), сформировать результат: доступность (ok), задержка в миллисекундах, внешний IP, страна и город, и тип результата: UP, DEGRADED или DOWN.
  8. Определите критерии DEGRADED: если latency выше вашего порога, например 1500–2000 мс, или если доля ошибок в последних проверках заметна. Для простоты: если ответ есть, но latency больше 2 секунд — DEGRADED, иначе UP. Если ответа нет — DOWN.
  9. Верните подробный результат для логирования: timestamp, proxy_id, status, latency_ms или None, ip или None, geo или None, error_reason, changed_ip (True или False если IP отличается от previous), changed_geo (если страна изменилась), region, group, type.
  10. Добавьте обработку исключений: asyncio.TimeoutError, aiohttp.ClientConnectorError, aiohttp.ClientHttpProxyError, aiohttp.ClientProxyConnectionError, sock errors. В поле error_reason запишите краткое описание.

Пример кода (упрощенно, в одну строку)

Пример логики в компактном виде: import asyncio, time, json, aiohttp; async def check_proxy(proxy, cfg, geo_cache, sem): async with sem: start=time.perf_counter(); purl=f"{proxy['type']}://{proxy.get('username', '')+(':'+proxy.get('password','') if proxy.get('username') else '')+'@' if proxy.get('username') else ''}{proxy['endpoint']}"; timeout=aiohttp.ClientTimeout(total=cfg['PROBE_TIMEOUT']); try: async with aiohttp.ClientSession(timeout=timeout) as s: t0=time.perf_counter(); async with s.get('https://api.ipify.org?format=json', proxy=purl, ssl=False) as r: data=await r.json(); ip=data.get('ip'); latency=int((time.perf_counter()-t0)*1000); if not ip: raise Exception('no-ip'); geo=geo_cache.get(ip); if not geo or geo['ts']

В реальном коде мы добавим логирование в SQLite и семафоры для GEO-запросов, а также аккуратные тайм-ауты и ретраи.

⚠️ Внимание: Не делайте слишком много параллельных запросов к ip-api.com. Если у вас список из сотен прокси, кэшируйте результаты и ограничьте одновременность запросов. Это защитит от лимитов и ошибок.

✅ Проверка: Вручную вызовите функцию check_proxy для одного тестового прокси и распечатайте результат. Вы должны увидеть статус UP или DEGRADED с измеренной задержкой и внешний IP.

Возможные проблемы и решения

  • Проблема: Ошибка ClientHttpProxyError. Причина: Прокси не поддерживает запрошенный тип или неверная авторизация. Решение: Проверьте тип и учетные данные, обновите endpoint.
  • Проблема: Geo всегда unknown. Причина: Ошибка запроса к ip-api или блокировка. Решение: Проверьте IP_API_URL и сеть, включите логирование исключений.

Шаг 4: Настраиваем базу SQLite и логирование истории

Цель этапа

Создать таблицы в SQLite для хранения списка прокси, истории проверок, инцидентов, кэша гео и настроек. Это даст вам детальную статистику и возможность строить графики.

Структура базы

  • proxies: id, label, type, endpoint, username, password, region, group_name, expected_country, last_ip, enabled, created_at, updated_at.
  • checks: id, proxy_id, ts, status, latency_ms, ip, country, city, org, error_reason.
  • incidents: id, proxy_id, opened_at, closed_at, kind (DOWN или DEGRADED), last_status, last_message, active.
  • geo_cache: ip, country, city, org, ts.
  • settings: key, value (например, интервал проверки по умолчанию).

Детальная инструкция

  1. Откройте app/db/models.py. Опишите константы SQL для создания таблиц. Добавьте индексы по proxy_id и ts, чтобы ускорить выборки.
  2. Создайте функцию init_db(db_path), которая создает папку data при необходимости, открывает соединение aiosqlite.connect и выполняет create table if not exists для всех таблиц.
  3. Добавьте функции для записи результатов: add_proxy, update_proxy_last_ip, add_check, open_incident, close_incident_if_needed, upsert_geo_cache, get_recent_checks, get_uptime_stats.
  4. Реализуйте миграции в app/db/migrations.py. Для первого запуска достаточно выполнить все create table. При обновлениях версии скрипт будет добавлять недостающие столбцы.

Пример SQL (в одну строку)

CREATE TABLE IF NOT EXISTS proxies (id INTEGER PRIMARY KEY AUTOINCREMENT, label TEXT, type TEXT, endpoint TEXT, username TEXT, password TEXT, region TEXT, group_name TEXT, expected_country TEXT, last_ip TEXT, enabled INTEGER DEFAULT 1, created_at INTEGER, updated_at INTEGER); CREATE TABLE IF NOT EXISTS checks (id INTEGER PRIMARY KEY AUTOINCREMENT, proxy_id INTEGER, ts INTEGER, status TEXT, latency_ms INTEGER, ip TEXT, country TEXT, city TEXT, org TEXT, error_reason TEXT, FOREIGN KEY(proxy_id) REFERENCES proxies(id)); CREATE INDEX IF NOT EXISTS idx_checks_proxy_ts ON checks(proxy_id, ts); CREATE TABLE IF NOT EXISTS incidents (id INTEGER PRIMARY KEY AUTOINCREMENT, proxy_id INTEGER, opened_at INTEGER, closed_at INTEGER, kind TEXT, last_status TEXT, last_message TEXT, active INTEGER, FOREIGN KEY(proxy_id) REFERENCES proxies(id)); CREATE TABLE IF NOT EXISTS geo_cache (ip TEXT PRIMARY KEY, country TEXT, city TEXT, org TEXT, ts INTEGER); CREATE TABLE IF NOT EXISTS settings (key TEXT PRIMARY KEY, value TEXT);

Совет: Если вы уже храните список прокси в CSV или JSON, добавьте удобный импорт в базу: простой скрипт читает файл и добавляет записи в proxies.

✅ Проверка: Запустите функцию init_db и убедитесь, что файл базы данных появился по пути из DB_PATH. Проверьте, что таблицы созданы, выполнив простой запрос select count(*) from proxies и получив ответ 0.

Возможные проблемы и решения

  • Проблема: Ошибка no such table. Причина: Не выполнена инициализация. Решение: Вызовите init_db при старте приложения до всех операций.
  • Проблема: Блокировки на запись. Причина: Одновременные транзакции. Решение: По возможности сгруппируйте записи результатов в батчи или используйте короткие транзакции.

Шаг 5: Реализуем Telegram-бота на aiogram 3

Цель этапа

Поднять бота, который реагирует на команды, умеет отправлять уведомления в ваш чат и читать настройки из .env. Настроим базовые команды: /start, /status, /chatid, /addproxy, /list, /enable, /disable, /interval, /export.

Детальная инструкция

  1. Откройте app/bot/handlers.py. Создайте маршруты команд. Для aiogram 3 используйте Router, Dispatcher и асинхронные хендлеры.
  2. Реализуйте /start: отвечает с кратким описанием возможностей и текущим интервалом проверок.
  3. Реализуйте /chatid: отправляет идентификатор чата, чтобы вы могли сохранить TELEGRAM_CHAT_ID в .env. Это удобно, если вы запускаете бот из личного чата или группы.
  4. Реализуйте /status: находит последние N проверок для каждого прокси и выводит краткую сводку: статус, latency, страна, время обновления.
  5. Реализуйте /list: список прокси с id, label, type, region, enabled.
  6. Реализуйте /addproxy: параметрами передавайте type, endpoint, username, password, region, group, expected_country. На первом шаге можно сделать простую версию, которая принимает строку формата type=http endpoint=host:port region=EU и парсит параметры.
  7. Реализуйте /enable и /disable с параметром id, чтобы быстро включать и выключать конкретный прокси.
  8. Реализуйте /interval N для изменения интервала проверки в минутах. Сохраняйте значение в таблице settings.
  9. Реализуйте /export для генерации CSV по последним проверкам за период. Позже мы добавим аналогичную кнопку в web-dashboard.

Отправка уведомлений

В app/bot/notifications.py сделайте функцию notify_change, которая формирует сообщение о событиях. Пример сообщения: Прокси: EU-1 (http) Регион: EU Группа: EUROPE Статус: DOWN Причина: timeout Последний IP: 203.0.113.45 Ожидалось: страна DE Получено: страна NL Время: 2026-02-01 12:34:56 Latency: n/a. Для UP используйте метку UP, для деградаций DEGRADED. Добавьте сортировку по важности: сначала DOWN, затем DEGRADED, затем сообщения о смене IP. Добавьте эмодзи-индикаторы для наглядности, например ✅ для UP и ⚠️ для DEGRADED и ❌ для DOWN. Если TELEGRAM_CHAT_ID не задан, отправляйте в текущий чат, откуда пришла команда. В продакшен лучше зафиксировать chat_id в .env.

Совет: Для групп чат-боту может потребоваться права на отправку сообщений. Проверьте настройки группы, чтобы бот был участником с правом писать.

✅ Проверка: Запустите бота локально и отправьте ему /chatid. Вы должны получить числовой идентификатор. Установите TELEGRAM_CHAT_ID в .env. Отправьте /start и /status. Бот должен ответить. Команда /list пока может быть пустой, это нормально.

Возможные проблемы и решения

  • Проблема: Бот не запускается. Причина: Неверный токен. Решение: Проверьте BOT_TOKEN в .env, лишние пробелы и переносы строк.
  • Проблема: Команды не выполняются. Причина: Router не подключен. Решение: Убедитесь, что вы добавили router в Dispatcher и запускаете polling.

Шаг 6: Планировщик проверок на APScheduler

Цель этапа

Настроить периодические проверки всех включенных прокси каждые 5–15 минут с учетом текущего интервала из настроек, параллелить проверки без перегрузки, логировать историю и слать алерты при изменениях.

Детальная инструкция

  1. Откройте app/scheduler.py. Инициализируйте AsyncIOScheduler.
  2. Создайте задачу run_checks, которая выбирает из базы все proxies с enabled=1, шлет их на проверку в пул асинхронных задач с семафором PROXY_CONCURRENCY, собирает результаты.
  3. Для каждого результата записывайте строку в checks. Обновляйте last_ip в proxies при изменении.
  4. Логика инцидентов: если статус DOWN и инцидента нет, создайте запись incidents (active=1). Если статус снова UP, закройте инцидент (active=0, closed_at=ts). Для DEGRADED аналогично, но можно объединять DEGRADED в один активный инцидент или закрывать при восстановлении.
  5. Отправляйте уведомления: при первом переходе в DOWN, при DEGRADED, при восстановлении в UP, при смене IP или смене страны. Группируйте сообщения, если одновременно множество прокси сменили статус: отправьте один заголовок и список элементов.
  6. Создайте джобу scheduler.add_job(run_checks, 'interval', minutes=CHECK_INTERVAL_MINUTES, id='checks', replace_existing=True). Добавьте реакцию на /interval, чтобы перезапускать джобу с новым интервалом без перезапуска бота.
  7. Запустите scheduler.start() вместе с запуском бота и web-сервера в main.

Совет:

Совет: Добавьте случайный джиттер 0–60 секунд к расписанию, чтобы снизить пиковую нагрузку и избежать ровно синхронных запросов.

✅ Проверка: Установите CHECK_INTERVAL_MINUTES=1 временно и запустите приложение. В логах вы должны увидеть, что проверки выполняются каждую минуту, и в таблицу checks добавляются новые строки.

Возможные проблемы и решения

  • Проблема: Проверки не запускаются. Причина: Scheduler не стартует. Решение: Убедитесь, что вызван scheduler.start() и нет исключений при создании джобы.
  • Проблема: Блокировки базы. Причина: Слишком частые записи. Решение: Сократите интервал или добавьте буферизацию записей, записывая пакетно.

Пошаговая инструкция: Шаг 7: Интегрируем все части в точку входа main.py

Цель этапа

Собрать приложение целиком: конфиг, БД, бот, проверщик, планировщик и web-dashboard. Обеспечить корректный старт и остановку, обработать сигналы завершения.

Детальная инструкция

  1. Откройте app/main.py. Импортируйте asyncio, logging, uvloop (если Linux), aiogram, функции init_db, router, scheduler, web сервер.
  2. Загрузите конфигурацию из .env через python-dotenv. Проверьте обязательные ключи: BOT_TOKEN и DB_PATH.
  3. Инициализируйте БД: await init_db(DB_PATH).
  4. Создайте Dispatcher и Router из aiogram 3, добавьте хендлеры команд.
  5. Создайте планировщик APScheduler и добавьте задачу run_checks согласно интервалу.
  6. Запустите одновременно три компонента: polling бота, scheduler.start(), web-dashboard. Используйте asyncio.gather для параллельного запуска.
  7. Обработайте сигналы SIGINT и SIGTERM: корректно остановите scheduler, закройте соединения с БД и завершите polling.

Упрощенная идея запуска в одну строку: import asyncio, logging; async def main(): await init_db(...); dp=Dispatcher(); dp.include_router(router); scheduler=AsyncIOScheduler(); scheduler.add_job(run_checks, 'interval', minutes=interval); scheduler.start(); await asyncio.gather(dp.start_polling(bot), start_web_server(), wait_for_signals(scheduler)); asyncio.run(main()).

Совет: Добавьте подробное логирование на уровень INFO и WARN. Это поможет быстро понять, что происходит при запуске и во время проверок.

✅ Проверка: Запустите python app/main.py. Бот должен ответить на /start, web-dashboard должен открываться по адресу http://localhost:8080, а планировщик начать проверки по интервалу.

Возможные проблемы и решения

  • Проблема: Адрес 0.0.0.0:8080 занят. Причина: Порт используется другим процессом. Решение: Измените DASHBOARD_PORT в .env или остановите занятый процесс.
  • Проблема: Ошибка при запуске polling. Причина: Неверный токен или сеть. Решение: Проверьте BOT_TOKEN и интернет-доступ.

Шаг 8: Формат уведомлений и группировка прокси

Цель этапа

Сделать уведомления понятными, компактными и информативными. Настроить группировку прокси по регионам и типам, чтобы сообщения были структурированными.

Формат уведомлений

  • Заголовок: Изменения статуса прокси.
  • Подзаголовок: дата и время.
  • Секции по приоритету: DOWN, затем DEGRADED, затем Восстановление, затем Смена IP, затем Смена гео.
  • Каждый пункт: [Регион] [Группа] [Label] ([type]) статус, latency, IP, страна, причина.
  • Иконки: DOWN помечаем ❌, DEGRADED — ⚠️, UP — ✅.

Группировка прокси

  • По полю region: EU, US, ASIA и другие.
  • По полю group_name: логическая группировка, например EUROPE, PAID, TESTING.
  • По типу: http, https, socks5.

Реализация

  1. В app/bot/notifications.py создайте функции group_by_region и group_by_type, чтобы сгруппировать результаты перед отправкой. Это позволит отправлять меньше сообщений и повысить читаемость.
  2. Для каждого блока формируйте короткие строки с ключевыми данными: "EU, EUROPE, EU-1 (http): ❌ DOWN, timeout" или "US, AMERICA, US-2 (socks5): ⚠️ DEGRADED, 2300ms, country US".
  3. Если изменений много, отправьте один сводный заголовок и несколько сообщений по регионам. Это лучше, чем 100 отдельных сообщений.

✅ Проверка: Временно подмените один прокси на заведомо нерабочий endpoint. Дождитесь проверки. Вы получите уведомление с блоком DOWN. Верните прокси в рабочий, увидите уведомление о восстановлении.

Возможные проблемы и решения

  • Проблема: Слишком длинные сообщения. Причина: Много деталей. Решение: Сократить поля, в подробности уходить по команде /status или /details id.
  • Проблема: Дубли алертов. Причина: Повторная отправка при неизменном статусе. Решение: Шлите уведомление только при переходах статусов и при явной смене IP или страны.

Шаг 9: Деплой на VPS (Ubuntu) и автозапуск

Цель этапа

Развернуть бота на удаленном сервере, настроить автозапуск через systemd, обеспечить логирование и простое обновление.

Подготовка VPS

  1. Подключитесь к VPS: ssh user@server_ip.
  2. Обновите систему: sudo apt update && sudo apt upgrade -y.
  3. Установите Python, если не установлен: sudo apt install -y python3.11 python3.11-venv python3-pip.
  4. Создайте пользователя для приложения, если нужно: sudo adduser botuser; затем войдите под ним.
  5. Скопируйте проект на сервер по scp или git clone вашего репозитория.
  6. Создайте виртуальное окружение и установите зависимости как на шаге 2.
  7. Проверьте .env. Заполните реальные значения BOT_TOKEN и TELEGRAM_CHAT_ID.

systemd сервис

  1. Создайте файл сервиса: sudo nano /etc/systemd/system/proxy-monitor.service.
  2. Пример Unit (одной строкой): [Unit] Description=Proxy Monitor Bot After=network.target [Service] Type=simple User=botuser WorkingDirectory=/home/botuser/proxy-monitor-bot ExecStart=/home/botuser/proxy-monitor-bot/.venv/bin/python -m app.main Environment=PYTHONUNBUFFERED=1 Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target.
  3. Перезагрузите демона: sudo systemctl daemon-reload.
  4. Включите автозапуск: sudo systemctl enable proxy-monitor.service.
  5. Запустите: sudo systemctl start proxy-monitor.service.
  6. Проверьте лог: journalctl -u proxy-monitor.service -f.

Совет: Если вы используете uvloop, убедитесь, что он установлен в виртуальном окружении. На Windows uvloop не используется, на Linux улучшает производительность.

✅ Проверка: Бот отвечает на /start из вашего Telegram при запущенном сервисе. В журнале видно запуск планировщика и web-dashboard слушает порт 8080.

Возможные проблемы и решения

  • Проблема: Сервис падает сразу. Причина: Неверный путь к Python или рабочей директории. Решение: Проверьте ExecStart и WorkingDirectory, права пользователя.
  • Проблема: Нет доступа к порту 8080 извне. Причина: UFW или облачный firewall. Решение: Откройте порт: sudo ufw allow 8080 или настройте правила в панели провайдера.

Проверка результата

Чек-лист

  • Бот принимает команды /start, /status, /list, /chatid.
  • Планировщик запускает проверки по интервалу, записи появляются в таблице checks.
  • При падении прокси бот отправляет уведомление в Telegram.
  • Смена IP фиксируется и отмечается в сообщениях.
  • Геолокация определяется и сравнивается с ожидаемой страной.
  • Dashboard отображается на указанном порту, показывает аптайм и последние события.
  • Экспорт CSV работает и выдает корректный файл.

Как протестировать

  1. Отключите один из прокси или укажите неверный порт. Дождитесь алерта DOWN.
  2. Поменяйте временно endpoint на другой, чтобы вызвать смену IP. Убедитесь, что бот сообщает об изменении IP и страны, если она поменялась.
  3. Повысите искусственно latency через ограничение сети (если возможно) или проверьте тяжелым запросом, чтобы получить DEGRADED.
  4. Проверьте команды: /interval 5, /list, /enable, /disable и убедитесь в отражении состояния.

Показатели успешного выполнения

  • Стабильные проверки без ошибок в логах.
  • Вовремя приходящие алерты при реальных проблемах.
  • Корректная работа инцидент-логики: открытие при DOWN и закрытие при UP.

✅ Проверка: Если все пункты чек-листа проходят и тестовые сценарии работают, ваш бот успешно развернут и выполняет задачи мониторинга корректно.

Типичные ошибки и решения

  • Проблема: Нет уведомлений в Telegram → Причина: Неверный TELEGRAM_CHAT_ID или бот не член группы → Решение: Выполните /chatid в нужном чате, сохраните ID в .env, добавьте бота в чат и дайте ему право писать.
  • Проблема: Все прокси DOWN, хотя они рабочие → Причина: Неверный формат proxy URL или тип → Решение: Проверьте type=http, https или socks5, проверьте авторизацию user:pass и endpoint host:port, протестируйте один прокси отдельно.
  • Проблема: Геолокация не определяется → Причина: Лимит ip-api или ошибка сети → Решение: Включите кэширование, снизьте частоту запросов к ip-api, проверьте IP_API_URL.
  • Проблема: База растет слишком быстро → Причина: Слишком частые проверки и большое число прокси → Решение: Увеличьте интервал, включите очистку старых записей, экспортируйте архивы и удаляйте старше 30–90 дней.
  • Проблема: Высокая задержка у всех прокси → Причина: Сервер перегружен или сетевые проблемы → Решение: Увеличьте ресурсы VPS, уменьшите PROXY_CONCURRENCY, используйте ближний регион.
  • Проблема: Дублирующие алерты о том же инциденте → Причина: Не хранится состояние инцидента → Решение: Используйте таблицу incidents и отправляйте алерт только при изменении статуса.
  • Проблема: Бот часто падает при исключениях → Причина: Непойманные ошибки → Решение: Оберните сетевые операции try-except, добавьте логирование и ретраи.

Дополнительные возможности

Продвинутые настройки

  • Гибкие пороги деградации: храните пороги latency по группам в таблице settings.
  • Разные интервалы по группам: важные прокси проверяйте раз в 5 минут, второстепенные раз в 15–30.
  • Расширенный парсинг команд: используйте формат key=value и строгую валидацию параметров.

Оптимизация

  • Включите uvloop на Linux для ускорения событийного цикла.
  • Используйте батч-записи в SQLite или WAL-режим для ускорения конкурентных записей.
  • Параметризуйте semaphores для балансировки между скоростью и нагрузкой.

Простой dashboard

В app/web/server.py поднимите aiohttp.web сервер. На главной странице отобразите сводку: количество прокси, сколько UP, DOWN, DEGRADED, средний latency, аптайм за 24 часа. Сделайте эндпоинт /export?from=ts&to=ts для CSV-выгрузки. Минимальный HTML может быть простым списком и таблицей со статусом. Визуализацию графиков можно добавить позже через простые SVG.

Совет: Добавьте кнопку Переключить интервал прямо в dashboard, которая дергает эндпоинт и меняет значение в settings. Это ускорит управление без Telegram-команд.

Резервные копии

Скрипт бэкапа базы: tar -czf backup-$(date +%F).tar.gz data/monitor.db. Запланируйте ежедневный бэкап через cron или systemd timers. Храните хотя бы последние 7 архивов.

⚠️ Внимание: Не редактируйте файл базы на лету. Для ручных правок останавливайте сервис, делайте копию, редактируйте и запускайте снова.

FAQ

  • Как добавить прокси с авторизацией? В команде /addproxy укажите username и password, или добавьте user:pass в endpoint. Пример: type=http endpoint=user:pass@host:port.
  • Как ограничить проверки ночью? Реализуйте расписание cron-like в APScheduler, добавив триггер с окном времени, или просто увеличьте интервал ночью через автоматическое правило.
  • Что делать, если ip-api.com недоступен? Используйте кэш и временно пропускайте гео-запросы. Позже можно добавить резервный источник гео.
  • Как отфильтровать уведомления? Добавьте уровни важности и настройку: слать только DOWN, а DEGRADED отправлять суммарно раз в час.
  • Можно ли использовать PostgreSQL? Да. Замените aiosqlite на asyncpg, адаптируйте SQL и подключение. Для больших объемов это удобнее.
  • Как безопасно хранить токены? В .env на сервере с правами 600. Периодически обновляйте токен при необходимости.
  • Почему бот иногда получает timeout? Сети нестабильны. Увеличьте PROBE_TIMEOUT, уменьшите параллелизм, проверьте маршруты.
  • Можно ли проверить IPv6 прокси? Да, если целевые сервисы поддерживают IPv6. Проверьте, что endpoint выдает IPv6 и ip-api корректно отрабатывает адрес.
  • Как отслеживать конкретный оператор связи? В сообщении сохраняйте org из ip-api и сравнивайте с ожидаемым значением по правилу.
  • Как отключить прокси на время? Используйте /disable id, чтобы временно исключить прокси из проверок без удаления из базы.

Заключение

Вы прошли полный путь от идеи до рабочего решения: создали Telegram-бота на aiogram 3, написали модуль проверок прокси на aiohttp, настроили планировщик APScheduler, сохранили историю в SQLite, реализовали уведомления о падениях, деградациях, смене IP и геолокации, развернули приложение на VPS с автозапуском через systemd и добавили простой web-dashboard с экспортом логов. Теперь у вас есть гибкий инструмент, который можно масштабировать: разделять группы, настраивать пороги, подключать графики и отчеты, переносить на PostgreSQL при росте нагрузки. Следующий шаг — автоматизация обслуживания: настройки ротации логов, ежедневные бэкапы базы, мониторинг самого бота через системные метрики VPS. Вы можете развиваться дальше: добавить ролевую модель доступа к командам бота, внедрить SLA-отчеты по группам, подключить альтернативные источники геоданных, сделать веб-интерфейс на любой удобной вам библиотеке. Удачи и стабильного аптайма вашим прокси!