# simple-reminder-bot Простой бот-напоминалка: читает JSON-конфиг и отправляет сообщения в Telegram - по расписанию из конфига. Конфиг можно править на лету: бот сам подхватывает изменения (время обновления до минуты), рестарт не нужен. Единственная зависимость - `requests`. ## Workflow - `interval` - сообщение отправляется каждые N секунд/минут/часов/дней. Первое сообщение уходит сразу при запуске (или в `start_at`), дальше - каждые N. - `at` - сообщение отправляется один раз в указанный момент. Если момент уже прошёл, напоминание пропускается с предупреждением в логе. - `at` + `repeat: "yearly"` (или `"monthly"`) - сообщение отправляется каждый год (месяц) в ту же календарную дату. Если дата уже прошла, бот сразу планирует ближайшее будущее наступление. - Когда все разовые напоминания отправлены (и в конфиге не осталось активных), процесс завершается с кодом 0. - Пропущенные повторные отправки не «догоняются»: после долгой паузы (сон, перезапуск) уйдёт максимум одно сообщение. - При получении `SIGTERM`/`SIGINT` (в том числе `docker stop`) бот завершается корректно. ## Hot-reload конфига - Пока бот работает, файл конфига проверяется на изменения (mtime) - не реже раза в минуту. Если файл изменился, конфиг перечитывается на ходу. - Мгновенное перечитывание - по `SIGHUP`: `docker kill -s HUP simple-reminder-bot` - Новые (или изменившиеся по расписанию) напоминания начинают работать так же, как при запуске бота: интервальные - с отправки сразу (или в `start_at`), разовые - в свой `at` (если он ещё не прошёл). - Если новый конфиг невалиден, бот пишет ошибку и продолжает работать со старым конфигом. ## Конфиг ### Верхний уровень | Поле | Описание | |-------------|---------------------------------------------------------| | `bot_token` | Токен бота | | `chat_id` | Чат по умолчанию для всех напоминаний | | `timezone` | Таймзона для дат без указания зоны (по умолчанию `UTC`) | | `reminders` | Массив напоминаний | ### Напоминания | Поле | Описание | |------------|-----------------------------------------------------------| | `message` | Текст сообщения | | `interval` | Число секунд или строка: `30s`, `5m`, `2h`, `1d`, `1h30m` | | `at` | Дата/время разовой отправки | | `repeat` | `yearly`/`monthly` - повтор по календарю (только с `at`) | | `start_at` | Первый запуск интервального напоминания | | `chat_id` | Переопределить чат для этого напоминания | | `enabled` | `false` - чтобы временно отключить напоминание | Ровно одно из `interval`/`at` обязательно. `repeat` можно только с `at`. Даты можно писать с таймзоной (`2026-12-31T10:00:00+03:00`) или без неё - тогда используется таймзона из конфига. ## Env - `CONFIG_PATH` - путь к конфигу в контейнере. - `LOG_LEVEL` - уровень логирования (`DEBUG`, `INFO`, `WARNING`, `ERROR`) ## Запуск ### Docker compose ```bash docker compose up -d ``` ### Локально ```bash pip install -r requirements.txt python reminder.py --config config.json # обычный запуск python reminder.py --check # проверить конфиг и показать расписание python reminder.py --dry-run # писать только в лог (dry-run) ```