bot/core/repeater.py

64 lines
No EOL
2.5 KiB
Python

import aiogram.types
from collections import defaultdict
import time
from config import config
class MessageRepeater:
def __init__(self, message_expiry_seconds=3600): # 1 hour default
self.message_counts = defaultdict(lambda: defaultdict(int))
self.repeated_messages = defaultdict(set)
self.message_timestamps = defaultdict(lambda: defaultdict(float))
self.last_messages = defaultdict(str) # Track last message in each chat
self.expiry_seconds = message_expiry_seconds
async def handle_message(self, message: aiogram.types.Message):
"""Handle incoming messages and repeat when a threshold is met"""
chat_id = message.chat.id
if message.text:
content = message.text
elif message.sticker:
content = message.sticker.file_id
elif message.photo:
content = message.photo[0].file_id
else:
return
if not config.is_feature_enabled('repeater', message.chat.id):
return
# Clean expired messages
self._clean_expired_messages(chat_id)
# Increment message count
self.message_counts[chat_id][content] += 1
self.message_timestamps[chat_id][content] = time.time()
# If a message appears twice and hasn't been repeated yet
if (content == self.last_messages[chat_id] and
self.message_counts[chat_id][content] >= 2 and
content not in self.repeated_messages[chat_id]):
# Mark as repeated and send the message
self.repeated_messages[chat_id].add(content)
# if the message replies to another message, copy it with the reply_to_message_id
if message.reply_to_message:
await message.copy_to(chat_id, reply_to_message_id=message.reply_to_message.message_id)
else:
await message.copy_to(chat_id)
self.last_messages[chat_id] = content
def _clean_expired_messages(self, chat_id: int):
"""Remove messages older than expiry_seconds"""
current_time = time.time()
expired_messages = []
for text, timestamp in self.message_timestamps[chat_id].items():
if current_time - timestamp > self.expiry_seconds:
expired_messages.append(text)
for text in expired_messages:
del self.message_counts[chat_id][text]
del self.message_timestamps[chat_id][text]
self.repeated_messages[chat_id].discard(text)