> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bedolagam.ru/llms.txt
> Use this file to discover all available pages before exploring further.

# Уведомления и рассылки

> Рассылки, топик-уведомления, вебхуки и автоматические сообщения

## Обзор

Система уведомлений включает:

1. **Рассылки** — массовые сообщения пользователям с фильтрами
2. **Топик-уведомления** — события для администраторов в Telegram-форуме
3. **Вебхук-уведомления** — автоматические сообщения пользователям от RemnaWave
4. **Уведомления о подписке** — напоминания, волны возврата, автопродление
5. **Закреплённые сообщения** — отображение при каждом `/start`

## Рассылки (Broadcasts)

### Создание рассылки

1. Администратор выбирает **аудиторию**
2. Вводит **текст** (до 4000 символов, HTML)
3. Опционально прикрепляет **медиа** (фото, видео, документ, до 50 МБ)
4. Выбирает **инлайн-кнопки** для прикрепления к сообщению
5. **Превью** с количеством получателей
6. **Подтверждение** и отправка

### Каналы рассылки

| Канал      | Описание           |
| ---------- | ------------------ |
| `telegram` | Через Telegram бот |
| `email`    | Через SMTP         |
| `both`     | Telegram + Email   |

### Аудитории

#### Базовые фильтры

| Фильтр        | Описание                              |
| ------------- | ------------------------------------- |
| `all`         | Все активные пользователи             |
| `active`      | Платная активная подписка             |
| `trial`       | Триальная подписка                    |
| `no_sub`      | Без активной подписки                 |
| `expiring`    | Подписка истекает в течение 3 дней    |
| `expired`     | Истёкшая/отключённая подписка         |
| `active_zero` | Платная подписка, 0 ГБ использовано   |
| `trial_zero`  | Триальная подписка, 0 ГБ использовано |
| `zero`        | Любая подписка, 0 ГБ использовано     |

#### Расширенные фильтры

| Фильтр                 | Описание                                 |
| ---------------------- | ---------------------------------------- |
| `expiring_subscribers` | Подписка истекает за 7 дней              |
| `canceled_subscribers` | Статус `DISABLED`                        |
| `trial_ending`         | Триал истекает за 3 дня                  |
| `trial_expired`        | Триал уже истёк                          |
| `autopay_failed`       | Неудачный автоплатёж за последние 7 дней |
| `low_balance`          | Баланс > 0, но \< 100 руб                |
| `inactive_30d/60d/90d` | Неактивны N дней                         |
| `tariff_{id}`          | Пользователи конкретного тарифа          |

#### Кастомные критерии

| Критерий         | Описание                 |
| ---------------- | ------------------------ |
| `today`          | Зарегистрированы сегодня |
| `week`           | За последние 7 дней      |
| `month`          | За последние 30 дней     |
| `active_today`   | Активны сегодня          |
| `inactive_week`  | Неактивны 7+ дней        |
| `inactive_month` | Неактивны 30+ дней       |
| `referrals`      | Пришли по рефералу       |
| `direct`         | Прямая регистрация       |

#### Email-фильтры

| Фильтр                | Описание                                |
| --------------------- | --------------------------------------- |
| `all_email`           | Все с подтверждённым email              |
| `email_only`          | Только email-авторизация                |
| `telegram_with_email` | Telegram + email                        |
| `active_email`        | Email-пользователи с активной подпиской |
| `expired_email`       | Email-пользователи с истёкшей подпиской |

### Инлайн-кнопки

К рассылке можно прикрепить кнопки быстрого действия:

| Кнопка           | Действие                      |
| ---------------- | ----------------------------- |
| Пополнить баланс | `balance_topup`               |
| Партнёрка        | `menu_referrals`              |
| Промокод         | `menu_promocode`              |
| Подключиться     | `subscription_connect`        |
| Подписка         | `menu_subscription`           |
| Техподдержка     | `menu_support`                |
| На главную       | `back_to_menu` (по умолчанию) |

### Доставка

* **Rate limiting**: \~25 сообщений/сек (батчи по 25 с задержкой 1 сек)
* **Повторные попытки**: до 3 раз при неудаче
* **FloodWait**: глобальная пауза при лимите Telegram
* **Прогресс**: обновление каждые 500 сообщений или 5 секунд
* **Заблокированные**: пользователи, заблокировавшие бота, помечаются. Триальные/бесплатные подписки отключаются

### Статусы рассылки

| Статус        | Описание                          |
| ------------- | --------------------------------- |
| `queued`      | Создана через API, не запущена    |
| `in_progress` | Идёт отправка                     |
| `completed`   | Все доставлены                    |
| `partial`     | Завершена с ошибками/блокировками |
| `failed`      | Критическая ошибка                |
| `cancelled`   | Остановлена администратором       |

