Files
telegram-helper-bot/helper_bot/handlers/callback/callback_handlers.py
2024-10-31 21:58:46 +03:00

282 lines
17 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 BaseDependencyFactory
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 = BaseDependencyFactory()
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()
await call.message.answer(
text=f"<b>Выбран пользователь:\nid:</b> {user_id}\n<b>username:</b> {user_name}\nИмя:{call.message.from_user.full_name}\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)
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)
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()
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)