mirror of
https://github.com/BEDOLAGA-DEV/remnawave-bedolaga-telegram-bot.git
synced 2026-01-20 11:50:27 +00:00
Фиксы UI
This commit is contained in:
@@ -752,95 +752,13 @@ async def auto_activate_subscription_after_topup(
|
||||
|
||||
subscription = await get_subscription_by_user_id(db, user.id)
|
||||
|
||||
# Если автоактивация отключена - только отправляем уведомление
|
||||
# Если автоактивация отключена - уведомление отправится из _send_payment_success_notification
|
||||
if not settings.is_auto_activate_after_topup_enabled():
|
||||
# Если включен яркий промпт активации, НЕ отправляем уведомление здесь
|
||||
# т.к. оно будет отправлено через _send_payment_success_notification
|
||||
if settings.SHOW_ACTIVATION_PROMPT_AFTER_TOPUP:
|
||||
logger.info(
|
||||
"⚠️ Пропущена отправка уведомления пользователю %s (SHOW_ACTIVATION_PROMPT_AFTER_TOPUP=true, уведомление будет из payment service)",
|
||||
user.telegram_id,
|
||||
)
|
||||
return (False, False)
|
||||
|
||||
# Старая логика уведомлений для режима без яркого промпта
|
||||
notification_sent = False
|
||||
if bot:
|
||||
try:
|
||||
texts = get_texts(getattr(user, "language", "ru"))
|
||||
has_active_subscription = (
|
||||
subscription
|
||||
and subscription.status in ("active", "ACTIVE")
|
||||
)
|
||||
|
||||
# Формируем строку с суммой пополнения
|
||||
topup_line = ""
|
||||
if topup_amount:
|
||||
topup_line = f"➕ Пополнено: <b>{settings.format_price(topup_amount)}</b>\n"
|
||||
|
||||
# Определяем состояние подписки
|
||||
is_trial = subscription and getattr(subscription, 'is_trial', False)
|
||||
|
||||
if has_active_subscription and not is_trial:
|
||||
# Активная платная подписка — 2 кнопки
|
||||
warning_message = (
|
||||
f"✅ <b>Баланс пополнен!</b>\n\n"
|
||||
f"{topup_line}"
|
||||
f"💳 Текущий баланс: <b>{settings.format_price(user.balance_kopeks)}</b>\n\n"
|
||||
f"👇 <b>Выберите действие:</b>"
|
||||
)
|
||||
keyboard = InlineKeyboardMarkup(
|
||||
inline_keyboard=[
|
||||
[InlineKeyboardButton(
|
||||
text="💎 Продлить подписку",
|
||||
callback_data="subscription_extend",
|
||||
)],
|
||||
[InlineKeyboardButton(
|
||||
text="📱 Изменить устройства",
|
||||
callback_data="subscription_change_devices",
|
||||
)],
|
||||
]
|
||||
)
|
||||
else:
|
||||
# Триал или подписка закончилась — 1 кнопка
|
||||
warning_message = (
|
||||
f"✅ <b>Баланс пополнен!</b>\n\n"
|
||||
f"{topup_line}"
|
||||
f"💳 Текущий баланс: <b>{settings.format_price(user.balance_kopeks)}</b>\n\n"
|
||||
f"{'━' * 20}\n\n"
|
||||
f"🚨🚨🚨 <b>ВНИМАНИЕ!</b> 🚨🚨🚨\n\n"
|
||||
f"🔴 <b>ПОДПИСКА НЕ АКТИВНА!</b>\n\n"
|
||||
f"⚠️ Пополнение баланса <b>НЕ активирует</b> подписку автоматически!\n\n"
|
||||
f"👇 <b>Обязательно оформите подписку:</b>"
|
||||
)
|
||||
keyboard = InlineKeyboardMarkup(
|
||||
inline_keyboard=[
|
||||
[InlineKeyboardButton(
|
||||
text="🚀 КУПИТЬ ПОДПИСКУ",
|
||||
callback_data="menu_buy",
|
||||
)],
|
||||
]
|
||||
)
|
||||
|
||||
await bot.send_message(
|
||||
chat_id=user.telegram_id,
|
||||
text=warning_message,
|
||||
reply_markup=keyboard,
|
||||
parse_mode="HTML",
|
||||
)
|
||||
notification_sent = True
|
||||
logger.info(
|
||||
"⚠️ Отправлено уведомление о пополнении баланса пользователю %s (автоактивация выключена, подписка %s)",
|
||||
user.telegram_id,
|
||||
"активна" if has_active_subscription else "неактивна",
|
||||
)
|
||||
except Exception as notify_error:
|
||||
logger.warning(
|
||||
"⚠️ Не удалось отправить уведомление пользователю %s: %s",
|
||||
user.telegram_id,
|
||||
notify_error,
|
||||
)
|
||||
return (False, notification_sent)
|
||||
logger.info(
|
||||
"⚠️ Автоактивация отключена для пользователя %s, уведомление будет отправлено из payment service",
|
||||
user.telegram_id,
|
||||
)
|
||||
return (False, False)
|
||||
|
||||
# Если подписка активна — ничего не делаем (автоактивация включена, но подписка уже есть)
|
||||
if subscription and subscription.status == "ACTIVE" and subscription.end_date > datetime.utcnow():
|
||||
@@ -921,93 +839,12 @@ async def auto_activate_subscription_after_topup(
|
||||
user.telegram_id,
|
||||
balance,
|
||||
)
|
||||
# Если включен яркий промпт активации, НЕ отправляем уведомление здесь
|
||||
# т.к. оно будет отправлено через _send_payment_success_notification
|
||||
if settings.SHOW_ACTIVATION_PROMPT_AFTER_TOPUP:
|
||||
logger.info(
|
||||
"⚠️ Пропущена отправка уведомления пользователю %s (SHOW_ACTIVATION_PROMPT_AFTER_TOPUP=true, уведомление будет из payment service)",
|
||||
user.telegram_id,
|
||||
)
|
||||
return (False, False)
|
||||
|
||||
# Старая логика уведомлений для режима без яркого промпта
|
||||
notification_sent = False
|
||||
if bot:
|
||||
try:
|
||||
texts = get_texts(getattr(user, "language", "ru"))
|
||||
has_active_subscription = (
|
||||
subscription
|
||||
and subscription.status in ("active", "ACTIVE")
|
||||
)
|
||||
|
||||
# Формируем строку с суммой пополнения
|
||||
topup_line2 = ""
|
||||
if topup_amount:
|
||||
topup_line2 = f"➕ Пополнено: <b>{settings.format_price(topup_amount)}</b>\n"
|
||||
|
||||
# Определяем состояние подписки
|
||||
is_trial2 = subscription and getattr(subscription, 'is_trial', False)
|
||||
|
||||
if has_active_subscription and not is_trial2:
|
||||
# Активная платная подписка — 2 кнопки
|
||||
warning_message = (
|
||||
f"✅ <b>Баланс пополнен!</b>\n\n"
|
||||
f"{topup_line2}"
|
||||
f"💳 Текущий баланс: <b>{settings.format_price(balance)}</b>\n\n"
|
||||
f"👇 <b>Выберите действие:</b>"
|
||||
)
|
||||
keyboard = InlineKeyboardMarkup(
|
||||
inline_keyboard=[
|
||||
[InlineKeyboardButton(
|
||||
text="💎 Продлить подписку",
|
||||
callback_data="subscription_extend",
|
||||
)],
|
||||
[InlineKeyboardButton(
|
||||
text="📱 Изменить устройства",
|
||||
callback_data="subscription_change_devices",
|
||||
)],
|
||||
]
|
||||
)
|
||||
else:
|
||||
# Триал или подписка закончилась — 1 кнопка
|
||||
warning_message = (
|
||||
f"✅ <b>Баланс пополнен!</b>\n\n"
|
||||
f"{topup_line2}"
|
||||
f"💳 Текущий баланс: <b>{settings.format_price(balance)}</b>\n\n"
|
||||
f"{'━' * 20}\n\n"
|
||||
f"🚨🚨🚨 <b>ВНИМАНИЕ!</b> 🚨🚨🚨\n\n"
|
||||
f"🔴 <b>ПОДПИСКА НЕ АКТИВНА!</b>\n\n"
|
||||
f"⚠️ Пополнение баланса <b>НЕ активирует</b> подписку автоматически!\n\n"
|
||||
f"👇 <b>Обязательно оформите подписку:</b>"
|
||||
)
|
||||
keyboard = InlineKeyboardMarkup(
|
||||
inline_keyboard=[
|
||||
[InlineKeyboardButton(
|
||||
text="🚀 КУПИТЬ ПОДПИСКУ",
|
||||
callback_data="menu_buy",
|
||||
)],
|
||||
]
|
||||
)
|
||||
|
||||
await bot.send_message(
|
||||
chat_id=user.telegram_id,
|
||||
text=warning_message,
|
||||
reply_markup=keyboard,
|
||||
parse_mode="HTML",
|
||||
)
|
||||
notification_sent = True
|
||||
logger.info(
|
||||
"⚠️ Отправлено уведомление о пополнении баланса пользователю %s (недостаточно средств, подписка %s)",
|
||||
user.telegram_id,
|
||||
"активна" if has_active_subscription else "неактивна",
|
||||
)
|
||||
except Exception as notify_error:
|
||||
logger.warning(
|
||||
"⚠️ Не удалось отправить уведомление пользователю %s: %s",
|
||||
user.telegram_id,
|
||||
notify_error,
|
||||
)
|
||||
return (False, notification_sent)
|
||||
# Уведомление отправится из _send_payment_success_notification
|
||||
logger.info(
|
||||
"⚠️ Недостаточно средств для автоактивации пользователя %s, уведомление будет отправлено из payment service",
|
||||
user.telegram_id,
|
||||
)
|
||||
return (False, False)
|
||||
|
||||
texts = get_texts(getattr(user, "language", "ru"))
|
||||
|
||||
|
||||
@@ -259,6 +259,7 @@ class BotConfigurationService:
|
||||
"PAYMENT_BALANCE_TEMPLATE": "PAYMENT",
|
||||
"PAYMENT_SUBSCRIPTION_TEMPLATE": "PAYMENT",
|
||||
"AUTO_PURCHASE_AFTER_TOPUP_ENABLED": "PAYMENT",
|
||||
"SHOW_ACTIVATION_PROMPT_AFTER_TOPUP": "PAYMENT",
|
||||
"SIMPLE_SUBSCRIPTION_ENABLED": "SIMPLE_SUBSCRIPTION",
|
||||
"SIMPLE_SUBSCRIPTION_PERIOD_DAYS": "SIMPLE_SUBSCRIPTION",
|
||||
"SIMPLE_SUBSCRIPTION_DEVICE_LIMIT": "SIMPLE_SUBSCRIPTION",
|
||||
@@ -271,6 +272,10 @@ class BotConfigurationService:
|
||||
"NOTIFICATION_CACHE_HOURS": "NOTIFICATIONS",
|
||||
"MONITORING_LOGS_RETENTION_DAYS": "MONITORING",
|
||||
"MONITORING_INTERVAL": "MONITORING",
|
||||
"TRAFFIC_MONITORING_ENABLED": "MONITORING",
|
||||
"TRAFFIC_MONITORING_INTERVAL_HOURS": "MONITORING",
|
||||
"TRAFFIC_MONITORED_NODES": "MONITORING",
|
||||
"TRAFFIC_SNAPSHOT_TTL_HOURS": "MONITORING",
|
||||
"ENABLE_LOGO_MODE": "INTERFACE_BRANDING",
|
||||
"LOGO_FILE": "INTERFACE_BRANDING",
|
||||
"HIDE_SUBSCRIPTION_LINK": "INTERFACE_SUBSCRIPTION",
|
||||
@@ -570,6 +575,19 @@ class BotConfigurationService:
|
||||
"Используйте с осторожностью: средства будут списаны мгновенно, если корзина найдена."
|
||||
),
|
||||
},
|
||||
"SHOW_ACTIVATION_PROMPT_AFTER_TOPUP": {
|
||||
"description": (
|
||||
"Включает режим яркого промпта активации подписки после пополнения баланса. "
|
||||
"Вместо обычного уведомления пользователь получит яркое сообщение с восклицательными знаками "
|
||||
"и кнопками для активации/продления подписки или изменения количества устройств."
|
||||
),
|
||||
"format": "Булево значение.",
|
||||
"example": "true",
|
||||
"warning": (
|
||||
"При включении пользователи будут получать только яркое уведомление без кнопок баланса и главного меню. "
|
||||
"Эти кнопки появятся после выполнения действия (активация/продление/изменение устройств)."
|
||||
),
|
||||
},
|
||||
"SUPPORT_TICKET_SLA_MINUTES": {
|
||||
"description": "Лимит времени для ответа модераторов на тикет в минутах.",
|
||||
"format": "Целое число от 1 до 1440.",
|
||||
@@ -710,6 +728,58 @@ class BotConfigurationService:
|
||||
"warning": "Убедитесь, что конфигурация существует в панели и содержит нужные приложения.",
|
||||
"dependencies": "Настроенное подключение к RemnaWave API",
|
||||
},
|
||||
"TRAFFIC_MONITORING_ENABLED": {
|
||||
"description": (
|
||||
"Включает автоматический мониторинг трафика пользователей. "
|
||||
"Система отслеживает изменения трафика (дельту) и сохраняет snapshot в Redis. "
|
||||
"При превышении порогов отправляются уведомления пользователям и админам."
|
||||
),
|
||||
"format": "Булево значение.",
|
||||
"example": "true",
|
||||
"warning": (
|
||||
"Требует настроенного подключения к Redis. "
|
||||
"При включении будет запущен фоновый мониторинг трафика по расписанию."
|
||||
),
|
||||
"dependencies": "Redis, TRAFFIC_MONITORING_INTERVAL_HOURS, TRAFFIC_SNAPSHOT_TTL_HOURS",
|
||||
},
|
||||
"TRAFFIC_MONITORING_INTERVAL_HOURS": {
|
||||
"description": (
|
||||
"Интервал проверки трафика в часах. "
|
||||
"Каждые N часов система проверяет трафик всех активных пользователей и сравнивает с предыдущим snapshot."
|
||||
),
|
||||
"format": "Целое число часов (минимум 1).",
|
||||
"example": "24",
|
||||
"warning": (
|
||||
"Слишком маленький интервал может создать большую нагрузку на RemnaWave API. "
|
||||
"Рекомендуется 24 часа для ежедневного мониторинга."
|
||||
),
|
||||
"dependencies": "TRAFFIC_MONITORING_ENABLED",
|
||||
},
|
||||
"TRAFFIC_MONITORED_NODES": {
|
||||
"description": (
|
||||
"Список UUID нод для мониторинга трафика через запятую. "
|
||||
"Если пусто - мониторятся все ноды. "
|
||||
"Позволяет ограничить мониторинг только определенными серверами."
|
||||
),
|
||||
"format": "UUID через запятую или пусто для всех нод.",
|
||||
"example": "d4aa2b8c-9a36-4f31-93a2-6f07dad05fba, a1b2c3d4-5678-90ab-cdef-1234567890ab",
|
||||
"warning": "UUID должны существовать в RemnaWave, иначе мониторинг не будет работать.",
|
||||
"dependencies": "TRAFFIC_MONITORING_ENABLED",
|
||||
},
|
||||
"TRAFFIC_SNAPSHOT_TTL_HOURS": {
|
||||
"description": (
|
||||
"Время жизни (TTL) snapshot трафика в Redis в часах. "
|
||||
"Snapshot используется для вычисления дельты (изменения трафика) между проверками. "
|
||||
"После истечения TTL snapshot удаляется и создается новый."
|
||||
),
|
||||
"format": "Целое число часов (минимум 1).",
|
||||
"example": "24",
|
||||
"warning": (
|
||||
"TTL должен быть >= интервала мониторинга. "
|
||||
"Если TTL меньше интервала, snapshot будет удален до следующей проверки."
|
||||
),
|
||||
"dependencies": "TRAFFIC_MONITORING_ENABLED, Redis",
|
||||
},
|
||||
}
|
||||
|
||||
@classmethod
|
||||
|
||||
Reference in New Issue
Block a user