From e2d31525eaeecfcbf6be26b2aeabc7d5f3db0b60 Mon Sep 17 00:00:00 2001 From: Capybara-z Date: Thu, 5 Jun 2025 01:14:20 +0300 Subject: [PATCH] add: android tv connection for remnawave --- handlers/admin/clusters/clusters_handler.py | 37 +++++++++++++++++---- handlers/instructions/instructions.py | 34 +++++++++++-------- handlers/keys/key_mode/key_cluster_mode.py | 3 ++ handlers/keys/key_mode/key_country_mode.py | 3 ++ handlers/keys/key_view.py | 3 ++ 5 files changed, 61 insertions(+), 19 deletions(-) diff --git a/handlers/admin/clusters/clusters_handler.py b/handlers/admin/clusters/clusters_handler.py index 20f0cecf..85dab862 100644 --- a/handlers/admin/clusters/clusters_handler.py +++ b/handlers/admin/clusters/clusters_handler.py @@ -611,9 +611,9 @@ async def handle_sync_cluster( traffic_limit_bytes = int(tariff.traffic_limit * 1024**3) hwid_limit = tariff.device_limit else: - logger.warning(f"[Sync] Ключ {key['client_id']} с несуществующим тарифом ID={key['tariff_id']} — обновим без лимитов") - - valid_email = f"{key['email']}@fake.local" + logger.warning( + f"[Sync] Ключ {key['client_id']} с несуществующим тарифом ID={key['tariff_id']} — обновим без лимитов" + ) inbound_ids = [ s["inbound_id"] @@ -621,16 +621,41 @@ async def handle_sync_cluster( if s.get("inbound_id") ] - await remna.update_user( + success = await remna.update_user( uuid=key["client_id"], expire_at=expire_iso, telegram_id=key["tg_id"], - email=valid_email, + email=f"{key['email']}@fake.local", active_user_inbounds=inbound_ids, traffic_limit_bytes=traffic_limit_bytes, hwid_device_limit=hwid_limit, ) + if not success: + logger.warning(f"[Sync] ошибка обновления, пробуем пересоздать") + + await delete_key_from_cluster( + cluster_name, key["email"], key["client_id"], session + ) + + await session.execute( + delete(Key).where( + Key.tg_id == key["tg_id"], + Key.client_id == key["client_id"] + ) + ) + + await create_key_on_cluster( + cluster_name, + key["tg_id"], + key["client_id"], + key["email"], + key["expiry_time"], + plan=key["tariff_id"], + session=session, + remnawave_link=key["remnawave_link"], + ) + else: await delete_key_from_cluster( cluster_name, key["email"], key["client_id"], session @@ -1200,4 +1225,4 @@ async def apply_tariff_group( logger.error(f"Ошибка при применении тарифной группы: {e}") await callback.message.edit_text( "❌ Произошла ошибка при установке тарифной группы." - ) + ) \ No newline at end of file diff --git a/handlers/instructions/instructions.py b/handlers/instructions/instructions.py index 1fe9a63a..1bbc4c3e 100644 --- a/handlers/instructions/instructions.py +++ b/handlers/instructions/instructions.py @@ -144,12 +144,19 @@ async def process_macos_menu(callback_query: CallbackQuery, session: Any): @router.callback_query(F.data.startswith("connect_tv|")) -async def process_connect_tv(callback_query: CallbackQuery): - key_name = callback_query.data.split("|")[1] +async def process_connect_tv(callback_query: CallbackQuery, session: Any): + data = callback_query.data.split("|") + key_name = data[1] + callback_data = callback_query.data + + if key_name == "direct" and len(data) > 2: + callback_data = f"continue_tv|{key_name}|{data[2]}" + else: + callback_data = callback_data.replace("connect_tv", "continue_tv") builder = InlineKeyboardBuilder() builder.row( - InlineKeyboardButton(text=TV_CONTINUE, callback_data=f"continue_tv|{key_name}") + InlineKeyboardButton(text=TV_CONTINUE, callback_data=callback_data) ) builder.row(InlineKeyboardButton(text=BACK, callback_data=f"view_key|{key_name}")) builder.row(InlineKeyboardButton(text=MAIN_MENU, callback_data="profile")) @@ -165,19 +172,20 @@ async def process_connect_tv(callback_query: CallbackQuery): @router.callback_query(F.data.startswith("continue_tv|")) async def process_continue_tv(callback_query: CallbackQuery, session: Any): - key_name = callback_query.data.split("|")[1] + data = callback_query.data.split("|") + key_name = data[1] + subscription_link = None + + if key_name == "direct" and len(data) > 2: + subscription_link = data[2] + else: + record = await get_key_details(session, key_name) + subscription_link = record["key"] - record = await get_key_details(session, key_name) - subscription_link = record["key"] message_text = SUBSCRIPTION_DETAILS_TEXT.format(subscription_link=subscription_link) builder = InlineKeyboardBuilder() - builder.row( - InlineKeyboardButton( - text=TV_INSTRUCTIONS, url="https://vpn4tv.com/quick-guide.html" - ) - ) - builder.row(InlineKeyboardButton(text=BACK, callback_data=f"connect_tv|{key_name}")) + builder.row(InlineKeyboardButton(text=BACK, callback_data=f"connect_tv|{key_name}|{subscription_link}" if subscription_link else f"connect_tv|{key_name}")) builder.row(InlineKeyboardButton(text=MAIN_MENU, callback_data="profile")) await edit_or_send_message( @@ -185,4 +193,4 @@ async def process_continue_tv(callback_query: CallbackQuery, session: Any): text=message_text, reply_markup=builder.as_markup(), media_path=None, - ) + ) \ No newline at end of file diff --git a/handlers/keys/key_mode/key_cluster_mode.py b/handlers/keys/key_mode/key_cluster_mode.py index ff252c6a..c0626a12 100644 --- a/handlers/keys/key_mode/key_cluster_mode.py +++ b/handlers/keys/key_mode/key_cluster_mode.py @@ -152,6 +152,9 @@ async def key_cluster_mode( text=CONNECT_DEVICE, web_app=WebAppInfo(url=final_link) ) ) + builder.row( + InlineKeyboardButton(text=TV_BUTTON, callback_data=f"connect_tv|direct|{final_link}") + ) elif CONNECT_PHONE_BUTTON: builder.row( InlineKeyboardButton( diff --git a/handlers/keys/key_mode/key_country_mode.py b/handlers/keys/key_mode/key_country_mode.py index a8233d50..da9f4728 100644 --- a/handlers/keys/key_mode/key_country_mode.py +++ b/handlers/keys/key_mode/key_country_mode.py @@ -528,6 +528,9 @@ async def finalize_key_creation( web_app=WebAppInfo(url=public_link or remnawave_link), ) ) + builder.row( + InlineKeyboardButton(text=TV_BUTTON, callback_data=f"connect_tv|direct|{public_link or remnawave_link}") + ) elif CONNECT_PHONE_BUTTON: builder.row( InlineKeyboardButton(text=CONNECT_PHONE, callback_data=f"connect_phone|{key_name}") diff --git a/handlers/keys/key_view.py b/handlers/keys/key_view.py index 312a1ac1..0030d3df 100644 --- a/handlers/keys/key_view.py +++ b/handlers/keys/key_view.py @@ -326,6 +326,9 @@ async def render_key_info( text=CONNECT_DEVICE, web_app=WebAppInfo(url=final_link) ) ) + builder.row( + InlineKeyboardButton(text=TV_BUTTON, callback_data=f"connect_tv|direct|{final_link}") + ) else: if CONNECT_PHONE_BUTTON: builder.row(