diff --git a/app/handlers/common.py b/app/handlers/common.py
index 17503bfc..ef2410d3 100644
--- a/app/handlers/common.py
+++ b/app/handlers/common.py
@@ -25,6 +25,17 @@ async def handle_delete_ban_notification(
await callback.answer('Не удалось удалить', show_alert=False)
+async def handle_webhook_notification_close(
+ callback: types.CallbackQuery,
+):
+ """Удаляет webhook-уведомление при нажатии кнопки Закрыть."""
+ try:
+ await callback.message.delete()
+ except Exception:
+ pass
+ await callback.answer()
+
+
async def handle_unknown_callback(callback: types.CallbackQuery, db_user: User):
texts = get_texts(db_user.language if db_user else 'ru')
@@ -86,8 +97,9 @@ async def show_rules(callback: types.CallbackQuery, db_user: User, db: AsyncSess
def register_handlers(dp: Dispatcher):
- # Удаление уведомлений о банах
+ # Удаление уведомлений
dp.callback_query.register(handle_delete_ban_notification, F.data == 'ban_notify:delete')
+ dp.callback_query.register(handle_webhook_notification_close, F.data == 'webhook:close')
dp.callback_query.register(show_rules, F.data == 'menu_rules')
diff --git a/app/localization/locales/en.json b/app/localization/locales/en.json
index 2401b495..6b4c159d 100644
--- a/app/localization/locales/en.json
+++ b/app/localization/locales/en.json
@@ -1716,5 +1716,6 @@
"WEBHOOK_RENEW_BUTTON": "🔄 Renew subscription",
"WEBHOOK_USER_NOT_CONNECTED": "📡 Not connected yet\n\nYour subscription is active but no VPN connection has been made. Connect to start using the service.",
"WEBHOOK_DEVICE_ADDED": "📱 New device\n\nA new device has been added to your subscription: {device}",
- "WEBHOOK_DEVICE_DELETED": "📱 Device removed\n\nA device has been removed from your subscription: {device}"
+ "WEBHOOK_DEVICE_DELETED": "📱 Device removed\n\nA device has been removed from your subscription: {device}",
+ "WEBHOOK_CLOSE_BUTTON": "✖️ Close"
}
diff --git a/app/localization/locales/fa.json b/app/localization/locales/fa.json
index 7e3a6215..1990861c 100644
--- a/app/localization/locales/fa.json
+++ b/app/localization/locales/fa.json
@@ -1734,5 +1734,6 @@
"WEBHOOK_RENEW_BUTTON": "🔄 تمدید اشتراک",
"WEBHOOK_USER_NOT_CONNECTED": "📡 هنوز متصل نشدهاید\n\nاشتراک شما فعال است اما هنوز اتصال VPN برقرار نشده. برای شروع استفاده متصل شوید.",
"WEBHOOK_DEVICE_ADDED": "📱 دستگاه جدید\n\nدستگاه جدیدی به اشتراک شما اضافه شد: {device}",
- "WEBHOOK_DEVICE_DELETED": "📱 دستگاه حذف شد\n\nدستگاهی از اشتراک شما حذف شد: {device}"
+ "WEBHOOK_DEVICE_DELETED": "📱 دستگاه حذف شد\n\nدستگاهی از اشتراک شما حذف شد: {device}",
+ "WEBHOOK_CLOSE_BUTTON": "✖️ بستن"
}
\ No newline at end of file
diff --git a/app/localization/locales/ru.json b/app/localization/locales/ru.json
index 97c14a5e..8c875193 100644
--- a/app/localization/locales/ru.json
+++ b/app/localization/locales/ru.json
@@ -1737,5 +1737,6 @@
"WEBHOOK_RENEW_BUTTON": "🔄 Продлить подписку",
"WEBHOOK_USER_NOT_CONNECTED": "📡 Вы ещё не подключились\n\nВаша подписка активна, но VPN-соединение не было установлено. Подключитесь, чтобы начать пользоваться.",
"WEBHOOK_DEVICE_ADDED": "📱 Новое устройство\n\nК вашей подписке подключено новое устройство: {device}",
- "WEBHOOK_DEVICE_DELETED": "📱 Устройство удалено\n\nУстройство отключено от подписки: {device}"
+ "WEBHOOK_DEVICE_DELETED": "📱 Устройство удалено\n\nУстройство отключено от подписки: {device}",
+ "WEBHOOK_CLOSE_BUTTON": "✖️ Закрыть"
}
diff --git a/app/localization/locales/ua.json b/app/localization/locales/ua.json
index caa156bc..f533e09d 100644
--- a/app/localization/locales/ua.json
+++ b/app/localization/locales/ua.json
@@ -1603,5 +1603,6 @@
"WEBHOOK_RENEW_BUTTON": "🔄 Продовжити підписку",
"WEBHOOK_USER_NOT_CONNECTED": "📡 Ви ще не підключились\n\nВаша підписка активна, але VPN-з'єднання не було встановлено. Підключіться, щоб почати користуватися.",
"WEBHOOK_DEVICE_ADDED": "📱 Новий пристрій\n\nДо вашої підписки підключено новий пристрій: {device}",
- "WEBHOOK_DEVICE_DELETED": "📱 Пристрій видалено\n\nПристрій відключено від підписки: {device}"
+ "WEBHOOK_DEVICE_DELETED": "📱 Пристрій видалено\n\nПристрій відключено від підписки: {device}",
+ "WEBHOOK_CLOSE_BUTTON": "✖️ Закрити"
}
diff --git a/app/localization/locales/zh.json b/app/localization/locales/zh.json
index 8eb84894..e1a9289d 100644
--- a/app/localization/locales/zh.json
+++ b/app/localization/locales/zh.json
@@ -1936,5 +1936,6 @@
"WEBHOOK_RENEW_BUTTON":"🔄 续订订阅",
"WEBHOOK_USER_NOT_CONNECTED":"📡 尚未连接\n\n您的订阅已激活,但尚未建立VPN连接。请连接以开始使用服务。",
"WEBHOOK_DEVICE_ADDED":"📱 新设备\n\n您的订阅已添加新设备:{device}",
-"WEBHOOK_DEVICE_DELETED":"📱 设备已移除\n\n设备已从您的订阅中移除:{device}"
+"WEBHOOK_DEVICE_DELETED":"📱 设备已移除\n\n设备已从您的订阅中移除:{device}",
+"WEBHOOK_CLOSE_BUTTON":"✖️ 关闭"
}
diff --git a/app/services/remnawave_webhook_service.py b/app/services/remnawave_webhook_service.py
index 42c294e1..312208db 100644
--- a/app/services/remnawave_webhook_service.py
+++ b/app/services/remnawave_webhook_service.py
@@ -15,7 +15,7 @@ from datetime import UTC, datetime
from typing import Any
from aiogram import Bot
-from aiogram.types import InlineKeyboardMarkup
+from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from sqlalchemy.ext.asyncio import AsyncSession
from app.database.crud.subscription import (
@@ -347,6 +347,16 @@ class RemnaWaveWebhookService:
logger.warning('Failed to format message %s with kwargs %s', text_key, format_kwargs)
return
+ # Append "Close" button to every webhook notification keyboard
+ close_text = texts.get('WEBHOOK_CLOSE_BUTTON', '✖️ Закрыть')
+ close_row = [InlineKeyboardButton(text=close_text, callback_data='webhook:close')]
+ if reply_markup:
+ reply_markup = InlineKeyboardMarkup(
+ inline_keyboard=[*reply_markup.inline_keyboard, close_row],
+ )
+ else:
+ reply_markup = InlineKeyboardMarkup(inline_keyboard=[close_row])
+
notification_type = _TEXT_KEY_TO_NOTIFICATION_TYPE.get(text_key)
if not notification_type:
logger.warning('No NotificationType mapping for text_key %s', text_key)