80 lines
5.0 KiB
Markdown
80 lines
5.0 KiB
Markdown
# 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)
|
||
```
|