This commit is contained in:
machka pasla
2025-11-07 20:47:09 +03:00
parent 7d446d5f64
commit 643bf5fabb
+83 -19
View File
@@ -4,7 +4,7 @@ from aiogram import Router, F, types, Bot
from aiogram.exceptions import TelegramBadRequest
from aiogram.fsm.context import FSMContext
from aiogram.utils.markdown import hcode, hbold
from typing import Optional, Dict, Any
from typing import Optional, Dict, Any, Callable, Awaitable
from sqlalchemy.ext.asyncio import AsyncSession
from datetime import datetime, timezone
@@ -174,6 +174,56 @@ def get_user_card_keyboard(user_id: int, i18n_instance, lang: str,
return builder
def _remove_profile_link_buttons(
markup: Optional[types.InlineKeyboardMarkup]) -> Optional[types.InlineKeyboardMarkup]:
"""Drop buttons that rely on tg://user links to avoid BUTTON_USER_INVALID errors."""
if not markup or not markup.inline_keyboard:
return None
cleaned_rows = []
for row in markup.inline_keyboard:
filtered_row = [
button for button in row
if not (getattr(button, "url", None) and button.url.startswith("tg://user?id="))
]
if filtered_row:
cleaned_rows.append(filtered_row)
if not cleaned_rows:
return None
return types.InlineKeyboardMarkup(inline_keyboard=cleaned_rows)
async def _send_with_profile_link_fallback(
sender: Callable[..., Awaitable[Any]],
*,
text: str,
markup: Optional[types.InlineKeyboardMarkup],
user_id: int,
parse_mode: Optional[str] = "HTML") -> None:
"""Send text with markup and fallback if Telegram rejects tg://user buttons."""
send_kwargs: Dict[str, Any] = {"text": text, "reply_markup": markup}
if parse_mode is not None:
send_kwargs["parse_mode"] = parse_mode
try:
await sender(**send_kwargs)
except TelegramBadRequest as exc:
message = getattr(exc, "message", "") or str(exc)
if "BUTTON_USER_INVALID" not in message:
raise
logging.warning(
"Telegram rejected profile buttons for user %s: %s. Retrying without tg:// links.",
user_id,
message,
)
fallback_markup = _remove_profile_link_buttons(markup)
send_kwargs["reply_markup"] = fallback_markup
await sender(**send_kwargs)
async def format_user_card(user: User, session: AsyncSession,
subscription_service: SubscriptionService,
i18n_instance, lang: str,
@@ -337,9 +387,11 @@ async def process_user_search_handler(message: types.Message, state: FSMContext,
user_model.referred_by_id
)
await message.answer(
user_card_text,
reply_markup=keyboard.as_markup(),
await _send_with_profile_link_fallback(
message.answer,
text=user_card_text,
markup=keyboard.as_markup(),
user_id=user_model.user_id,
parse_mode="HTML"
)
except Exception as e:
@@ -606,17 +658,22 @@ async def handle_refresh_user_card(callback: types.CallbackQuery, user: User,
lang,
fresh_user.referred_by_id
)
markup = keyboard.as_markup()
try:
await callback.message.edit_text(
user_card_text,
reply_markup=keyboard.as_markup(),
await _send_with_profile_link_fallback(
callback.message.edit_text,
text=user_card_text,
markup=markup,
user_id=fresh_user.user_id,
parse_mode="HTML"
)
except Exception:
await callback.message.answer(
user_card_text,
reply_markup=keyboard.as_markup(),
await _send_with_profile_link_fallback(
callback.message.answer,
text=user_card_text,
markup=markup,
user_id=fresh_user.user_id,
parse_mode="HTML"
)
@@ -896,9 +953,11 @@ async def process_subscription_days_handler(message: types.Message, state: FSMCo
user.referred_by_id
)
await message.answer(
user_card_text,
reply_markup=keyboard.as_markup(),
await _send_with_profile_link_fallback(
message.answer,
text=user_card_text,
markup=keyboard.as_markup(),
user_id=user.user_id,
parse_mode="HTML"
)
else:
@@ -1010,9 +1069,11 @@ async def process_direct_message_handler(message: types.Message, state: FSMConte
target_user.referred_by_id
)
await message.answer(
user_card_text,
reply_markup=keyboard.as_markup(),
await _send_with_profile_link_fallback(
message.answer,
text=user_card_text,
markup=keyboard.as_markup(),
user_id=target_user.user_id,
parse_mode="HTML"
)
@@ -1325,10 +1386,13 @@ async def user_card_from_list_handler(callback: types.CallbackQuery,
from bot.services.referral_service import ReferralService
referral_service = ReferralService(settings, subscription_service, bot, i18n)
user_card_text = await format_user_card(user, session, subscription_service, i18n, current_lang, referral_service)
markup = keyboard.as_markup()
await callback.message.edit_text(
user_card_text,
reply_markup=keyboard.as_markup(),
await _send_with_profile_link_fallback(
callback.message.edit_text,
text=user_card_text,
markup=markup,
user_id=user.user_id,
parse_mode="HTML"
)
await callback.answer()