diff --git a/handlers/instructions/instructions.py b/handlers/instructions/instructions.py index 7ffb3ab3..5daf3d5c 100644 --- a/handlers/instructions/instructions.py +++ b/handlers/instructions/instructions.py @@ -82,7 +82,7 @@ async def process_connect_pc(callback_query: CallbackQuery, session: Any): builder = InlineKeyboardBuilder() builder.row(InlineKeyboardButton(text=PC_PC, callback_data=f"windows_menu|{key_name}")) builder.row(InlineKeyboardButton(text=PC_MACOS, callback_data=f"macos_menu|{key_name}")) - builder.row(InlineKeyboardButton(text=BACK, callback_data=f"view_key|{key_name}")) + builder.row(InlineKeyboardButton(text=BACK, callback_data=f"connect_device|{key_name}")) await edit_or_send_message( target_message=callback_query.message, @@ -142,7 +142,7 @@ async def process_connect_tv(callback_query: CallbackQuery, session: Any): builder = InlineKeyboardBuilder() builder.row(InlineKeyboardButton(text=TV_CONTINUE, callback_data=f"continue_tv|{key_name}")) - builder.row(InlineKeyboardButton(text=BACK, callback_data=f"view_key|{key_name}")) + builder.row(InlineKeyboardButton(text=BACK, callback_data=f"connect_device|{key_name}")) builder.row(InlineKeyboardButton(text=MAIN_MENU, callback_data="profile")) await edit_or_send_message( diff --git a/handlers/keys/key_connect.py b/handlers/keys/key_connect.py index 4cd392ee..0eb80251 100644 --- a/handlers/keys/key_connect.py +++ b/handlers/keys/key_connect.py @@ -38,6 +38,8 @@ from handlers.texts import ( SUBSCRIPTION_DESCRIPTION, ) from handlers.utils import edit_or_send_message +from hooks.hooks import run_hooks +from hooks.hook_buttons import insert_hook_buttons from logger import logger @@ -45,7 +47,7 @@ router = Router() @router.callback_query(F.data.startswith("connect_device|")) -async def handle_connect_device(callback_query: CallbackQuery): +async def handle_connect_device(callback_query: CallbackQuery, session: AsyncSession): try: key_name = callback_query.data.split("|")[1] @@ -57,10 +59,23 @@ async def handle_connect_device(callback_query: CallbackQuery): # builder.row(InlineKeyboardButton(text=ROUTER, callback_data=f"connect_router|{key_name}")) builder.row(InlineKeyboardButton(text=BACK, callback_data=f"view_key|{key_name}")) + try: + hook_builder = InlineKeyboardBuilder() + hook_builder.attach(builder) + + hook_commands = await run_hooks("connect_device_menu", chat_id=callback_query.from_user.id, admin=False, session=session) + if hook_commands: + hook_builder = insert_hook_buttons(hook_builder, hook_commands) + + final_markup = hook_builder.as_markup() + except Exception as e: + logger.warning(f"[CONNECT_DEVICE] Ошибка при применении хуков: {e}") + final_markup = builder.as_markup() + await edit_or_send_message( target_message=callback_query.message, text=CHOOSE_DEVICE_TEXT, - reply_markup=builder.as_markup(), + reply_markup=final_markup, media_path=None, ) except Exception as e: diff --git a/handlers/keys/key_renew.py b/handlers/keys/key_renew.py index 0516cb4a..10d42ee4 100644 --- a/handlers/keys/key_renew.py +++ b/handlers/keys/key_renew.py @@ -41,6 +41,8 @@ from handlers.texts import ( get_renewal_message, ) from handlers.utils import edit_or_send_message, get_russian_month +from hooks.hooks import run_hooks +from hooks.hook_buttons import insert_hook_buttons from logger import logger from utils.modules_loader import load_module_fast_flow_handlers @@ -136,6 +138,19 @@ async def process_callback_renew_key(callback_query: CallbackQuery, state: FSMCo builder.row(InlineKeyboardButton(text=BACK, callback_data="renew_menu")) + try: + hook_builder = InlineKeyboardBuilder() + hook_builder.attach(builder) + + hook_commands = await run_hooks("renew_tariffs", chat_id=tg_id, admin=False, session=session) + if hook_commands: + hook_builder = insert_hook_buttons(hook_builder, hook_commands) + + final_markup = hook_builder.as_markup() + except Exception as e: + logger.warning(f"[RENEW] Ошибка при применении хуков: {e}") + final_markup = builder.as_markup() + balance = await get_balance(session, tg_id) response_message = PLAN_SELECTION_MSG.format( balance=balance, @@ -145,7 +160,7 @@ async def process_callback_renew_key(callback_query: CallbackQuery, state: FSMCo await edit_or_send_message( target_message=callback_query.message, text=response_message, - reply_markup=builder.as_markup(), + reply_markup=final_markup, ) except Exception as e: @@ -222,10 +237,23 @@ async def show_tariffs_in_renew_subgroup(callback: CallbackQuery, state: FSMCont builder.row(InlineKeyboardButton(text="⬅️ Назад", callback_data=f"renew_key|{key_name}")) builder.row(InlineKeyboardButton(text=MAIN_MENU, callback_data="profile")) + try: + hook_builder = InlineKeyboardBuilder() + hook_builder.attach(builder) + + hook_commands = await run_hooks("renew_tariffs", chat_id=callback.from_user.id, admin=False, session=session) + if hook_commands: + hook_builder = insert_hook_buttons(hook_builder, hook_commands) + + final_markup = hook_builder.as_markup() + except Exception as e: + logger.warning(f"[RENEW_SUBGROUP] Ошибка при применении хуков: {e}") + final_markup = builder.as_markup() + await edit_or_send_message( target_message=callback.message, text=f"{subgroup}\n\nВыберите тариф:", - reply_markup=builder.as_markup(), + reply_markup=final_markup, ) except Exception as e: diff --git a/handlers/profile.py b/handlers/profile.py index 1cc9660d..84a85d49 100644 --- a/handlers/profile.py +++ b/handlers/profile.py @@ -66,6 +66,10 @@ async def process_callback_view_profile( profile_message = profile_message_send(username, chat_id, int(balance), key_count) profile_message += ADD_SUBSCRIPTION_HINT if key_count == 0 else f"\n
{NEWS_MESSAGE}" + text_hooks = await run_hooks("profile_text", username=username, chat_id=chat_id, balance=int(balance), key_count=key_count, session=session) + if text_hooks: + profile_message = text_hooks[0] + builder = InlineKeyboardBuilder() if key_count > 0: diff --git a/handlers/start.py b/handlers/start.py index 10950d7b..aa281812 100644 --- a/handlers/start.py +++ b/handlers/start.py @@ -173,6 +173,17 @@ async def handle_gift(part, message, state, session, user_data): processing_gifts.add(gift_id) try: + gift_results = await run_hooks("gift_activation", + gift_id=gift_id, + message=message, + state=state, + session=session, + user_data=user_data + ) + + if gift_results and "SUCCESS" in gift_results: + return True + await handle_gift_link(gift_id, message, state, session, user_data=user_data) return True finally: diff --git a/hooks/hook_buttons.py b/hooks/hook_buttons.py index 1de2287a..faad331a 100644 --- a/hooks/hook_buttons.py +++ b/hooks/hook_buttons.py @@ -9,6 +9,7 @@ def insert_hook_buttons(builder: InlineKeyboardBuilder, buttons: list) -> Inline Поддерживает: - {"button": InlineKeyboardButton} — добавить в конец - {"after": callback_data, "button": InlineKeyboardButton} — вставить после заданной кнопки + - {"insert_at": int, "button": InlineKeyboardButton} — вставить по индексу (0 = начало) - {"remove": str | list[str]} — удалить кнопки с указанным callback_data - {"remove_prefix": str} — удалить кнопки, у которых callback_data начинается с префикса """ @@ -58,11 +59,19 @@ def insert_hook_buttons(builder: InlineKeyboardBuilder, buttons: list) -> Inline new_rows.insert(insert_pos, [button]) else: new_rows.append([button]) + elif isinstance(module, dict) and "insert_at" in module and "button" in module: + insert_at = module["insert_at"] + button = module["button"] + + if 0 <= insert_at <= len(new_rows): + new_rows.insert(insert_at, [button]) + else: + new_rows.append([button]) else: if isinstance(module, dict) and "button" in module: button = module["button"] new_rows.append([button]) - elif module and not isinstance(module, dict): # оставим совместимость со старыми модулями + elif module and not isinstance(module, dict): new_rows.append([module]) return InlineKeyboardBuilder.from_markup(InlineKeyboardMarkup(inline_keyboard=new_rows))