Fix: resolve buttons crash in phones menu when callback message contains photo
This commit is contained in:
parent
209d2f29e1
commit
633b0f0d05
1 changed files with 49 additions and 34 deletions
|
|
@ -18,6 +18,33 @@ import config
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
router = Router()
|
router = Router()
|
||||||
|
|
||||||
|
|
||||||
|
async def safe_edit_or_reply(event, text: str, reply_markup=None, parse_mode='HTML'):
|
||||||
|
"""
|
||||||
|
Безопасное редактирование сообщения.
|
||||||
|
Если сообщение содержит медиа (фото и т.д.), мы удаляем его и отправляем новое.
|
||||||
|
"""
|
||||||
|
if isinstance(event, CallbackQuery):
|
||||||
|
await event.answer()
|
||||||
|
message = event.message
|
||||||
|
if (hasattr(message, 'photo') and message.photo) or \
|
||||||
|
(hasattr(message, 'video') and message.video) or \
|
||||||
|
(hasattr(message, 'document') and message.document) or \
|
||||||
|
(hasattr(message, 'content_type') and message.content_type != 'text'):
|
||||||
|
try:
|
||||||
|
await message.delete()
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"Не удалось удалить сообщение с медиа: {e}")
|
||||||
|
await message.answer(text, reply_markup=reply_markup, parse_mode=parse_mode)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
await message.edit_text(text, reply_markup=reply_markup, parse_mode=parse_mode)
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"Ошибка edit_text: {e}. Отправляем новое сообщение.")
|
||||||
|
await message.answer(text, reply_markup=reply_markup, parse_mode=parse_mode)
|
||||||
|
elif isinstance(event, Message):
|
||||||
|
await event.answer(text, reply_markup=reply_markup, parse_mode=parse_mode)
|
||||||
|
|
||||||
@router.message(Command('cancel'), StateFilter('*'))
|
@router.message(Command('cancel'), StateFilter('*'))
|
||||||
@router.message(F.text.lower().in_(['отмена', 'отменить']), StateFilter('*'))
|
@router.message(F.text.lower().in_(['отмена', 'отменить']), StateFilter('*'))
|
||||||
async def global_cancel(message: Message, state: FSMContext):
|
async def global_cancel(message: Message, state: FSMContext):
|
||||||
|
|
@ -74,7 +101,8 @@ async def cb_main_menu(callback: CallbackQuery):
|
||||||
ig_stmt = select(InitiativeGroup).where(InitiativeGroup.user_id == user_id, InitiativeGroup.is_active == True)
|
ig_stmt = select(InitiativeGroup).where(InitiativeGroup.user_id == user_id, InitiativeGroup.is_active == True)
|
||||||
is_ig = (await session.execute(ig_stmt)).scalar_one_or_none() is not None
|
is_ig = (await session.execute(ig_stmt)).scalar_one_or_none() is not None
|
||||||
|
|
||||||
await callback.message.edit_text(
|
await safe_edit_or_reply(
|
||||||
|
callback,
|
||||||
"Главное меню:",
|
"Главное меню:",
|
||||||
reply_markup=get_main_menu(verified=user.verified, is_ig=is_ig, is_admin=(user.is_admin or user_id == config.ADMIN_USER_ID), is_superadmin=(user_id == config.ADMIN_USER_ID)),
|
reply_markup=get_main_menu(verified=user.verified, is_ig=is_ig, is_admin=(user.is_admin or user_id == config.ADMIN_USER_ID), is_superadmin=(user_id == config.ADMIN_USER_ID)),
|
||||||
parse_mode='HTML'
|
parse_mode='HTML'
|
||||||
|
|
@ -85,11 +113,7 @@ async def cb_main_menu(callback: CallbackQuery):
|
||||||
async def cb_phones(event):
|
async def cb_phones(event):
|
||||||
text = '📞 <b>ЭКСТРЕННЫЕ ТЕЛЕФОНЫ</b>\n\nВыберите категорию ниже:'
|
text = '📞 <b>ЭКСТРЕННЫЕ ТЕЛЕФОНЫ</b>\n\nВыберите категорию ниже:'
|
||||||
kb = get_phones_menu()
|
kb = get_phones_menu()
|
||||||
if isinstance(event, CallbackQuery):
|
await safe_edit_or_reply(event, text, reply_markup=kb, parse_mode='HTML')
|
||||||
await event.answer()
|
|
||||||
await event.message.edit_text(text, reply_markup=kb, parse_mode='HTML')
|
|
||||||
else:
|
|
||||||
await event.answer(text, reply_markup=kb, parse_mode='HTML')
|
|
||||||
|
|
||||||
@router.message(F.text & ~F.text.startswith('/'))
|
@router.message(F.text & ~F.text.startswith('/'))
|
||||||
async def chat_with_ai(message: Message):
|
async def chat_with_ai(message: Message):
|
||||||
|
|
@ -135,9 +159,19 @@ async def cb_phone_category(callback: CallbackQuery):
|
||||||
async with AsyncSessionLocal() as session:
|
async with AsyncSessionLocal() as session:
|
||||||
stmt = select(Service).where(Service.category == cat_code).order_by(Service.name)
|
stmt = select(Service).where(Service.category == cat_code).order_by(Service.name)
|
||||||
services = list((await session.execute(stmt)).scalars().all())
|
services = list((await session.execute(stmt)).scalars().all())
|
||||||
|
|
||||||
|
user_stmt = select(User).where(User.user_id == callback.from_user.id)
|
||||||
|
user = (await session.execute(user_stmt)).scalar_one_or_none()
|
||||||
|
ig_stmt = select(InitiativeGroup).where(InitiativeGroup.user_id == callback.from_user.id, InitiativeGroup.is_active == True)
|
||||||
|
is_ig = (await session.execute(ig_stmt)).scalar_one_or_none() is not None
|
||||||
|
|
||||||
|
is_admin = user.is_admin or callback.from_user.id == config.ADMIN_USER_ID if user else False
|
||||||
|
is_superadmin = callback.from_user.id == config.ADMIN_USER_ID
|
||||||
|
verified = user.verified if user else False
|
||||||
|
menu_kb = get_main_menu(verified=verified, is_ig=is_ig, is_admin=is_admin, is_superadmin=is_superadmin)
|
||||||
|
|
||||||
if not services:
|
if not services:
|
||||||
return await callback.message.edit_text("👷 Данные для этой категории еще не заполнены.", reply_markup=get_main_menu())
|
return await safe_edit_or_reply(callback, "👷 Данные для этой категории еще не заполнены.", reply_markup=menu_kb)
|
||||||
|
|
||||||
text = f"📞 <b>СПИСОК ТЕЛЕФОНОВ: {cat_code.upper()}</b>\n\n"
|
text = f"📞 <b>СПИСОК ТЕЛЕФОНОВ: {cat_code.upper()}</b>\n\n"
|
||||||
for s in services:
|
for s in services:
|
||||||
|
|
@ -150,11 +184,9 @@ async def cb_phone_category(callback: CallbackQuery):
|
||||||
|
|
||||||
if photo_path and os.path.exists(photo_path):
|
if photo_path and os.path.exists(photo_path):
|
||||||
await callback.message.delete()
|
await callback.message.delete()
|
||||||
await callback.message.answer_photo(FSInputFile(photo_path), caption=text, reply_markup=get_main_menu(), parse_mode='HTML')
|
await callback.message.answer_photo(FSInputFile(photo_path), caption=text, reply_markup=menu_kb, parse_mode='HTML')
|
||||||
else:
|
else:
|
||||||
await callback.message.edit_text(text, reply_markup=get_main_menu(), parse_mode='HTML')
|
await safe_edit_or_reply(callback, text, reply_markup=menu_kb, parse_mode='HTML')
|
||||||
|
|
||||||
await callback.answer()
|
|
||||||
|
|
||||||
@router.message(Command('rules'))
|
@router.message(Command('rules'))
|
||||||
@router.callback_query(F.data == 'rules')
|
@router.callback_query(F.data == 'rules')
|
||||||
|
|
@ -163,11 +195,7 @@ async def cb_rules(event):
|
||||||
kb = InlineKeyboardBuilder()
|
kb = InlineKeyboardBuilder()
|
||||||
kb.row(InlineKeyboardButton(text="🏠 В меню", callback_data="main_menu"))
|
kb.row(InlineKeyboardButton(text="🏠 В меню", callback_data="main_menu"))
|
||||||
|
|
||||||
if isinstance(event, Message):
|
await safe_edit_or_reply(event, text, reply_markup=kb.as_markup(), parse_mode='HTML')
|
||||||
await event.answer(text, reply_markup=kb.as_markup(), parse_mode='HTML')
|
|
||||||
else:
|
|
||||||
await event.answer()
|
|
||||||
await event.message.edit_text(text, reply_markup=kb.as_markup(), parse_mode='HTML')
|
|
||||||
|
|
||||||
@router.message(Command('about'))
|
@router.message(Command('about'))
|
||||||
@router.callback_query(F.data == 'about_house')
|
@router.callback_query(F.data == 'about_house')
|
||||||
|
|
@ -180,11 +208,7 @@ async def cb_about(event):
|
||||||
kb = InlineKeyboardBuilder()
|
kb = InlineKeyboardBuilder()
|
||||||
kb.row(InlineKeyboardButton(text="🏠 В меню", callback_data="main_menu"))
|
kb.row(InlineKeyboardButton(text="🏠 В меню", callback_data="main_menu"))
|
||||||
|
|
||||||
if isinstance(event, Message):
|
await safe_edit_or_reply(event, text, reply_markup=kb.as_markup(), parse_mode='HTML')
|
||||||
await event.answer(text, reply_markup=kb.as_markup(), parse_mode='HTML')
|
|
||||||
else:
|
|
||||||
await event.answer()
|
|
||||||
await event.message.edit_text(text, reply_markup=kb.as_markup(), parse_mode='HTML')
|
|
||||||
|
|
||||||
@router.message(Command('profile'))
|
@router.message(Command('profile'))
|
||||||
@router.callback_query(F.data == 'my_profile')
|
@router.callback_query(F.data == 'my_profile')
|
||||||
|
|
@ -207,11 +231,7 @@ async def cb_profile(event):
|
||||||
|
|
||||||
kb = get_profile_keyboard(user.meter_reminders_enabled if user else True)
|
kb = get_profile_keyboard(user.meter_reminders_enabled if user else True)
|
||||||
|
|
||||||
if isinstance(event, Message):
|
await safe_edit_or_reply(event, text, reply_markup=kb, parse_mode='HTML')
|
||||||
await event.answer(text, reply_markup=kb, parse_mode='HTML')
|
|
||||||
else:
|
|
||||||
await event.answer()
|
|
||||||
await event.message.edit_text(text, reply_markup=kb, parse_mode='HTML')
|
|
||||||
|
|
||||||
@router.callback_query(F.data == "toggle_meter_reminders")
|
@router.callback_query(F.data == "toggle_meter_reminders")
|
||||||
async def cb_toggle_meter_reminders(callback: CallbackQuery):
|
async def cb_toggle_meter_reminders(callback: CallbackQuery):
|
||||||
|
|
@ -244,12 +264,11 @@ async def cb_toggle_meter_reminders(callback: CallbackQuery):
|
||||||
f"Рейтинг: {user.rating} 🏆")
|
f"Рейтинг: {user.rating} 🏆")
|
||||||
|
|
||||||
kb = get_profile_keyboard(new_val)
|
kb = get_profile_keyboard(new_val)
|
||||||
await callback.message.edit_text(text, reply_markup=kb, parse_mode='HTML')
|
await safe_edit_or_reply(callback, text, reply_markup=kb, parse_mode='HTML')
|
||||||
|
|
||||||
@router.callback_query(F.data == "edit_location")
|
@router.callback_query(F.data == "edit_location")
|
||||||
async def edit_location_start(callback: CallbackQuery):
|
async def edit_location_start(callback: CallbackQuery):
|
||||||
await callback.message.edit_text("Введите ваш подъезд и этаж через пробел\n<i>Например: '3 5' (3 подъезд, 5 этаж)</i>", parse_mode='HTML')
|
await safe_edit_or_reply(callback, "Введите ваш подъезд и этаж через пробел\n<i>Например: '3 5' (3 подъезд, 5 этаж)</i>")
|
||||||
await callback.answer()
|
|
||||||
|
|
||||||
@router.message(F.text.regexp(r"^\d+\s+\d+$"))
|
@router.message(F.text.regexp(r"^\d+\s+\d+$"))
|
||||||
async def process_location(message: Message):
|
async def process_location(message: Message):
|
||||||
|
|
@ -282,8 +301,4 @@ async def cb_help(event):
|
||||||
kb = InlineKeyboardBuilder()
|
kb = InlineKeyboardBuilder()
|
||||||
kb.row(InlineKeyboardButton(text="🏠 В меню", callback_data="main_menu"))
|
kb.row(InlineKeyboardButton(text="🏠 В меню", callback_data="main_menu"))
|
||||||
|
|
||||||
if isinstance(event, Message):
|
await safe_edit_or_reply(event, text, reply_markup=kb.as_markup(), parse_mode='HTML')
|
||||||
await event.answer(text, reply_markup=kb.as_markup(), parse_mode='HTML')
|
|
||||||
else:
|
|
||||||
await event.answer()
|
|
||||||
await event.message.edit_text(text, reply_markup=kb.as_markup(), parse_mode='HTML')
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue