Compare commits
108 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cdd1e3f107 | |||
| 6c6ade4f7f | |||
| 30ad692bc2 | |||
| 24b3ea4881 | |||
| 560689d9ee | |||
| aa763403c6 | |||
| 96c0c3562d | |||
| e48eaf584c | |||
| 790cd6bab3 | |||
| 55ae2bd91c | |||
| d431931501 | |||
| 425d15c850 | |||
| 58affda938 | |||
| c4eb2a60de | |||
| 46dca8c095 | |||
| b752278398 | |||
| 6a659a2131 | |||
| 019397b0ea | |||
| 947a400909 | |||
| 7f52beb2a2 | |||
| 283d42af86 | |||
| d36d1e3041 | |||
| a83bc25bd0 | |||
| 3555ada3b5 | |||
| 1cb93d9688 | |||
| 6f9fc5e071 | |||
| 96d466328c | |||
| 846e7844db | |||
| 4e0b0837d9 | |||
| 8ba5cda095 | |||
| 7ac33bce28 | |||
| d8a0c166ac | |||
| c1858fe925 | |||
| dae8e4c34c | |||
| 3d7c219fd1 | |||
| 03781463e4 | |||
| dcd9074136 | |||
| 7fbd26c8c3 | |||
| 9677a55375 | |||
| eb51cda617 | |||
| 09bdde6f91 | |||
| 784b2ed996 | |||
| 9bee4a2365 | |||
| f8946b99f3 | |||
| a17cbf4448 | |||
| b0422e0c0f | |||
| 9d0bf8b3cf | |||
| 8c5e8ca019 | |||
| 0327adb8da | |||
| 5769fa63a5 | |||
| 1d09006b7c | |||
| e194ab9729 | |||
| 45a6173916 | |||
| b21baba006 | |||
| 45c1b4695c | |||
| 9b2b28423d | |||
| 9d00c2ddc6 | |||
| dc66676663 | |||
| 1d600e2c63 | |||
| 5ce177a7b5 | |||
| d181a333d7 | |||
| 3694cb4ed7 | |||
| 051048e0ae | |||
| 61ee6e42cf | |||
| 5bd618a799 | |||
| 7794a4cc7b | |||
| 6d01d32dc2 | |||
| be71def203 | |||
| 7a2de410bd | |||
| b019e8b32d | |||
| cb4f773eb1 | |||
| 29fe9f4943 | |||
| 63edfa852d | |||
| 66fabb6836 | |||
| f29ea49185 | |||
| 7620a3df92 | |||
| 577bcfdc88 | |||
| 33ec09edd0 | |||
| 7b3c463fa2 | |||
| 0e541af5e1 | |||
| e39822e732 | |||
| c7973e7b58 | |||
| 4941052d57 | |||
| 0022abc6e0 | |||
| acef77b0e8 | |||
| 4ddd580347 | |||
| 42cc4db077 | |||
| 8e3f976441 | |||
| 190d9ae13e | |||
| d6deec1a29 | |||
| e8dcbd09ff | |||
| 382f1eb6f7 | |||
| 2853410ebc | |||
| 2bde6a83ed | |||
| 83b1fa0f0f | |||
| 3a2a05d307 | |||
| 2460766e30 | |||
| 3eb01eaabc | |||
| 35bca4166d | |||
| f2db938fdc | |||
| ff0c68afc6 | |||
| 67babf7566 | |||
| f71788d2d4 | |||
| 5eebdcc85c | |||
| 4b89de9634 | |||
| b81d5b199b | |||
| a21559cd0d | |||
| 6cd3f87318 |
@@ -36,15 +36,15 @@ jobs:
|
||||
TAGS="fr1ngg/remnawave-bedolaga-telegram-bot:latest,fr1ngg/remnawave-bedolaga-telegram-bot:${VERSION}"
|
||||
echo "🏷️ Собираем релизную версию: $VERSION"
|
||||
elif [[ $GITHUB_REF == refs/heads/main ]]; then
|
||||
VERSION="v2.4.6-$(git rev-parse --short HEAD)"
|
||||
VERSION="v2.4.7-$(git rev-parse --short HEAD)"
|
||||
TAGS="fr1ngg/remnawave-bedolaga-telegram-bot:latest,fr1ngg/remnawave-bedolaga-telegram-bot:${VERSION}"
|
||||
echo "🚀 Собираем версию из main: $VERSION"
|
||||
elif [[ $GITHUB_REF == refs/heads/dev ]]; then
|
||||
VERSION="v2.4.6-dev-$(git rev-parse --short HEAD)"
|
||||
VERSION="v2.4.7-dev-$(git rev-parse --short HEAD)"
|
||||
TAGS="fr1ngg/remnawave-bedolaga-telegram-bot:dev,fr1ngg/remnawave-bedolaga-telegram-bot:${VERSION}"
|
||||
echo "🧪 Собираем dev версию: $VERSION"
|
||||
else
|
||||
VERSION="v2.4.6-pr-$(git rev-parse --short HEAD)"
|
||||
VERSION="v2.4.7-pr-$(git rev-parse --short HEAD)"
|
||||
TAGS="fr1ngg/remnawave-bedolaga-telegram-bot:pr-$(git rev-parse --short HEAD)"
|
||||
echo "🔀 Собираем PR версию: $VERSION"
|
||||
fi
|
||||
|
||||
@@ -49,13 +49,13 @@ jobs:
|
||||
VERSION=${GITHUB_REF#refs/tags/}
|
||||
echo "🏷️ Building release version: $VERSION"
|
||||
elif [[ $GITHUB_REF == refs/heads/main ]]; then
|
||||
VERSION="v2.4.6-$(git rev-parse --short HEAD)"
|
||||
VERSION="v2.4.7-$(git rev-parse --short HEAD)"
|
||||
echo "🚀 Building main version: $VERSION"
|
||||
elif [[ $GITHUB_REF == refs/heads/dev ]]; then
|
||||
VERSION="v2.4.6-dev-$(git rev-parse --short HEAD)"
|
||||
VERSION="v2.4.7-dev-$(git rev-parse --short HEAD)"
|
||||
echo "🧪 Building dev version: $VERSION"
|
||||
else
|
||||
VERSION="v2.4.6-pr-$(git rev-parse --short HEAD)"
|
||||
VERSION="v2.4.7-pr-$(git rev-parse --short HEAD)"
|
||||
echo "🔀 Building PR version: $VERSION"
|
||||
fi
|
||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ RUN pip install --no-cache-dir --upgrade pip && \
|
||||
|
||||
FROM python:3.13-slim
|
||||
|
||||
ARG VERSION="v2.4.6"
|
||||
ARG VERSION="v2.4.7"
|
||||
ARG BUILD_DATE
|
||||
ARG VCS_REF
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
### ⚡ **Полная автоматизация VPN бизнеса**
|
||||
- 🎯 **Готовое решение** - разверни за 5 минут, начни продавать сегодня
|
||||
- 💰 **Многоканальные платежи** - Telegram Stars + Tribute + CryptoBot + ЮKassa + MulenPay + PayPalych + P2P
|
||||
- 💰 **Многоканальные платежи** - Telegram Stars + Tribute + CryptoBot + YooKassa + MulenPay + PayPalych (СБП)
|
||||
- 🔄 **Автоматизация 99%** - от регистрации до продления подписок
|
||||
- 📊 **Детальная аналитика** - полная картина вашего бизнеса
|
||||
- 💬 **Уведомления в топики** об: Активация триала 💎 Покупка подписки 🔄 Конверсия из триала в платную ⏰ Продление подписки 💰 Пополнение баланса 🚧 Включении тех работ ♻️ Появлении новой версии бота
|
||||
@@ -952,105 +952,111 @@ WEBHOOK_PATH=/webhook
|
||||
|
||||
### 👤 **Для пользователей**
|
||||
|
||||
🧭 **Онбординг и доступ**
|
||||
- 🌐 Выбор языка интерфейса, динамическая локализация и настройка кнопки меню.
|
||||
- 📜 Принятие правил, оферты и политики конфиденциальности прямо в боте.
|
||||
- 📡 Проверка подписки на обязательный канал, deeplink-инвайты и UTM-кампании.
|
||||
- 👤 Сбор контактных данных с антиспам-защитой и быстрым восстановлением доступа.
|
||||
|
||||
🛒 **Умная покупка подписок**
|
||||
- 📅 Гибкие периоды (14-360 дней)
|
||||
- 📊 Выбор трафика или фиксированный лимит
|
||||
- 🌍 Автоматический выбор серверов (для одного сквада) или ручной выбор из множества
|
||||
- 📱 Настройка количества устройств и серверов прямо при оформлении
|
||||
- 🧾 Понятный калькулятор стоимости с учетом всех опций
|
||||
- 📅 Гибкие периоды (14–360 дней) и скидки за длительные подписки.
|
||||
- 📊 Выбор трафика: фиксированный лимит, квоты или безлимит.
|
||||
- 🌍 Автоматический выбор сквада или мультивыбор из десятков серверов.
|
||||
- 📱 Настройка количества устройств, стран и доп. услуг прямо в чек-ауте.
|
||||
- 🧾 Динамический калькулятор стоимости, черновики и возвращение к незавершённым заказам.
|
||||
|
||||
🧪 **Тестовая подписка**
|
||||
- Настраиваемый триал-период
|
||||
- Уведомления об истечении и сценарий мягкой конверсии в платную подписку
|
||||
- Приветственное сообщение с предложением активации триала (с возможностью отключения)
|
||||
- Поддержка рекламных кампаний с автоматической выдачей бонусных подписок
|
||||
- Гибко настраиваемый триал и welcome-цепочка.
|
||||
- Уведомления об истечении и автоконверсия в платный тариф.
|
||||
- Автовыдача бонусов за участие в кампаниях и инвайт-линках.
|
||||
- Контроль за обязательной подпиской на канал даже в режиме триала.
|
||||
|
||||
💰 **Удобные платежи**
|
||||
- ⭐ Telegram Stars
|
||||
- 💳 Tribute
|
||||
- 💳 YooKassa (включая СБП и онлайн-чек)
|
||||
- 💳 MulenPay
|
||||
- 💳 PayPalych (Pal24)
|
||||
- 💰 CryptoBot (мультивалюта и срок жизни инвойсов)
|
||||
- 🎁 Реферальные и промо-бонусы
|
||||
- Детальная история транзакций и чеков
|
||||
💰 **Платежи и баланс**
|
||||
- ⭐ Telegram Stars, 💳 Tribute, 💳 YooKassa (СБП + онлайн-чек), 💳 MulenPay, 🏦 PayPalych (СБП), 💰 CryptoBot.
|
||||
- 📥 Автогенерация счетов, контроль статусов через вебхуки и уведомления.
|
||||
- 💼 История операций с фильтрами, квитанциями и выгрузкой чеков.
|
||||
- 🔄 Автоплатёж с настройкой дня списания и уведомлениями об ошибках.
|
||||
- 🎁 Реферальные, промо- и кэшбэк-бонусы автоматически начисляются на баланс.
|
||||
|
||||
📱 **Управление подписками**
|
||||
- 📈 Статистика использования в реальном времени (трафик, устройства, серверы)
|
||||
- 🔄 Автопродление с баланса с настройкой дней и мгновенными уведомлениями
|
||||
- 🔄 Управление трафиком и лимитами без участия оператора
|
||||
- 🌍 Переключение серверов Remnawave на лету
|
||||
- 📱 Управление устройствами + сброс HWID
|
||||
- 🧩 Смена языка и персональных настроек
|
||||
- 📈 Реальный трафик, устройства и география серверов прямо в диалоге.
|
||||
- 🌍 Переключение серверов, стран и лимитов без помощи оператора.
|
||||
- 📱 Сброс HWID, повторная выдача конфигов и инструкции подключения.
|
||||
- 🧩 Смена языка, промогруппы и персональных параметров.
|
||||
- 🧾 Просмотр активных услуг, статуса оплаты и сроков действия.
|
||||
|
||||
🎁 **Бонусная система**
|
||||
- 🎫 Промокоды на деньги/дни/длинный триал
|
||||
- 👥 Защищенная реферальная программа с комиссиями и антифродом
|
||||
- 📊 Детальная статистика рефералов и кампаний
|
||||
- 📨 Персональные рассылки и уведомления о новых бонусах
|
||||
🛟 **Поддержка и самообслуживание**
|
||||
- 🎫 Тикеты с приоритетами, вложениями и уведомлениями об ответе.
|
||||
- 📚 FAQ, правила, оферта и политика доступны из меню.
|
||||
- 💬 Быстрые ссылки на живую поддержку или кастомные каналы связи.
|
||||
|
||||
🧩 **Бонусы и рефералы**
|
||||
- 🎫 Промокоды на деньги, дни, устройства, страны и расширенные триалы.
|
||||
- 👥 Реферальная программа с комиссиями, бонусами и антифрод-фильтрами.
|
||||
- 🧾 Подробная аналитика доходов, конверсии и активности приглашённых.
|
||||
- 🔗 Генерация реферальных ссылок и QR-кодов в один тап.
|
||||
|
||||
🪪 **Mini App и инструкции**
|
||||
- 📱 Telegram WebApp с обзором подписки, конфигами и кнопкой «Подключить».
|
||||
- 📥 Библиотека загрузочных ссылок для клиентов Happ и кастомных гайдов.
|
||||
- 🛰️ Web API для получения статуса подписки в мини-приложениях и внешних витринах.
|
||||
|
||||
</td>
|
||||
<td width="50%" valign="top">
|
||||
|
||||
### ⚙️ **Для администраторов**
|
||||
|
||||
📊 **Мощная аналитика**
|
||||
- 👥 Детальная статистика пользователей и подписок
|
||||
- 💰 Анализ платежей по источникам (Stars, YooKassa, Tribute, MulenPay, PayPalych, CryptoBot)
|
||||
- 🖥️ Мониторинг серверов Remnawave и статуса сквадов
|
||||
- 📈 Финансовые отчеты, конверсии и эффективность рекламных кампаний
|
||||
📊 **Аналитика и отчётность**
|
||||
- 📈 Дашборды по пользователям, подпискам, трафику и удержанию.
|
||||
- 💰 Детализация платежей по источникам (Stars, YooKassa, Tribute, MulenPay, PayPalych, CryptoBot).
|
||||
- 🧮 Продажи по тарифам, устройствам, странам и промогруппам.
|
||||
- 📣 Эффективность кампаний, промокодов, UTM-источников и реферальных потоков.
|
||||
|
||||
👥 **Управление пользователями**
|
||||
- 🔍 Поиск и редактирование профилей
|
||||
- 💰 Управление балансами и ручные начисления
|
||||
- 📱 Изменение лимита устройств (1-X)
|
||||
- 📊 Настройка лимитов трафика (0-10000 ГБ) и подключенных сквадов
|
||||
- 🌍 Мультивыбор серверов и мгновенная синхронизация с панелью
|
||||
- 🔄 Сброс HWID устройств и обновление конфигураций
|
||||
- 👥 Детальная реферальная статистика в профиле пользователя
|
||||
- 🔄 Изменение типа подписки триал/платная и ручное продление
|
||||
- 🚫 Блокировка/разблокировка/удаление аккаунтов
|
||||
- 🔍 Поиск, фильтры и детальные карточки с историей операций.
|
||||
- 💰 Ручное изменение баланса, компенсации и корректировки.
|
||||
- 📱 Изменение лимитов устройств, трафика, стран и подключенных сквадов.
|
||||
- 🔄 Сброс HWID, перегенерация подписки и синхронизация с Remnawave.
|
||||
- 🎯 Назначение промогрупп, тарифов и ручных продлений/обновлений.
|
||||
- 🚫 Блокировки с таймером, полное удаление и аудит действий персонала.
|
||||
|
||||
🎯 **Маркетинг и продажи**
|
||||
- 🎫 Гибкая промо-система (деньги/дни/длинный триал)
|
||||
- 📣 Рекламные кампании с автоматическими бонусами за регистрацию
|
||||
- 📊 Детальная статистика использования промокодов и кампаний
|
||||
- 📨 Рассылки по сегментам с фильтрами по активности, подпискам и языкам
|
||||
🎯 **Продажи, маркетинг и удержание**
|
||||
- 🎫 Промокоды (разовые/многоразовые), бонусные предложения и бесплатные пакеты.
|
||||
- 💳 Промогруппы со скидками на серверы, трафик, устройства и допуслуги.
|
||||
- 📣 Кампании с deeplink-ссылками, UTM и автопродвижением триалов.
|
||||
- 📨 Рассылки по сегментам, кастомные кнопки и медиа, отмена «в полёте».
|
||||
- 🔘 Настройка кнопок главного меню, приветственных экранов и мини-приложений.
|
||||
|
||||
🖥️ **Умный мониторинг**
|
||||
- 💚 Контроль доступности Remnawave панели в реальном времени
|
||||
- 🔄 Автоматическая синхронизация данных и реконнект при ошибках
|
||||
- 🌐 Управление сквадами с актуальным статусом и массовыми действиями
|
||||
- 🚧 Автоматический режим тех. работ с уведомлениями пользователей
|
||||
- 📋 Логи и диагностика, включая журнал сбоев и действий бота
|
||||
- 📦 Проверка обновлений проекта и уведомления о новых релизах
|
||||
🛟 **Поддержка и модерация**
|
||||
- 🎫 Центр тикетов с приоритетами, статусами и перепиской.
|
||||
- 🧑⚖️ Разграничение ролей (админы, модераторы), журнал аудита действий.
|
||||
- ⏱️ SLA таймеры, автоматические напоминания и уведомления в канал.
|
||||
- 🚫 Массовые блокировки нарушителей и автоматическое снятие блокировок.
|
||||
- 🧾 История диалогов, прикреплённые файлы и быстрые ответы.
|
||||
|
||||
📨 **Коммуникации и поддержка**
|
||||
- 📢 Рассылки по сегментам и мгновенные оповещения
|
||||
- 🔔 Автоуведомления о продлении, задолженностях и автоплатежах
|
||||
- 💬 Система поддержки с HTML разметкой и история обращений
|
||||
- 📝 Настройка правил сервиса, FAQ и приветственных экранов
|
||||
- 🧪 Настраиваемое приветственное сообщение с предложением активации триала
|
||||
🔔 **Уведомления и коммуникации**
|
||||
- 📢 Топики для событий (покупки, триалы, техработы, ошибки интеграций).
|
||||
- 🔔 Настройка пользовательских и админских уведомлений, расписаний и каналов.
|
||||
- 📨 Шаблоны правил, оферты, FAQ, приветствий и страницы поддержки.
|
||||
- 💬 Автоматические сообщения о задолженностях, автоплатежах и продлениях.
|
||||
|
||||
📨 **Уведомления в закрытый канал**
|
||||
- 🎯 Активация триала, продления и конверсии в платную подписку
|
||||
- 💎 Покупка подписки и пополнение баланса
|
||||
- 🔄 Изменения параметров подписки пользователем
|
||||
- 🚧 Потеря соединения с Remnawave и включение техработ
|
||||
- 🗄️ Авто- и ручные бекапы/восстановления с отправкой файлов
|
||||
- ♻️ Выхлоп новых версий бота и результаты автоплатежей
|
||||
🧰 **Обслуживание и DevOps**
|
||||
- 🛠️ `install_bot.sh`: управление контейнерами, логами, обновлениями, прокси и резервными копиями.
|
||||
- 🚧 Ручной и авто-режим техработ с кастомными сообщениями.
|
||||
- 🗒️ Просмотр системных логов, health-check, мониторинг Remnawave и серверов.
|
||||
- ♻️ Проверка обновлений репозитория, уведомления о новых версиях и плавный деплой.
|
||||
|
||||
🗄️ **Бекапы и восстановление**
|
||||
- Ручной запуск бекапа с выбором содержимого (включая логи)
|
||||
- Автоматические бекапы по расписанию и управление retention-политикой
|
||||
- Восстановление из бекапа без остановки сервиса
|
||||
- Отправка копии бекапа в выделенный чат/топик и ведение метаданных
|
||||
- 🗓️ Планировщик авто-бекапов, гибкая политика хранения и компрессия.
|
||||
- 📦 Ручные бекапы с выбором содержимого (БД, конфиги, логи).
|
||||
- 📤 Отправка архивов в выделенный чат/топик, журнал попыток и статусов.
|
||||
- 🔁 Восстановление из бекапа без остановки бота, проверка целостности.
|
||||
|
||||
💳 **Автоплатежи и биллинг**
|
||||
- Настройки автоплатежа на уровне пользователя (вкл/выкл, дни до списания)
|
||||
- Принудительная проверка готовности автосписаний
|
||||
- Уведомления об успешных и неудачных автоплатежах с подсказками действий
|
||||
- Настройка минимального баланса и логирование всех списаний
|
||||
💳 **Биллинг и автоплатежи**
|
||||
- ⚙️ Глобальные настройки автосписаний, минимального баланса и напоминаний.
|
||||
- 🧪 Тестовые платежи для каждого провайдера прямо из админки.
|
||||
- 🪝 Управление вебхуками Tribute, YooKassa, CryptoBot, MulenPay и PayPalych.
|
||||
- 🧾 Экспорт транзакций, сверка с платёжками и интеграция с бухгалтерией.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
@@ -1065,6 +1071,16 @@ WEBHOOK_PATH=/webhook
|
||||
- 📦 **Интеграция с Remnawave API** — автоматическое создание пользователей, управление сквадами и синхронизация подписок.
|
||||
- 🧾 **История операций** — хранение транзакций, уведомлений, рассылок, кампаний и бекапов для аудита.
|
||||
|
||||
### 🌐 Веб-API, мини-приложение и интеграции
|
||||
|
||||
- ⚙️ **FastAPI Web API** (`app/webapi`) с эндпоинтами для управления токенами, конфигурациями, рассылками, кампаниями, промогруппами, статистикой, подписками, транзакциями, тикетами и бекапами.
|
||||
- 🔑 **Управление API-ключами** — выпуск, отзыв, реактивация и аудит токенов прямо из админки.
|
||||
- 🛡️ **Гибкая авторизация** — API-key, Bearer, Basic Auth и cookie eGames для совместимости с внешними панелями.
|
||||
- 🛰️ **Mini App** — статический фронтенд в `miniapp/` и proxied эндпоинты `/miniapp/*` для отображения статуса подписки внутри Telegram.
|
||||
- 🧭 **App Config** — централизованная раздача ссылок на клиенты и инструкции (`app-config.json`, `miniapp/app-config.json`).
|
||||
- 🪝 **Платёжные вебхуки** — встроенные Flask-серверы для Tribute, YooKassa, CryptoBot, MulenPay и PayPalych (Pal24) с health-check и логированием.
|
||||
- 📡 **Мониторинг серверов** — REST-эндпоинты для просмотра нод Remnawave, статистики нагрузки и управления сквадами из внешних систем.
|
||||
|
||||
### 🧭 Навигация по проекту
|
||||
|
||||
- `app/bot.py` — точка входа бота и регистрация middlewares/handlers.
|
||||
@@ -1350,121 +1366,6 @@ ADMIN_NOTIFICATIONS_TOPIC_ID=123 # ID топика (опционал
|
||||
- **🔗 SQLAlchemy ORM** - безопасная работа с БД
|
||||
- **🚀 aiogram 3** - современная Telegram Bot API
|
||||
|
||||
### 📁 Структура проекта
|
||||
|
||||
```
|
||||
bedolaga_bot/
|
||||
├── 🎯 main.py # Точка входа
|
||||
├── 📦 requirements.txt # Зависимости
|
||||
├── ⚙️ .env.example # Конфиг
|
||||
├── ⚙️ app-config.json # Информация для гайда подключения
|
||||
│
|
||||
├── 📱 app/
|
||||
│ ├── 🤖 bot.py # Инициализация бота
|
||||
│ ├── ⚙️ config.py # Настройки
|
||||
│ ├── 🎛️ states.py # FSM состояния
|
||||
│ │
|
||||
│ ├── 🎮 handlers/ # Обработчики событий
|
||||
│ │ ├── 🏠 start.py # Регистрация и старт
|
||||
│ │ ├── 🛒 subscription.py # Подписки
|
||||
│ │ ├── 💰 balance.py # Баланс и платежи
|
||||
│ │ ├── 🎁 promocode.py # Промокоды
|
||||
│ │ ├── 👥 referral.py # Реферальная система
|
||||
│ │ ├── 🌟 stars_payment.py # Start платежи
|
||||
│ │ ├── common.py
|
||||
│ │ ├── 💬 support.py # Техподдержка
|
||||
│ │ └── 👑 admin/ # Админ панель
|
||||
│ │ ├── 📊 statistics.py # Статистика
|
||||
│ │ ├── 🗄️ backup.py # Бекапы
|
||||
│ │ ├── 👥 users.py # Управление юзерами
|
||||
│ │ ├── 🎫 promocodes.py # Управление промокодами
|
||||
│ │ ├── 🚧 maintenance.py # Тех работы
|
||||
│ │ ├── 📨 messages.py # Рассылки
|
||||
│ │ ├── 📨 user_messages.py # Рандомные сообщения в меню
|
||||
│ │ ├── 📨 welcome_text.py # Приветственное сообщение
|
||||
│ │ ├── ⚙️ main.py # Админское меню
|
||||
│ │ ├── 📖 rules.py # Правила
|
||||
│ │ ├── 🙋 referrals.py # Правила
|
||||
│ │ ├── 🌎 servers.py # Сервера
|
||||
│ │ ├── 📱 subscriptions.py # Подписки
|
||||
│ │ ├── 🔍 monitoring.py # Мониторинг
|
||||
│ │ └── 🔗 remnawave.py # Система Remnawave
|
||||
│ │
|
||||
│ ├── 🗄️ database/ # База данных
|
||||
│ │ ├── 📊 models.py # Модели SQLAlchemy
|
||||
│ │ ├── 🔗 database.py # Подключение к БД
|
||||
│ │ ├── 🔄 universal_migration.py # Миграции
|
||||
│ │ └── 📝 crud/ # CRUD операции
|
||||
│ │ ├── 👤 user.py # Операции с пользователями
|
||||
│ │ ├── 📋 subscription.py # Операции с подписками
|
||||
│ │ ├── 💰 transaction.py # Операции с транзакциями
|
||||
│ │ ├── 📜 rules.py # Правила сервиса
|
||||
│ │ ├── 📜 subscription_conversion.py # Правила сервиса
|
||||
│ │ ├── 💳 yookassa.py # YooKassa операции
|
||||
│ │ ├── 📨 welcome_text.py # Приветственное сообщение
|
||||
│ │ ├── 💳 cryptobot.py # CryptoBot операции
|
||||
│ │ ├── 🌐 server_squad.py # Серверы и сквады
|
||||
│ │ ├── 🎁 promocode.py # Промокоды
|
||||
│ │ └── 👥 referral.py # Партнерка
|
||||
│ │
|
||||
│ ├── 🔧 services/ # Бизнес-логика
|
||||
│ │ ├── 👤 user_service.py # Сервис пользователей
|
||||
│ │ ├── 📋 subscription_service.py # Сервис подписок
|
||||
│ │ ├── 💰 payment_service.py # Платежи
|
||||
│ │ ├── 🗄️ backup_service.py # Бекапы
|
||||
│ │ ├── 🎁 promocode_service.py # Промокоды
|
||||
│ │ ├── 🚧 maintenance_service.py # Промокоды
|
||||
│ │ ├── 👥 referral_service.py # Партнерка
|
||||
│ │ ├── 💬 admin_notification_service.py # Уведомления для администраторов в чаты
|
||||
│ │ ├── 🔍 monitoring_service.py # Мониторинг
|
||||
│ │ ├── ♻️ version_service.py # Проверка версий бота
|
||||
│ │ ├── 🎖️ tribute_service.py # Tribute платежи
|
||||
│ │ ├── 💳 yookassa_service.py # YooKassa платежи
|
||||
│ │ └── 🌐 remnawave_service.py # Интеграция с Remnawave
|
||||
│ │
|
||||
│ ├── 🛠️ utils/ # Утилиты
|
||||
│ │ ├── 🎨 decorators.py # Декораторы
|
||||
│ │ ├── 📝 formatters.py # Форматирование данных
|
||||
│ │ ├── ✅ validators.py # Валидация
|
||||
│ │ ├── ✅ subscription_utils.py # Проверка подписок
|
||||
│ │ ├── 📄 pagination.py # Пагинация
|
||||
│ │ ├── 📄 pricing_utils.py # Цены
|
||||
│ │ ├── 📄 message_patch.py
|
||||
│ │ ├── 📄 photo_message.py
|
||||
│ │ ├── ‼️ global_error.py # Обработка ошибок
|
||||
│ │ ├── 👤 user_utils.py # Утилиты для пользователей
|
||||
│ │ ├── 🫰 currency_converter.py # Курсы для CryptoBota
|
||||
│ │ └── ⚡ cache.py # Кеширование
|
||||
│ │
|
||||
│ ├── 🛡️ middlewares/ # Middleware
|
||||
│ │ ├── 🔐 auth.py # Авторизация
|
||||
│ │ ├── 📋 logging.py # Логирование
|
||||
│ │ ├── 🚧 maintenance.py # тех работы
|
||||
│ │ ├── 🔐 subscription_checker.py # тех работы
|
||||
│ │ ├── 🔐 channel_checker.py
|
||||
│ │ └── ⏱️ throttling.py # Ограничение запросов
|
||||
│ │
|
||||
│ ├── 🌐 localization/ # Локализация
|
||||
│ │ ├── 📝 texts.py # Тексты интерфейса
|
||||
│ │ └── 🗣️ languages/
|
||||
│ │
|
||||
│ ├── ⌨️ keyboards/ # Клавиатуры
|
||||
│ │ ├── 🔗 inline.py # Inline клавиатуры
|
||||
│ │ ├── 💬 reply.py # Reply клавиатуры
|
||||
│ │ └── 👑 admin.py # Админские клавиатуры
|
||||
│ │
|
||||
│ └── 🔌 external/ # Внешние API
|
||||
│ ├── 🌐 remnawave_api.py # Remnawave API
|
||||
│ ├── ⭐ telegram_stars.py # Telegram Stars
|
||||
│ ├── 💳 yookassa_webhook.py # YooKassa webhook
|
||||
│ ├── 🌐 webhook_server.py # Webhook сервер
|
||||
│ ├── 💳 cryptobot.py # CryptoBot Api
|
||||
│ └── 🎖️ tribute.py # Tribute платежи
|
||||
│
|
||||
├── 🔄 migrations/ # Миграции БД
|
||||
└── 📋 logs/ # Логи системы
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Устранение неполадок
|
||||
@@ -1708,62 +1609,146 @@ REMNAWAVE_SECRET_KEY=XXXXXXX:DDDDDDDD
|
||||
|
||||
<tr>
|
||||
<td>🥇</td>
|
||||
<td><strong>@SmartSystemCompany</strong></td>
|
||||
<td>₽8,500</td>
|
||||
<td>За щедрую поддержку и вклад в развитие</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>🥈</td>
|
||||
<td><strong>@pilot_737800</strong></td>
|
||||
<td>₽4,750</td>
|
||||
<td>₽7,750</td>
|
||||
<td>За веру в проект с самого начала</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>🥈</td>
|
||||
<td><strong>@Legacyyy777</strong></td>
|
||||
<td>₽2,600</td>
|
||||
<td>За ценные предложения по улучшению</td>
|
||||
<td><strong>@psych0O</strong></td>
|
||||
<td>$60</td>
|
||||
<td>За щедрую поддержку и вклад в развитие</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>🥉</td>
|
||||
<td><strong>Илья (@ispanec_nn)</strong></td>
|
||||
<td>$30</td>
|
||||
<td>За активное тестирование и фидбек</td>
|
||||
<td><strong>@Vldmrmtn</strong></td>
|
||||
<td>₽5,000</td>
|
||||
<td>За значительную поддержку проекта</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>4</td>
|
||||
<td><strong>@k0tbtc</strong></td>
|
||||
<td>₽3,000</td>
|
||||
<td>За поддержку и доверие</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>5</td>
|
||||
<td><strong>@Legacyyy777</strong></td>
|
||||
<td>₽2,900</td>
|
||||
<td>За ценные предложения по улучшению</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>6</td>
|
||||
<td><strong>@sklvg</strong></td>
|
||||
<td>₽3,000</td>
|
||||
<td>За международную поддержку</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>7</td>
|
||||
<td><strong>@bolgov0zero</strong></td>
|
||||
<td>₽2,000</td>
|
||||
<td>За поддержку и доверие</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>8</td>
|
||||
<td><strong>@i_burjuy</strong></td>
|
||||
<td>₽1,300</td>
|
||||
<td>За активное участие в проекте</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>9</td>
|
||||
<td><strong>@kr33njee</strong></td>
|
||||
<td>₽1,550</td>
|
||||
<td>За поддержку и доверие</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>10</td>
|
||||
<td><strong>@Nav1_0</strong></td>
|
||||
<td>₽2,000</td>
|
||||
<td>За поддержку и доверие</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>11</td>
|
||||
<td><strong>@vitos_7771997</strong></td>
|
||||
<td>₽1,500</td>
|
||||
<td>За поддержку и доверие</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>12</td>
|
||||
<td><strong>@haxonate</strong></td>
|
||||
<td>₽1,500</td>
|
||||
<td>За поддержку и доверие</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>13</td>
|
||||
<td><strong>@fso404</strong></td>
|
||||
<td>₽1,000</td>
|
||||
<td>За поддержку и доверие</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>5</td>
|
||||
<td>14</td>
|
||||
<td><strong>@edward_forix</strong></td>
|
||||
<td>₽1,000</td>
|
||||
<td>За поддержку и доверие</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>5</td>
|
||||
<td><strong>@Nav1_0</strong></td>
|
||||
<td>₽1,000</td>
|
||||
<td>За поддержку и доверие</td>
|
||||
<td>15</td>
|
||||
<td><strong>@Илья (@ispanec_nn)</strong></td>
|
||||
<td>$30</td>
|
||||
<td>За активное тестирование и фидбек</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>6</td>
|
||||
<td><strong>@kr33njee</strong></td>
|
||||
<td>₽800</td>
|
||||
<td>За поддержку и доверие</td>
|
||||
<td>16</td>
|
||||
<td><strong>@DonMatteoRU</strong></td>
|
||||
<td>₽500</td>
|
||||
<td>За участие в развитии</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>7</td>
|
||||
<td><strong>@SmartSystemCompany</strong></td>
|
||||
<td>₽600</td>
|
||||
<td>За поддержку и доверие</td>
|
||||
<td>17</td>
|
||||
<td><strong>@pedzeo</strong></td>
|
||||
<td>₽500</td>
|
||||
<td>За участие в развитии</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>8</td>
|
||||
<td>18</td>
|
||||
<td><strong>@suzumuj</strong></td>
|
||||
<td>₽400</td>
|
||||
<td>За участие в развитии</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>19</td>
|
||||
<td><strong>@andrey_93rus</strong></td>
|
||||
<td>₽300</td>
|
||||
<td>За участие в развитии</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>20</td>
|
||||
<td><strong>@PhiLin58</strong></td>
|
||||
<td>₽300</td>
|
||||
<td>За участие в развитии</td>
|
||||
|
||||
+39
-3
@@ -13,8 +13,9 @@ from pathlib import Path
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
|
||||
|
||||
BOT_TOKEN: str
|
||||
BOT_USERNAME: Optional[str] = None
|
||||
ADMIN_IDS: str = ""
|
||||
SUPPORT_USERNAME: str = "@support"
|
||||
SUPPORT_MENU_ENABLED: bool = True
|
||||
@@ -527,7 +528,14 @@ class Settings(BaseSettings):
|
||||
|
||||
def get_trial_warning_hours(self) -> int:
|
||||
return self.TRIAL_WARNING_HOURS
|
||||
|
||||
|
||||
def get_bot_username(self) -> Optional[str]:
|
||||
username = getattr(self, "BOT_USERNAME", None)
|
||||
if not username:
|
||||
return None
|
||||
normalized = str(username).strip().lstrip("@")
|
||||
return normalized or None
|
||||
|
||||
def is_notifications_enabled(self) -> bool:
|
||||
return self.ENABLE_NOTIFICATIONS
|
||||
|
||||
@@ -837,14 +845,42 @@ class Settings(BaseSettings):
|
||||
return (self.BACKUP_SEND_ENABLED and
|
||||
self.get_backup_send_chat_id() is not None)
|
||||
|
||||
def get_referred_user_reward_kopeks(self) -> int:
|
||||
"""Return the referred user reward normalized to kopeks.
|
||||
|
||||
Historically the value was stored in kopeks, however some
|
||||
installations provide it in rubles. To keep backward compatibility we
|
||||
treat any value greater than or equal to one thousand as already being
|
||||
in kopeks (≥ 10 ₽). Smaller positive values are assumed to be provided
|
||||
in rubles and therefore converted to kopeks.
|
||||
"""
|
||||
|
||||
raw_value = getattr(self, "REFERRED_USER_REWARD", 0)
|
||||
|
||||
try:
|
||||
value = int(raw_value)
|
||||
except (TypeError, ValueError):
|
||||
return 0
|
||||
|
||||
if value <= 0:
|
||||
return 0
|
||||
|
||||
if value >= 1000:
|
||||
return value
|
||||
|
||||
return value * 100
|
||||
|
||||
def get_referral_settings(self) -> Dict:
|
||||
referred_reward_kopeks = self.get_referred_user_reward_kopeks()
|
||||
|
||||
return {
|
||||
"minimum_topup_kopeks": self.REFERRAL_MINIMUM_TOPUP_KOPEKS,
|
||||
"first_topup_bonus_kopeks": self.REFERRAL_FIRST_TOPUP_BONUS_KOPEKS,
|
||||
"inviter_bonus_kopeks": self.REFERRAL_INVITER_BONUS_KOPEKS,
|
||||
"commission_percent": self.REFERRAL_COMMISSION_PERCENT,
|
||||
"notifications_enabled": self.REFERRAL_NOTIFICATIONS_ENABLED,
|
||||
"referred_user_reward": self.REFERRED_USER_REWARD
|
||||
"referred_user_reward": referred_reward_kopeks,
|
||||
"referred_user_reward_kopeks": referred_reward_kopeks,
|
||||
}
|
||||
|
||||
def is_referral_notifications_enabled(self) -> bool:
|
||||
|
||||
@@ -110,6 +110,31 @@ async def list_discount_offers(
|
||||
return result.scalars().all()
|
||||
|
||||
|
||||
async def list_active_discount_offers_for_user(
|
||||
db: AsyncSession,
|
||||
user_id: int,
|
||||
) -> List[DiscountOffer]:
|
||||
"""Return active (not yet claimed) offers for a user."""
|
||||
|
||||
now = datetime.utcnow()
|
||||
stmt = (
|
||||
select(DiscountOffer)
|
||||
.options(
|
||||
selectinload(DiscountOffer.user),
|
||||
selectinload(DiscountOffer.subscription),
|
||||
)
|
||||
.where(
|
||||
DiscountOffer.user_id == user_id,
|
||||
DiscountOffer.is_active == True, # noqa: E712
|
||||
DiscountOffer.expires_at > now,
|
||||
)
|
||||
.order_by(DiscountOffer.expires_at.asc())
|
||||
)
|
||||
|
||||
result = await db.execute(stmt)
|
||||
return result.scalars().all()
|
||||
|
||||
|
||||
async def count_discount_offers(
|
||||
db: AsyncSession,
|
||||
*,
|
||||
|
||||
@@ -279,7 +279,7 @@ def _get_group_status(group_key: str) -> Tuple[str, str]:
|
||||
settings.REFERRAL_COMMISSION_PERCENT
|
||||
or settings.REFERRAL_FIRST_TOPUP_BONUS_KOPEKS
|
||||
or settings.REFERRAL_INVITER_BONUS_KOPEKS
|
||||
or settings.REFERRED_USER_REWARD
|
||||
or settings.get_referred_user_reward_kopeks()
|
||||
)
|
||||
return ("🟢", "Программа активна") if active else ("⚪", "Бонусы не заданы")
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ async def show_referral_statistics(
|
||||
- Минимальное пополнение: {settings.format_price(settings.REFERRAL_MINIMUM_TOPUP_KOPEKS)}
|
||||
- Бонус за первое пополнение: {settings.format_price(settings.REFERRAL_FIRST_TOPUP_BONUS_KOPEKS)}
|
||||
- Бонус пригласившему: {settings.format_price(settings.REFERRAL_INVITER_BONUS_KOPEKS)}
|
||||
- Бонус новому пользователю: {settings.format_price(settings.REFERRED_USER_REWARD)}
|
||||
- Бонус новому пользователю: {settings.format_price(settings.get_referred_user_reward_kopeks())}
|
||||
- Комиссия с покупок: {settings.REFERRAL_COMMISSION_PERCENT}%
|
||||
- Уведомления: {'✅ Включены' if settings.REFERRAL_NOTIFICATIONS_ENABLED else '❌ Отключены'}
|
||||
|
||||
@@ -105,7 +105,7 @@ async def show_referral_statistics(
|
||||
- Минимальное пополнение: {settings.format_price(settings.REFERRAL_MINIMUM_TOPUP_KOPEKS)}
|
||||
- Бонус за первое пополнение: {settings.format_price(settings.REFERRAL_FIRST_TOPUP_BONUS_KOPEKS)}
|
||||
- Бонус пригласившему: {settings.format_price(settings.REFERRAL_INVITER_BONUS_KOPEKS)}
|
||||
- Бонус новому пользователю: {settings.format_price(settings.REFERRED_USER_REWARD)}
|
||||
- Бонус новому пользователю: {settings.format_price(settings.get_referred_user_reward_kopeks())}
|
||||
- Комиссия с покупок: {settings.REFERRAL_COMMISSION_PERCENT}%
|
||||
|
||||
<i>🕐 Время: {current_time}</i>
|
||||
@@ -190,7 +190,7 @@ async def show_referral_settings(
|
||||
• Минимальная сумма пополнения для участия: {settings.format_price(settings.REFERRAL_MINIMUM_TOPUP_KOPEKS)}
|
||||
• Бонус за первое пополнение реферала: {settings.format_price(settings.REFERRAL_FIRST_TOPUP_BONUS_KOPEKS)}
|
||||
• Бонус пригласившему за первое пополнение: {settings.format_price(settings.REFERRAL_INVITER_BONUS_KOPEKS)}
|
||||
• Бонус новому пользователю при регистрации: {settings.format_price(settings.REFERRED_USER_REWARD)}
|
||||
• Бонус новому пользователю при регистрации: {settings.format_price(settings.get_referred_user_reward_kopeks())}
|
||||
|
||||
<b>Комиссионные:</b>
|
||||
• Процент с каждой покупки реферала: {settings.REFERRAL_COMMISSION_PERCENT}%
|
||||
|
||||
+1193
-4
File diff suppressed because it is too large
Load Diff
@@ -34,11 +34,34 @@ class MiniAppSubscriptionUser(BaseModel):
|
||||
traffic_limit_label: str
|
||||
lifetime_used_traffic_gb: float = 0.0
|
||||
has_active_subscription: bool = False
|
||||
promo_offer_discount_percent: int = 0
|
||||
promo_offer_discount_expires_at: Optional[datetime] = None
|
||||
promo_offer_discount_source: Optional[str] = None
|
||||
|
||||
|
||||
class MiniAppPromoGroup(BaseModel):
|
||||
id: int
|
||||
name: str
|
||||
server_discount_percent: int = 0
|
||||
traffic_discount_percent: int = 0
|
||||
device_discount_percent: int = 0
|
||||
period_discounts: Dict[int, int] = Field(default_factory=dict)
|
||||
apply_discounts_to_addons: bool = True
|
||||
|
||||
|
||||
class MiniAppAutoPromoGroupLevel(BaseModel):
|
||||
id: int
|
||||
name: str
|
||||
threshold_kopeks: int
|
||||
threshold_rubles: float
|
||||
threshold_label: str
|
||||
is_reached: bool = False
|
||||
is_current: bool = False
|
||||
server_discount_percent: int = 0
|
||||
traffic_discount_percent: int = 0
|
||||
device_discount_percent: int = 0
|
||||
period_discounts: Dict[int, int] = Field(default_factory=dict)
|
||||
apply_discounts_to_addons: bool = True
|
||||
|
||||
|
||||
class MiniAppConnectedServer(BaseModel):
|
||||
@@ -47,6 +70,7 @@ class MiniAppConnectedServer(BaseModel):
|
||||
|
||||
|
||||
class MiniAppDevice(BaseModel):
|
||||
hwid: Optional[str] = None
|
||||
platform: Optional[str] = None
|
||||
device_model: Optional[str] = None
|
||||
app_version: Optional[str] = None
|
||||
@@ -54,6 +78,16 @@ class MiniAppDevice(BaseModel):
|
||||
last_ip: Optional[str] = None
|
||||
|
||||
|
||||
class MiniAppDeviceRemovalRequest(BaseModel):
|
||||
init_data: str = Field(..., alias="initData")
|
||||
hwid: str
|
||||
|
||||
|
||||
class MiniAppDeviceRemovalResponse(BaseModel):
|
||||
success: bool = True
|
||||
message: Optional[str] = None
|
||||
|
||||
|
||||
class MiniAppTransaction(BaseModel):
|
||||
id: int
|
||||
type: str
|
||||
@@ -67,6 +101,158 @@ class MiniAppTransaction(BaseModel):
|
||||
completed_at: Optional[datetime] = None
|
||||
|
||||
|
||||
class MiniAppPromoOffer(BaseModel):
|
||||
id: int
|
||||
status: str
|
||||
notification_type: Optional[str] = None
|
||||
offer_type: Optional[str] = None
|
||||
effect_type: Optional[str] = None
|
||||
discount_percent: int = 0
|
||||
bonus_amount_kopeks: int = 0
|
||||
bonus_amount_label: Optional[str] = None
|
||||
expires_at: Optional[datetime] = None
|
||||
claimed_at: Optional[datetime] = None
|
||||
is_active: bool = False
|
||||
template_id: Optional[int] = None
|
||||
template_name: Optional[str] = None
|
||||
button_text: Optional[str] = None
|
||||
title: Optional[str] = None
|
||||
message_text: Optional[str] = None
|
||||
icon: Optional[str] = None
|
||||
test_squads: List[MiniAppConnectedServer] = Field(default_factory=list)
|
||||
active_discount_expires_at: Optional[datetime] = None
|
||||
active_discount_started_at: Optional[datetime] = None
|
||||
active_discount_duration_seconds: Optional[int] = None
|
||||
|
||||
|
||||
class MiniAppPromoOfferClaimRequest(BaseModel):
|
||||
init_data: str = Field(..., alias="initData")
|
||||
|
||||
|
||||
class MiniAppPromoOfferClaimResponse(BaseModel):
|
||||
success: bool = True
|
||||
code: Optional[str] = None
|
||||
|
||||
|
||||
class MiniAppPromoCode(BaseModel):
|
||||
code: str
|
||||
type: Optional[str] = None
|
||||
balance_bonus_kopeks: int = 0
|
||||
subscription_days: int = 0
|
||||
max_uses: Optional[int] = None
|
||||
current_uses: Optional[int] = None
|
||||
valid_until: Optional[datetime] = None
|
||||
|
||||
|
||||
class MiniAppPromoCodeActivationRequest(BaseModel):
|
||||
init_data: str = Field(..., alias="initData")
|
||||
code: str
|
||||
|
||||
|
||||
class MiniAppPromoCodeActivationResponse(BaseModel):
|
||||
success: bool = True
|
||||
description: Optional[str] = None
|
||||
promocode: Optional[MiniAppPromoCode] = None
|
||||
|
||||
|
||||
class MiniAppFaqItem(BaseModel):
|
||||
id: int
|
||||
title: Optional[str] = None
|
||||
content: Optional[str] = None
|
||||
display_order: Optional[int] = None
|
||||
|
||||
|
||||
class MiniAppFaq(BaseModel):
|
||||
requested_language: str
|
||||
language: str
|
||||
is_enabled: bool = True
|
||||
total: int = 0
|
||||
items: List[MiniAppFaqItem] = Field(default_factory=list)
|
||||
|
||||
|
||||
class MiniAppRichTextDocument(BaseModel):
|
||||
requested_language: str
|
||||
language: str
|
||||
title: Optional[str] = None
|
||||
is_enabled: bool = True
|
||||
content: str = ""
|
||||
created_at: Optional[datetime] = None
|
||||
updated_at: Optional[datetime] = None
|
||||
|
||||
|
||||
class MiniAppLegalDocuments(BaseModel):
|
||||
public_offer: Optional[MiniAppRichTextDocument] = None
|
||||
service_rules: Optional[MiniAppRichTextDocument] = None
|
||||
privacy_policy: Optional[MiniAppRichTextDocument] = None
|
||||
|
||||
|
||||
class MiniAppReferralTerms(BaseModel):
|
||||
minimum_topup_kopeks: int = 0
|
||||
minimum_topup_label: Optional[str] = None
|
||||
first_topup_bonus_kopeks: int = 0
|
||||
first_topup_bonus_label: Optional[str] = None
|
||||
inviter_bonus_kopeks: int = 0
|
||||
inviter_bonus_label: Optional[str] = None
|
||||
commission_percent: float = 0.0
|
||||
referred_user_reward_kopeks: int = 0
|
||||
referred_user_reward_label: Optional[str] = None
|
||||
|
||||
|
||||
class MiniAppReferralStats(BaseModel):
|
||||
invited_count: int = 0
|
||||
paid_referrals_count: int = 0
|
||||
active_referrals_count: int = 0
|
||||
total_earned_kopeks: int = 0
|
||||
total_earned_label: Optional[str] = None
|
||||
month_earned_kopeks: int = 0
|
||||
month_earned_label: Optional[str] = None
|
||||
conversion_rate: float = 0.0
|
||||
|
||||
|
||||
class MiniAppReferralRecentEarning(BaseModel):
|
||||
amount_kopeks: int = 0
|
||||
amount_label: Optional[str] = None
|
||||
reason: Optional[str] = None
|
||||
referral_name: Optional[str] = None
|
||||
created_at: Optional[datetime] = None
|
||||
|
||||
|
||||
class MiniAppReferralItem(BaseModel):
|
||||
id: int
|
||||
telegram_id: Optional[int] = None
|
||||
full_name: Optional[str] = None
|
||||
username: Optional[str] = None
|
||||
created_at: Optional[datetime] = None
|
||||
last_activity: Optional[datetime] = None
|
||||
has_made_first_topup: bool = False
|
||||
balance_kopeks: int = 0
|
||||
balance_label: Optional[str] = None
|
||||
total_earned_kopeks: int = 0
|
||||
total_earned_label: Optional[str] = None
|
||||
topups_count: int = 0
|
||||
days_since_registration: Optional[int] = None
|
||||
days_since_activity: Optional[int] = None
|
||||
status: Optional[str] = None
|
||||
|
||||
|
||||
class MiniAppReferralList(BaseModel):
|
||||
total_count: int = 0
|
||||
has_next: bool = False
|
||||
has_prev: bool = False
|
||||
current_page: int = 1
|
||||
total_pages: int = 1
|
||||
items: List[MiniAppReferralItem] = Field(default_factory=list)
|
||||
|
||||
|
||||
class MiniAppReferralInfo(BaseModel):
|
||||
referral_code: Optional[str] = None
|
||||
referral_link: Optional[str] = None
|
||||
terms: Optional[MiniAppReferralTerms] = None
|
||||
stats: Optional[MiniAppReferralStats] = None
|
||||
recent_earnings: List[MiniAppReferralRecentEarning] = Field(default_factory=list)
|
||||
referrals: Optional[MiniAppReferralList] = None
|
||||
|
||||
|
||||
class MiniAppSubscriptionResponse(BaseModel):
|
||||
success: bool = True
|
||||
subscription_id: int
|
||||
@@ -89,8 +275,16 @@ class MiniAppSubscriptionResponse(BaseModel):
|
||||
balance_rubles: float = 0.0
|
||||
balance_currency: Optional[str] = None
|
||||
transactions: List[MiniAppTransaction] = Field(default_factory=list)
|
||||
promo_offers: List[MiniAppPromoOffer] = Field(default_factory=list)
|
||||
promo_group: Optional[MiniAppPromoGroup] = None
|
||||
auto_assign_promo_groups: List[MiniAppAutoPromoGroupLevel] = Field(default_factory=list)
|
||||
total_spent_kopeks: int = 0
|
||||
total_spent_rubles: float = 0.0
|
||||
total_spent_label: Optional[str] = None
|
||||
subscription_type: str
|
||||
autopay_enabled: bool = False
|
||||
branding: Optional[MiniAppBranding] = None
|
||||
faq: Optional[MiniAppFaq] = None
|
||||
legal_documents: Optional[MiniAppLegalDocuments] = None
|
||||
referral: Optional[MiniAppReferralInfo] = None
|
||||
|
||||
|
||||
+3953
-99
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user