# 📡 RSS → ntfy Лёгкое приложение на Python (FastAPI), которое следит за RSS/Atom-лентами и при появлении новых записей рассылает их в [ntfy](https://ntfy.sh), Telegram и/или через webhook. Управление — через современную веб-панель. ![tech](https://img.shields.io/badge/FastAPI-009688?logo=fastapi&logoColor=white) ![tech](https://img.shields.io/badge/Docker-2496ED?logo=docker&logoColor=white) ![tech](https://img.shields.io/badge/Python-3.12-3776AB?logo=python&logoColor=white) ## Возможности **Основное** - ✅ Добавление, редактирование и удаление RSS-лент через веб-интерфейс - ✅ Свой ntfy-сервер и тема для каждой ленты (или общий по умолчанию) - ✅ Приоритет и теги/эмодзи для каждой ленты - ✅ Опциональная авторизация при входе в веб-панель (вкл/выкл из UI) - ✅ Настраиваемый интервал проверки и кнопки «Проверить сейчас» / «тест» - ✅ Защита от дублей: при первом добавлении ленты история не рассылается **Расширенные возможности** - 🔐 **Приватные ntfy-серверы** — Bearer-токен или Basic-авторизация на ленту - ✈️ **Telegram** — дублирование уведомлений через бота (вкл. на нужных лентах) - 🔗 **Webhook** — POST с JSON в произвольный URL как ещё один канал - 🖼️ **Картинки** — первое изображение записи прикрепляется к ntfy-уведомлению - 🧩 **Фильтры по ключевым словам** — include/exclude на каждую ленту - ⏱️ **Индивидуальный интервал** проверки для каждой ленты (0 = общий) - 📊 **История и статистика** — лог всех отправок (успех/ошибка) + сводка - 👥 **Несколько пользователей и роли** — `admin` (полный доступ) и `viewer` - 🩺 **Алерты администратора** — ntfy-уведомление, если лента падает N раз подряд - 🔁 **Импорт/экспорт OPML** — перенос списка лент из/в другие ридеры **Интерфейс** - 🌗 **Светлая и тёмная тема** — переключатель, выбор запоминается - 🌍 **Локализация RU / EN** — переключение языка на лету - 👁 **Предпросмотр уведомления** — как будет выглядеть последняя запись ленты - 🔍 **Поиск по истории** + фильтр «только ошибки» - 📈 **График активности** за 14 дней (отправлено / сбои) Готов к запуску в Docker, данные хранятся в томе. Внешняя БД не нужна (SQLite). Инструкция по развёртыванию через Gitea — в [DEPLOY.md](DEPLOY.md). ## Быстрый старт (Docker Compose) ```bash docker compose up -d --build ``` Откройте **http://localhost:8000**. Логин/пароль по умолчанию — `admin` / `admin` (вход требуется только если включить авторизацию в настройках). > ⚠️ Поменяйте `ADMIN_USERNAME` / `ADMIN_PASSWORD` в `docker-compose.yml` > **до первого запуска**, либо смените пароль во вкладке «Пользователи». > Эти переменные применяются только при создании базы данных. ## Запуск без Docker ```bash python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate pip install -r requirements.txt uvicorn app.main:app --host 0.0.0.0 --port 8000 ``` ## Как пользоваться 1. **Настройки → ntfy**: укажите сервер по умолчанию и отправьте тест. 2. **Ленты → Добавить ленту**: вставьте URL RSS и тему ntfy (например `my-news`). В расширенном блоке можно задать токен приватного сервера, фильтры по словам, личный интервал и включить дублирование в Telegram/webhook. 3. Подпишитесь на тему в приложении ntfy или на `https://ntfy.sh/my-news`. 4. **История** — журнал отправленных и неудачных уведомлений. 5. **Пользователи** — добавьте учётки с ролями (нужно для включения авторизации). 6. **Настройки → Авторизация** — включите требование входа в панель. ### Telegram 1. Создайте бота через [@BotFather](https://t.me/BotFather), получите токен. 2. Добавьте бота в чат/канал и узнайте `chat_id` (например, через [@userinfobot](https://t.me/userinfobot) или `getUpdates`). 3. **Настройки → Telegram**: включите канал, вставьте токен и `chat_id`. 4. В нужных лентах поставьте галочку «Дублировать в Telegram». ### Webhook **Настройки → Webhook** → включите и укажите URL. На каждую новую запись придёт `POST` с JSON: ```json { "feed": "...", "feed_url": "...", "title": "...", "body": "...", "link": "...", "image": "..." } ``` ## Конфигурация (переменные окружения) | Переменная | По умолчанию | Описание | |---|---|---| | `DEFAULT_NTFY_SERVER` | `https://ntfy.sh` | Сервер для лент без своего | | `DEFAULT_CHECK_INTERVAL` | `5` | Интервал проверки по умолчанию, минуты | | `ADMIN_USERNAME` | `admin` | Логин админа (только при первом старте) | | `ADMIN_PASSWORD` | `admin` | Пароль админа (только при первом старте) | | `SECRET_KEY` | автогенерация | Секрет для подписи cookie сессии | | `DATA_DIR` | `./data` (`/data` в Docker) | Где лежит БД и ключ | ## Архитектура ``` app/ ├── main.py # FastAPI: страницы, JSON API, авторизация, роли ├── models.py # таблицы SQLModel (Feed, SeenEntry, Notification, User, Settings) ├── database.py # движок БД, инициализация, авто-миграция колонок ├── checker.py # парсинг лент, фильтры, картинки, история, алерты ├── delivery.py # доставка по каналам (ntfy + Telegram + webhook) ├── ntfy.py # публикация в ntfy (авторизация, вложения) ├── scheduler.py # тик раз в минуту, интервалы считаются на лету ├── opml.py # импорт/экспорт OPML ├── auth.py # хеширование пароля (PBKDF2, stdlib) ├── schemas.py # валидация запросов API ├── templates/ # Jinja2 (index, login, base) └── static/ # style.css, app.js, i18n.js (RU/EN словари) ``` Хранилище — SQLite (один файл в `DATA_DIR`). При добавлении новых полей в моделях схема существующей БД обновляется автоматически (`ALTER TABLE ... ADD COLUMN`). ## Идеи для дальнейшего развития - 📨 Доставка по e-mail (SMTP) как ещё один канал - 🔑 OAuth/OIDC для входа в больших инсталляциях - 📊 Детализация графиков по конкретной ленте - 🏷️ Группы/папки лент и массовые операции - 🌐 Поддержка прокси для доступа к лентам ## Лицензия MIT — используйте свободно.