### Остановка рассылки

Через API: `POST /broadcasts/{id}/stop` — корректная остановка между батчами.

## Закреплённые сообщения

Специальный тип контента, отображаемый при каждом `/start`:

| Параметр              | Описание                                   |
| --------------------- | ------------------------------------------ |
| Контент               | Текст, фото или видео                      |
| `send_before_menu`    | До или после главного меню                 |
| `send_on_every_start` | При каждом `/start` или только один раз    |
| Варианты доставки     | "Разослать сейчас" или "Только при /start" |

## Топик-уведомления для администраторов

Бот отправляет события в Telegram-форум, разделяя по топикам:

### Конфигурация топиков

| Переменная                                   | Описание                          |
| -------------------------------------------- | --------------------------------- |
| `ADMIN_NOTIFICATIONS_CHAT_ID`                | ID чата (с префиксом `-100`)      |
| `ADMIN_NOTIFICATIONS_TOPIC_ID`               | Топик для общих уведомлений       |
| `ADMIN_NOTIFICATIONS_TICKET_TOPIC_ID`        | Топик для тикетов поддержки       |
| `ADMIN_NOTIFICATIONS_NALOG_TOPIC_ID`         | Топик для чеков NaloGO            |
| `SUSPICIOUS_NOTIFICATIONS_TOPIC_ID`          | Топик для подозрительного трафика |
| `REFERRAL_WITHDRAWAL_NOTIFICATIONS_TOPIC_ID` | Топик для заявок на вывод         |
| `BACKUP_SEND_TOPIC_ID`                       | Топик для бэкапов                 |
| `LOG_ROTATION_TOPIC_ID`                      | Топик для архивов логов           |

### Типы событий

| Событие               | Описание                        |
| --------------------- | ------------------------------- |
| Активация триала      | Новый триал-пользователь        |
| Покупка подписки      | Покупка / продление / конверсия |
| Продление подписки    | Расширение срока                |
| Пополнение баланса    | Новый платёж                    |
| Активация промокода   | Промокод использован            |
| Переход по кампании   | Клик по deeplink кампании       |
| Смена промо-группы    | Автоматическая или ручная       |
| Изменение подписки    | Трафик / устройства / серверы   |
| Новая версия бота     | Обнаружена в репозитории        |
| Техработы             | Включение / выключение          |
| Статус панели         | Изменение доступности RemnaWave |
| Тикеты поддержки      | Новые тикеты, ответы, SLA       |
| Подозрительный трафик | Превышение порога               |
| Заявка партнёра       | Новая заявка на партнёрство     |
| Заявка на вывод       | Запрос вывода средств           |
| Массовый бан          | Операция массовой блокировки    |

### События от RemnaWave (вебхуки)

Если `REMNAWAVE_WEBHOOK_ENABLED=true`, события от панели пересылаются в чат администраторов:

* **Ноды**: создание, изменение, включение/выключение, удаление, потеря/восстановление соединения, трафик
* **Сервис**: запуск панели, попытки входа, изменение конфигурации
* **CRM**: биллинг нод (оплата через 7 дней, 48ч, 24ч, сегодня, просрочка)

## Вебхук-уведомления пользователям

Уведомления пользователям при событиях в RemnaWave панели. Каждый тип переключается отдельно:

| Переменная                           | По умолчанию | Событие                                     |
| ------------------------------------ | ------------ | ------------------------------------------- |
| `WEBHOOK_NOTIFY_USER_ENABLED`        | `true`       | Глобальный переключатель                    |
| `WEBHOOK_NOTIFY_SUB_STATUS`          | `true`       | Подписка включена/выключена администратором |
| `WEBHOOK_NOTIFY_SUB_EXPIRED`         | `true`       | Подписка истекла                            |
| `WEBHOOK_NOTIFY_SUB_EXPIRING`        | `true`       | Истекает через 72ч / 48ч / 24ч              |
| `WEBHOOK_NOTIFY_SUB_LIMITED`         | `true`       | Достигнут лимит трафика                     |
| `WEBHOOK_NOTIFY_TRAFFIC_RESET`       | `true`       | Сброс счётчика трафика                      |
| `WEBHOOK_NOTIFY_SUB_DELETED`         | `true`       | Пользователь удалён из панели               |
| `WEBHOOK_NOTIFY_SUB_REVOKED`         | `true`       | Ключи подписки отозваны                     |
| `WEBHOOK_NOTIFY_FIRST_CONNECTED`     | `true`       | Первое VPN-подключение                      |
| `WEBHOOK_NOTIFY_NOT_CONNECTED`       | `true`       | Напоминание о неподключении                 |
| `WEBHOOK_NOTIFY_BANDWIDTH_THRESHOLD` | `true`       | Приближение к лимиту трафика                |
| `WEBHOOK_NOTIFY_DEVICES`             | `true`       | Устройство добавлено/удалено                |

