forked from Muzifs/LGBot
92 lines
4.9 KiB
Python
92 lines
4.9 KiB
Python
from telebot.async_telebot import AsyncTeleBot
|
||
from telebot.types import Message
|
||
import asyncio
|
||
import logging
|
||
|
||
from database import db
|
||
from thank_words import contains_thank_word
|
||
from bad_words import contains_bad_word
|
||
from config import THANK_COOLDOWN
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
def register_handlers(bot: AsyncTeleBot):
|
||
"""Регистрирует обработчики для отслеживания благодарностей"""
|
||
logger.info("Регистрация обработчика благодарностей (karma_tracker)")
|
||
|
||
@bot.message_handler(func=lambda message: message.reply_to_message is not None and message.text and not message.text.startswith('/'))
|
||
async def handle_thank_message(message: Message):
|
||
"""
|
||
Обрабатывает сообщения, которые являются ответами на другие сообщения.
|
||
Если сообщение содержит благодарность, начисляет карму автору оригинального сообщения.
|
||
"""
|
||
try:
|
||
logger.info(f"[KARMA] Получено reply-сообщение: {message.text[:50]}")
|
||
|
||
# Проверяем, что это групповой чат
|
||
if message.chat.type not in ['group', 'supergroup']:
|
||
logger.info(f"[KARMA] Пропуск - не групповой чат: {message.chat.type}")
|
||
return
|
||
|
||
# Проверяем наличие благодарственных слов
|
||
if not contains_thank_word(message.text):
|
||
logger.info(f"[KARMA] Нет слов благодарности в: {message.text[:50]}")
|
||
return
|
||
|
||
logger.info(f"[KARMA] Обнаружена благодарность от {message.from_user.id}: {message.text[:50]}")
|
||
|
||
# Проверяем, что в сообщении нет мата (не начисляем карму за мат)
|
||
if contains_bad_word(message.text):
|
||
logger.info(f"Пользователь {message.from_user.id} написал благодарность с матом - карма не начислена")
|
||
return
|
||
|
||
from_user = message.from_user
|
||
to_user = message.reply_to_message.from_user
|
||
chat_id = message.chat.id
|
||
|
||
# Защита от самоблагодарности
|
||
if from_user.id == to_user.id:
|
||
logger.info(f"Пользователь {from_user.id} попытался поблагодарить сам себя")
|
||
return
|
||
|
||
# Проверяем, не является ли благодарность ботам
|
||
if to_user.is_bot:
|
||
logger.info(f"Пользователь {from_user.id} попытался поблагодарить бота")
|
||
return
|
||
|
||
# Атомарно проверяем кулдаун и записываем благодарность
|
||
# Это предотвращает race condition при параллельных запросах
|
||
if not db.try_add_karma_thank(from_user.id, to_user.id, chat_id, THANK_COOLDOWN):
|
||
logger.info(f"Пользователь {from_user.id} уже благодарил {to_user.id} недавно")
|
||
# Молча игнорируем, чтобы не спамить
|
||
return
|
||
|
||
# Начисляем карму (благодарность уже записана атомарно выше)
|
||
db.add_karma(to_user.id, chat_id, 1)
|
||
|
||
# Получаем новую карму пользователя
|
||
new_karma = db.get_karma(to_user.id, chat_id)
|
||
|
||
# Формируем имя пользователя для отображения
|
||
to_user_name = to_user.first_name
|
||
if to_user.username:
|
||
to_user_display = f"@{to_user.username}"
|
||
else:
|
||
to_user_display = to_user_name
|
||
|
||
# Отправляем уведомление
|
||
response = f"👍 Карма пользователя {to_user_display} увеличена! Текущая карма: {new_karma}"
|
||
|
||
sent_message = await bot.reply_to(message, response)
|
||
|
||
logger.info(f"Пользователь {from_user.id} поблагодарил {to_user.id}, карма: {new_karma}")
|
||
|
||
# Удаляем уведомление через 5 секунд
|
||
await asyncio.sleep(5)
|
||
try:
|
||
await bot.delete_message(chat_id, sent_message.message_id)
|
||
except Exception as e:
|
||
logger.error(f"Не удалось удалить уведомление о карме: {e}")
|
||
|
||
except Exception as e:
|
||
logger.error(f"Ошибка при обработке благодарности: {e}", exc_info=True) |