import html import traceback from aiogram import Router, F from aiogram.fsm.context import FSMContext from aiogram.types import CallbackQuery from helper_bot.keyboards.keyboards import create_keyboard_with_pagination, get_reply_keyboard_admin, \ create_keyboard_for_ban_reason from helper_bot.utils.base_dependency_factory import get_global_instance from helper_bot.utils.helper_func import send_text_message, send_photo_message, get_banned_users_list, \ get_banned_users_buttons, delete_user_blacklist, send_media_group_to_channel, \ send_video_message, send_video_note_message, send_audio_message, send_voice_message from logs.custom_logger import logger callback_router = Router() bdf = get_global_instance() GROUP_FOR_POST = bdf.settings['Telegram']['group_for_posts'] GROUP_FOR_MESSAGE = bdf.settings['Telegram']['group_for_message'] MAIN_PUBLIC = bdf.settings['Telegram']['main_public'] GROUP_FOR_LOGS = bdf.settings['Telegram']['group_for_logs'] IMPORTANT_LOGS = bdf.settings['Telegram']['important_logs'] PREVIEW_LINK = bdf.settings['Telegram']['preview_link'] LOGS = bdf.settings['Settings']['logs'] TEST = bdf.settings['Settings']['test'] BotDB = bdf.get_db() @callback_router.callback_query( F.data == "publish" ) async def post_for_group(call: CallbackQuery, state: FSMContext): logger.info( f'Получен callback-запрос с действием: {call.data} от пользователя {call.from_user.full_name} (ID сообщения: {call.message.message_id})') text_post = html.escape(str(call.message.text)) text_post_with_photo = html.escape(str(call.message.caption)) if call.message.content_type == 'text' and call.message.text != "^": try: # Пересылаем сообщение в канал await send_text_message(MAIN_PUBLIC, call.message, text_post) # Получаем из базы автора author_id = BotDB.get_author_id_by_message_id(call.message.message_id) # Очищаем предложку и удаляем оттуда пост await call.bot.delete_message(chat_id=GROUP_FOR_POST, message_id=call.message.message_id) logger.info(f'Текст сообщения опубликован в канале {MAIN_PUBLIC}.') await call.answer(text='Выложено!', cache_time=3) # Отвечаем пользователю await send_text_message(author_id, call.message, 'Твой пост был выложен🥰') except Exception as e: if e.message != 'Forbidden: bot was blocked by the user': await call.bot.send_message(chat_id=IMPORTANT_LOGS, text=f"Произошла ошибка: {str(e)}\n\nTraceback:\n{traceback.format_exc()}") logger.error(f'Ошибка при публикации текста в канал {MAIN_PUBLIC}: {str(e)}') await call.answer(text='Что-то пошло не так!', show_alert=True, cache_time=3) elif call.message.content_type == 'photo': try: await send_photo_message(MAIN_PUBLIC, call.message, call.message.photo[-1].file_id, text_post_with_photo) # Получаем из базы автора + отправляем сообщение + удаляем сообщение из предложки author_id = BotDB.get_author_id_by_message_id(call.message.message_id) # Удаляем пост из предложки await call.bot.delete_message(chat_id=GROUP_FOR_POST, message_id=call.message.message_id) logger.info(f'Пост с фото опубликован в канале {MAIN_PUBLIC}.') await call.answer(text='Выложено!', cache_time=3) await send_text_message(author_id, call.message, 'Твой пост был выложен🥰') except Exception as e: if e.message != 'Forbidden: bot was blocked by the user': await call.bot.send_message(chat_id=IMPORTANT_LOGS, text=f"Произошла ошибка: {str(e)}\n\nTraceback:\n{traceback.format_exc()}") logger.error(f'Ошибка при публикации фотографии в канал {MAIN_PUBLIC}: {str(e)}') await call.answer(text='Что-то пошло не так!', show_alert=True, cache_time=3) elif call.message.content_type == 'video': try: await send_video_message(MAIN_PUBLIC, call.message, call.message.video.file_id, text_post_with_photo) # Получаем из базы автора + отправляем сообщение + удаляем сообщение из предложки author_id = BotDB.get_author_id_by_message_id(call.message.message_id) await call.bot.delete_message(chat_id=GROUP_FOR_POST, message_id=call.message.message_id) logger.info(f'Пост с видео опубликован в канале {MAIN_PUBLIC}.') await call.answer(text='Выложено!', cache_time=3) await send_text_message(author_id, call.message, 'Твой пост был выложен🥰') except Exception as e: if e.message != 'Forbidden: bot was blocked by the user': await call.bot.send_message(chat_id=IMPORTANT_LOGS, text=f"Произошла ошибка: {str(e)}\n\nTraceback:\n{traceback.format_exc()}") logger.error(f'Ошибка при публикации видео в канал {MAIN_PUBLIC}: {str(e)}') await call.answer(text='Что-то пошло не так!', show_alert=True, cache_time=3) elif call.message.content_type == 'video_note': try: await send_video_note_message(MAIN_PUBLIC, call.message, call.message.video_note.file_id) # Получаем из базы автора + отправляем сообщение + удаляем сообщение из предложки author_id = BotDB.get_author_id_by_message_id(call.message.message_id) await call.bot.delete_message(chat_id=GROUP_FOR_POST, message_id=call.message.message_id) logger.info(f'Пост с кружком опубликован в канале {MAIN_PUBLIC}.') await call.answer(text='Выложено!', cache_time=3) await send_text_message(author_id, call.message, 'Твой пост был выложен🥰') except Exception as e: if e.message != 'Forbidden: bot was blocked by the user': await call.bot.send_message(chat_id=IMPORTANT_LOGS, text=f"Произошла ошибка: {str(e)}\n\nTraceback:\n{traceback.format_exc()}") logger.error(f'Ошибка при публикации кружка в канал {MAIN_PUBLIC}: {str(e)}') await call.answer(text='Что-то пошло не так!', show_alert=True, cache_time=3) elif call.message.content_type == 'audio': try: await send_audio_message(MAIN_PUBLIC, call.message, call.message.audio.file_id, text_post_with_photo) # Получаем из базы автора + отправляем сообщение + удаляем сообщение из предложки author_id = BotDB.get_author_id_by_message_id(call.message.message_id) await call.bot.delete_message(chat_id=GROUP_FOR_POST, message_id=call.message.message_id) logger.info(f'Пост с аудио опубликован в канале {MAIN_PUBLIC}.') await call.answer(text='Выложено!', cache_time=3) await send_text_message(author_id, call.message, 'Твой пост был выложен🥰') except Exception as e: if e.message != 'Forbidden: bot was blocked by the user': await call.bot.send_message(chat_id=IMPORTANT_LOGS, text=f"Произошла ошибка: {str(e)}\n\nTraceback:\n{traceback.format_exc()}") logger.error(f'Ошибка при публикации аудио в канал {MAIN_PUBLIC}: {str(e)}') await call.answer(text='Что-то пошло не так!', show_alert=True, cache_time=3) elif call.message.content_type == 'voice': try: await send_voice_message(MAIN_PUBLIC, call.message, call.message.voice.file_id) # Получаем из базы автора + отправляем сообщение + удаляем сообщение из предложки author_id = BotDB.get_author_id_by_message_id(call.message.message_id) await call.bot.delete_message(chat_id=GROUP_FOR_POST, message_id=call.message.message_id) logger.info(f'Пост с войсом опубликован в канале {MAIN_PUBLIC}.') await call.answer(text='Выложено!', cache_time=3) await send_text_message(author_id, call.message, 'Твой пост был выложен🥰') except Exception as e: if e.message != 'Forbidden: bot was blocked by the user': await call.bot.send_message(chat_id=IMPORTANT_LOGS, text=f"Произошла ошибка: {str(e)}\n\nTraceback:\n{traceback.format_exc()}") logger.error(f'Ошибка при публикации войса в канал {MAIN_PUBLIC}: {str(e)}') await call.answer(text='Что-то пошло не так!', show_alert=True, cache_time=3) elif call.message.text == "^": # Получаем контент медиагруппы и текст для публикации post_content = BotDB.get_post_content_from_telegram_by_last_id(call.message.message_id) pre_text = BotDB.get_post_text_from_telegram_by_last_id(call.message.message_id) post_text = html.escape(str(pre_text)) # Готовим список для удаления post_ids = BotDB.get_post_ids_from_telegram_by_last_id(call.message.message_id) message_ids = [row[0] for row in post_ids] message_ids.append(call.message.message_id) # Выкладываем пост в канал await send_media_group_to_channel(bot=call.bot, chat_id=MAIN_PUBLIC, post_content=post_content, post_text=post_text) # Получаем из базы автора + отправляем сообщение + удаляем сообщение из предложки author_id = BotDB.get_author_id_by_helper_message_id(call.message.message_id) # TODO: Удалить фотки с локалки после выкладки? await call.bot.delete_messages(chat_id=GROUP_FOR_POST, message_ids=message_ids) await call.answer(text='Выложено!', cache_time=3) await send_text_message(author_id, call.message, 'Твой пост был выложен🥰') @callback_router.callback_query( F.data == "decline" ) async def decline_post_for_group(call: CallbackQuery, state: FSMContext): logger.info( f'Получен callback-запрос с данными: {call.data} от пользователя {call.from_user.full_name} (ID: {call.from_user.id})') try: if call.message.content_type == 'text' and call.message.text != "^" or call.message.content_type == 'photo' \ or call.message.content_type == 'audio' or call.message.content_type == 'voice' \ or call.message.content_type == 'video' or call.message.content_type == 'video_note': await call.bot.delete_message(chat_id=GROUP_FOR_POST, message_id=call.message.message_id) # Получаем из базы автора + отправляем сообщение + удаляем сообщение из предложки author_id = BotDB.get_author_id_by_message_id(call.message.message_id) logger.info( f'Сообщение отклонено админом {call.from_user.full_name} (ID: {call.from_user.id}).') await call.answer(text='Отклонено!', cache_time=3) await send_text_message(author_id, call.message, 'Твой пост был отклонен😔') if call.message.text == '^': post_ids = BotDB.get_post_ids_from_telegram_by_last_id(call.message.message_id) message_ids = [row[0] for row in post_ids] message_ids.append(call.message.message_id) await call.bot.delete_messages(chat_id=GROUP_FOR_POST, message_ids=message_ids) # Получаем из базы автора + отправляем сообщение + удаляем сообщение из предложки author_id = BotDB.get_author_id_by_helper_message_id(call.message.message_id) await call.answer(text='Удалено!', cache_time=3) await send_text_message(author_id, call.message, 'Твой пост был отклонен😔') except Exception as e: if e.message != 'Forbidden: bot was blocked by the user': await call.bot.send_message(IMPORTANT_LOGS, f"Произошла ошибка: {str(e)}\n\nTraceback:\n{traceback.format_exc()}") logger.error(f'Ошибка при удалении сообщения в группе {GROUP_FOR_POST}: {str(e)}') await call.answer(text='Что-то пошло не так!', show_alert=True, cache_time=3) @callback_router.callback_query( F.data.contains('ban') ) async def process_ban_user(call: CallbackQuery, state: FSMContext): user_id = call.data[4:] logger.info( f"Вызов функции process_ban_user. Данные callback: {call.data} пользователь: {user_id}") user_name = BotDB.get_username(user_id=user_id) if user_name: await state.update_data(user_id=user_id, user_name=user_name, message_for_user=None, date_to_unban=None) markup = create_keyboard_for_ban_reason() # Экранируем потенциально проблемные символы user_name_escaped = html.escape(str(user_name)) full_name_escaped = html.escape(str(call.message.from_user.full_name)) await call.message.answer( text=f"Выбран пользователь:\nid: {user_id}\nusername: {user_name_escaped}\nИмя:{full_name_escaped}\nВыбери причину бана из списка или напиши ее в чат", reply_markup=markup) await state.set_state('BAN_2') else: markup = get_reply_keyboard_admin() await call.message.answer(text='Пользователь с таким ID не найден в базе', markup=markup) await state.set_state('ADMIN') @callback_router.callback_query( F.data.contains('unlock') ) async def process_unlock_user(call: CallbackQuery): user_id = call.data[7:] user_name = BotDB.get_username(user_id=user_id) delete_user_blacklist(user_id, BotDB) logger.info(f"Разблокирован пользователь с ID: {user_id} username:{user_name}") username = BotDB.get_username(user_id) await call.answer(f'Пользователь разблокирован {username}', show_alert=True) @callback_router.callback_query( F.data == 'return' ) async def return_to_main_menu(call: CallbackQuery): await call.message.delete() logger.info(f"Запуск админ панели для пользователя: {call.message.from_user.id}") markup = get_reply_keyboard_admin() await call.message.answer("Добро пожаловать в админку. Выбери что хочешь:", reply_markup=markup) @callback_router.callback_query( F.data.contains('page') ) async def change_page(call: CallbackQuery): page_number = int(call.data[5:]) logger.info(f"Переход на страницу {page_number}") if call.message.text == 'Список пользователей которые последними обращались к боту': list_users = BotDB.get_last_users_from_db() # TODO: Здесь где-то надо добавить обработку ошибки IndexError: list index out of range keyboard = create_keyboard_with_pagination(int(page_number), len(list_users), list_users, 'ban') await call.bot.edit_message_reply_markup(chat_id=call.message.chat.id, message_id=call.message.message_id, reply_markup=keyboard) else: # Готовим сообщения message_user = get_banned_users_list(int(page_number) * 7 - 7, BotDB) await call.bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.message_id, text=message_user) # Готовим клавиатуру buttons = get_banned_users_buttons(BotDB) keyboard = create_keyboard_with_pagination(int(call.data[5:]), len(buttons), buttons, 'unlock') await call.bot.edit_message_reply_markup(chat_id=call.message.chat.id, message_id=call.message.message_id, reply_markup=keyboard)