## Уведомления о подписке

### Предупреждения об истечении

Настройка через `AUTOPAY_WARNING_DAYS` (по умолчанию `3,1`):

* За 3 дня — первое предупреждение
* За 1 день — повторное предупреждение
* Дедупликация: если уже отправлено более срочное, менее срочное пропускается

### Триальные предупреждения

* За `TRIAL_WARNING_HOURS` часов (по умолчанию 2) до истечения триала

### Волны возврата (Recovery Waves)

Многоступенчатая система для истёкших подписок:

| Волна       | Когда                         | Описание                                         |
| ----------- | ----------------------------- | ------------------------------------------------ |
| **1 день**  | Через 1 день после истечения  | Напоминание о продлении                          |
| **Волна 2** | Через 2-3 дня                 | Скидка (по умолчанию 10%), действует 24ч         |
| **Волна 3** | Через N дней (по умолчанию 5) | Большая скидка (по умолчанию 20%), действует 24ч |

Настраивается через `NotificationSettingsService` (файл `data/notification_settings.json`).

### Автопродление

| Переменная                       | По умолчанию | Описание                             |
| -------------------------------- | ------------ | ------------------------------------ |
| `ENABLE_AUTOPAY`                 | `false`      | Включить автопродление               |
| `AUTOPAY_WARNING_DAYS`           | `3,1`        | Дни предупреждений (через запятую)   |
| `DEFAULT_AUTOPAY_ENABLED`        | `true`       | Автопродление по умолчанию для новых |
| `DEFAULT_AUTOPAY_DAYS_BEFORE`    | `3`          | За сколько дней списывать            |
| `MIN_BALANCE_FOR_AUTOPAY_KOPEKS` | `10000`      | Минимальный баланс для автопродления |

Уведомления автопродления:

* **Успех** — подписка продлена автоматически
* **Недостаточно средств** — с cooldown 6 часов между повторами
* **Ошибка** — сбой при автопродлении

## Ежедневные отчёты

```env theme={null}
ADMIN_REPORTS_ENABLED=true
ADMIN_REPORTS_CHAT_ID=           # Опционально (fallback на ADMIN_NOTIFICATIONS_CHAT_ID)
ADMIN_REPORTS_TOPIC_ID=          # ID топика для отчётов
ADMIN_REPORTS_SEND_TIME=10:00    # Время отправки (МСК)
```

## Мониторинг трафика

Система мониторинга отслеживает подозрительное потребление трафика:

### Быстрая проверка (дельта за интервал)

```env theme={null}
TRAFFIC_FAST_CHECK_ENABLED=false
TRAFFIC_FAST_CHECK_INTERVAL_MINUTES=10
TRAFFIC_FAST_CHECK_THRESHOLD_GB=5.0
```

### Суточная проверка

```env theme={null}
TRAFFIC_DAILY_CHECK_ENABLED=false
TRAFFIC_DAILY_CHECK_TIME=00:00
TRAFFIC_DAILY_THRESHOLD_GB=50.0
```

### Фильтрация

| Переменная                              | Описание                             |
| --------------------------------------- | ------------------------------------ |
| `TRAFFIC_MONITORED_NODES`               | Только эти ноды (UUID через запятую) |
| `TRAFFIC_IGNORED_NODES`                 | Исключить ноды                       |
| `TRAFFIC_EXCLUDED_USER_UUIDS`           | Исключить пользователей              |
| `TRAFFIC_NOTIFICATION_COOLDOWN_MINUTES` | Cooldown уведомлений (60 мин)        |

## Пользовательские настройки уведомлений (Cabinet)

Через Cabinet API пользователи настраивают:

| Настройка                     | По умолчанию | Описание                      |
| ----------------------------- | ------------ | ----------------------------- |
| `subscription_expiry_enabled` | `true`       | Предупреждения об истечении   |
| `subscription_expiry_days`    | `3`          | За сколько дней предупреждать |
| `traffic_warning_enabled`     | `true`       | Предупреждение о трафике      |
| `traffic_warning_percent`     | `80`         | Порог (50-99%)                |
| `balance_low_enabled`         | `true`       | Низкий баланс                 |
| `balance_low_threshold`       | `100`        | Порог (копейки)               |
| `news_enabled`                | `true`       | Новости                       |
| `promo_offers_enabled`        | `true`       | Промо-предложения             |
