add module hooks to replace profile text / implement interception of gifts via hooks / add dynamic control of buttons in key interfaces / add insert_at button ordering via hooks

This commit is contained in:
Capybara-z
2025-08-21 17:00:03 +03:00
parent a5a4e16990
commit ab8efe8529
6 changed files with 74 additions and 7 deletions
+2 -2
View File
@@ -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(
+17 -2
View File
@@ -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:
+30 -2
View File
@@ -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"<b>{subgroup}</b>\n\nВыберите тариф:",
reply_markup=builder.as_markup(),
reply_markup=final_markup,
)
except Exception as e:
+4
View File
@@ -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<blockquote><i>{NEWS_MESSAGE}</i></blockquote>"
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:
+11
View File
@@ -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:
+10 -1
View File
@@ -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))