Асинхронный Telegram‑бот, который показывает погоду в Москве (сейчас, сегодня, завтра) и может присылать ежедневное уведомление о погоде на завтра в выбранное пользователем время.
Бот реализован на aiogram 3.x, использует WeatherAPI для получения прогнозов и APScheduler для планирования уведомлений.
- Погода сейчас — текущая температура, состояние погоды и «ощущается как».
- Погода на сегодня — краткий прогноз на текущий день (средняя/макс/мин температура, дождь/снег, восход/закат, фаза Луны).
- Погода на завтра — аналогичный прогноз на следующий день.
- Уведомление о завтрашней погоде — ежедневное сообщение с прогнозом на завтра в заданное время.
- Ограничение частоты запросов — каждый режим можно вызывать не чаще одного раза в 15 минут (per‑user).
Основные используемые библиотеки:
- aiogram — асинхронный Telegram‑фреймворк (версия 3.x).
- APScheduler — планировщик задач (AsyncIOScheduler).
- Requests — HTTP‑клиент для запросов к WeatherAPI.
- python‑dotenv — загрузка переменных окружения из
.env. - Loguru — удобное логирование.
Зависимости и версии зафиксированы в pyproject.toml и uv.lock.
git clone <url_репозитория>
cd Weather_in_MoscowЕсли используешь uv (рекомендуется, т.к. в проекте уже есть pyproject.toml и uv.lock):
uv syncЕсли хочешь установить через pip, ориентируйся на зависимости:
pip install aiogram requests python-dotenv apscheduler loguru(Версии лучше уточнить в pyproject.toml.)
Создай файл .env в корне проекта со следующим содержимым:
BOT_TOKEN=токен_твоего_бота_из_BotFather
API_TOKEN=ключ_доступа_к_WeatherAPI
CODE=секретный_код_для_доступа_к_ботуBOT_TOKEN— токен Telegram‑бота (см. инструкцию BotFather).API_TOKEN— токен WeatherAPI (получить наhttps://www.weatherapi.com/, см. их документацию).CODE— любой секретный код (строка), который пользователь должен ввести после/start.
Модуль src/config.py загружает эти значения при помощи load_dotenv().
Точка входа — src/main.py, который вызывает handlers.main() через asyncio.run.
python -m src.mainили, если используешь uv:
uv run python -m src.mainПосле запуска бот начинает long polling и ждёт обновления от Telegram.
Для удобного развёртывания на сервере проект включает Dockerfile и docker-compose.yml.
- Docker (версия 20.10+)
- Docker Compose (версия 2.0+, опционально)
-
Убедись, что файл
.envсоздан и содержит все необходимые переменные (см. раздел "Настройка переменных окружения"). -
Запусти контейнер:
docker-compose up -dКонтейнер запустится в фоновом режиме и будет автоматически перезапускаться при сбоях (restart: unless-stopped).
- Просмотр логов:
docker-compose logs -f weather-bot- Остановка контейнера:
docker-compose down- Собери образ:
docker build -t weather-in-moscow-bot .- Запусти контейнер с переменными окружения из
.env:
docker run -d \
--name weather-in-moscow-bot \
--restart unless-stopped \
--env-file .env \
weather-in-moscow-botИли передай переменные окружения напрямую:
docker run -d \
--name weather-in-moscow-bot \
--restart unless-stopped \
-e BOT_TOKEN=твой_токен \
-e API_TOKEN=твой_api_токен \
-e CODE=твой_код \
weather-in-moscow-bot- Просмотр логов:
docker logs -f weather-in-moscow-bot- Остановка и удаление контейнера:
docker stop weather-in-moscow-bot
docker rm weather-in-moscow-bot- Используется многоступенчатая сборка для уменьшения размера финального образа.
- Зависимости устанавливаются через
uv(быстрый менеджер зависимостей Python). - Базовый образ:
python:3.13-slim(минимальный образ на основе Debian). - Логирование настроено через драйвер
json-fileс ротацией (максимум 10 МБ на файл, до 3 файлов). - Переменные окружения загружаются из
.envфайла черезpython-dotenv.
Для обновления кода бота:
# Останови текущий контейнер
docker-compose down
# Пересобери образ (если изменился код)
docker-compose build
# Запусти заново
docker-compose up -dЕсли изменились только переменные окружения в .env, достаточно перезапустить контейнер:
docker-compose restartДля автоматического запуска контейнера при загрузке сервера нужно настроить systemd сервис.
Важно: Убедись, что Docker настроен на автозапуск (обычно это уже включено по умолчанию):
sudo systemctl enable dockerНастройка systemd сервиса для бота:
- Скопируй файл
weather-bot.serviceв директорию systemd:
sudo cp weather-bot.service /etc/systemd/system/- Отредактируй файл и укажи правильный путь к проекту:
sudo nano /etc/systemd/system/weather-bot.serviceИзмени строку WorkingDirectory=/path/to/Weather_in_Moscow на реальный путь к проекту, например:
WorkingDirectory=/home/user/Weather_in_Moscow
Также убедись, что путь к docker-compose правильный. Обычно это /usr/bin/docker-compose или /usr/local/bin/docker-compose. Проверь:
which docker-compose- Перезагрузи конфигурацию systemd:
sudo systemctl daemon-reload- Включи автозапуск сервиса:
sudo systemctl enable weather-bot.service- Запусти сервис:
sudo systemctl start weather-bot.service- Проверь статус:
sudo systemctl status weather-bot.serviceТеперь бот будет автоматически запускаться при перезагрузке сервера.
Управление сервисом:
# Запуск
sudo systemctl start weather-bot
# Остановка
sudo systemctl stop weather-bot
# Перезапуск
sudo systemctl restart weather-bot
# Просмотр статуса
sudo systemctl status weather-bot
# Просмотр логов
sudo journalctl -u weather-bot -f
# Отключить автозапуск
sudo systemctl disable weather-botАльтернативный способ (без systemd):
Если не хочешь использовать systemd, можно использовать флаг --restart unless-stopped при запуске через Docker напрямую:
docker run -d \
--name weather-in-moscow-bot \
--restart unless-stopped \
--env-file .env \
weather-in-moscow-botВ этом случае Docker сам будет поднимать контейнер после падения/перезагрузки сервера, но не будет запускать его, если ты остановил контейнер вручную (если Docker daemon настроен на автозапуск).
-
Найди бота в Telegram по username.
-
Нажми Start или отправь
/start. -
Бот ответит: «Введите пароль для использования бота:».
-
Введи код, который ты указал в переменной окружения
CODE. -
При успешной проверке кода бот покажет клавиатуру с кнопками:
- «Погода сейчас»
- «Погода на сегодня»
- «Погода на завтра»
- «Уведомление о завтрашней погоде»
- «Выключить оповещение»
-
Нажимай на нужный режим:
- «Погода сейчас» — мгновенно получает текущую погоду через WeatherAPI.
- «Погода на сегодня» — прогноз на текущий день.
- «Погода на завтра» — прогноз на следующий день.
Каждый из этих режимов можно вызывать раз в 15 минут (ограничение реализовано в
utils.check_cooldown/update_cooldown). -
Уведомление о завтрашней погоде:
- Нажми кнопку «Уведомление о завтрашней погоде».
- Если у тебя уже есть активное уведомление, бот сообщит, что может быть только одно.
- Если уведомления нет, бот попросит время в формате
HH:MM(например,9:30). - Отправь время — будет создана ежедневная задача в APScheduler, которая будет вызывать
send_weather_funcи присылать прогноз на завтра.
-
Выключение уведомления:
- Нажми «Выключить оповещение».
- Если задача найдена — бот удалит её и напишет, что оповещение отключено.
- Если задач нет — бот сообщит, что у тебя нет активных оповещений.
src/config.py— загрузка конфигурации и создание объектов:dp: Dispatcherbot: Botscheduler: AsyncIOScheduler- токены и код доступа из
.env.
src/utils.py— утилиты:keyboard_mode()— клавиатура режимов.weather_now_func()— текущая погода.weather_today_func()— прогноз на сегодня.weather_tomorrow_func()— прогноз на завтра.send_weather_func()— отправка прогноза в чат.check_cooldown()/update_cooldown()— ограничение частоты запросов.
src/handlers.py— хэндлеры aiogram + FSM + логика APScheduler:- состояния
Auth,Notify; - обработчики
/start, пароля, кнопок режимов; - настройка/отключение уведомлений;
- корутина
main()— запуск бота.
- состояния
src/main.py— точка входа, запускаетasyncio.run(main()).
- Логи работы бота пишутся через
loguru.logger. - Планировщик задач
AsyncIOSchedulerявно запускается вhandlers.main()при помощиscheduler.start(), что соответствует документации APScheduler.