Compare commits

...

3 commits

6 changed files with 37 additions and 22 deletions

View file

@ -53,7 +53,7 @@ class TelegramAdapter:
# link 模块 # link 模块
router.message(F.text.regexp(r'https?:\/\/(?:www\.)?([-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b)*(\/[\/\d\w\.-]*)*(?:[\?])*(.+)*'))(handle_links) router.message(F.text.regexp(r'https?:\/\/(?:www\.)?([-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b)*(\/[\/\d\w\.-]*)*(?:[\?])*(.+)*'))(handle_links)
# repeater 模块 # repeater 模块
router.message(F.text & (F.chat.type.in_({'group', 'supergroup'})))(MessageRepeater().handle_message) router.message(F.chat.type.in_({'group', 'supergroup'}))(MessageRepeater().handle_message)
# 捕获所有其他消息 # 捕获所有其他消息
router.message(F.chat.type.in_({'group', 'supergroup'}))(dummy_handler) router.message(F.chat.type.in_({'group', 'supergroup'}))(dummy_handler)
@ -79,7 +79,6 @@ class TelegramAdapter:
) )
await self.dp.start_polling(bot) await self.dp.start_polling(bot)
print(await bot.get_updates())
async def main() -> None: async def main() -> None:

View file

@ -7,17 +7,22 @@ async def handle_actions(message: Message) -> None:
if not config.is_feature_enabled('actions', message.chat.id): if not config.is_feature_enabled('actions', message.chat.id):
return return
rawtext = message.text rawtext = message.text
from_user = message.from_user.mention_html(message.sender_chat.title) if message.sender_chat else message.from_user.mention_html()
replied_user = message.from_user.mention_html(message.reply_to_message.sender_chat.title) if message.reply_to_message and message.reply_to_message.sender_chat else message.reply_to_message.from_user.mention_html()
# 防止识别成命令而被误触发 # 防止识别成命令而被误触发
if rawtext.replace('/','',1).isalpha() or '@' in rawtext: if rawtext.replace('/','',1).isascii() or '@' in rawtext:
print(rawtext.replace('/','',1).isascii())
return return
elif " " in message.text: elif " " in message.text:
if rawtext.split(" ")[0].replace('/','',1).isalpha(): if rawtext.split(" ")[0].replace('/','',1).isascii():
return return
await message.reply(f"{message.from_user.mention_html()} {rawtext.split(" ")[0].replace('/','')}{message.reply_to_message.from_user.mention_html() if message.reply_to_message else '自己' } {''.join(rawtext.split(" ")[1:])}",disable_web_page_preview=True) await message.reply(f"{from_user} {rawtext.split(" ")[0].replace('/','')}{replied_user if message.reply_to_message else '自己' } {''.join(rawtext.split(" ")[1:])}",disable_web_page_preview=True)
else: else:
await message.reply(f"{message.from_user.mention_html()} {message.text.replace('/','')}{message.reply_to_message.from_user.mention_html() if message.reply_to_message else '自己'}",disable_web_page_preview=True) await message.reply(f"{from_user} {message.text.replace('/','')}{replied_user if message.reply_to_message else '自己'}",disable_web_page_preview=True)
async def handle_reverse_actions(message: Message) -> None: async def handle_reverse_actions(message: Message) -> None:
from_user = message.from_user.mention_html(message.sender_chat.title) if message.sender_chat else message.from_user.mention_html()
replied_user = message.from_user.mention_html(message.reply_to_message.sender_chat.title) if message.reply_to_message and message.reply_to_message.sender_chat else message.reply_to_message.from_user.mention_html()
if not config.is_feature_enabled('actions', message.chat.id): if not config.is_feature_enabled('actions', message.chat.id):
return return
await message.reply(f"{message.from_user.mention_html()}{message.reply_to_message.from_user.mention_html()} {message.text.replace('\\','')}了!",disable_web_page_preview=True) await message.reply(f"{from_user}{replied_user if message.reply_to_message else '自己'} {message.text.replace('\\','')}了!",disable_web_page_preview=True)

View file

@ -28,10 +28,19 @@ class MessageStatsMiddleware(BaseMiddleware):
} }
if user_id not in self.stats[chat_id]['users']: if user_id not in self.stats[chat_id]['users']:
name = 'Unknown'
if event.sender_chat:
if event.sender_chat.type in ['group','supergroup']:
# 如果是频道/群组匿名管理员消息,使用频道名称
name = f"{event.sender_chat.title} [admin]"
# 如果是频道/群组匿名管理员消息,使用频道名称
name = f"{event.sender_chat.title} [channel]"
elif event.from_user:
name = event.from_user.full_name
self.stats[chat_id]['users'][user_id] = { self.stats[chat_id]['users'][user_id] = {
'message_count': 0, 'message_count': 0,
'username': event.from_user.username if event.from_user else 'Unknown', 'username': event.from_user.username if event.from_user else 'Unknown',
'first_name': event.from_user.first_name if event.from_user else 'Unknown' 'name': name
} }
# 更新统计 # 更新统计

View file

@ -10,32 +10,37 @@ class MessageRepeater:
self.message_counts = defaultdict(lambda: defaultdict(int)) self.message_counts = defaultdict(lambda: defaultdict(int))
self.repeated_messages = defaultdict(set) self.repeated_messages = defaultdict(set)
self.message_timestamps = defaultdict(lambda: defaultdict(float)) self.message_timestamps = defaultdict(lambda: defaultdict(float))
self.last_messages = defaultdict(str) # Track last message in each chat
self.expiry_seconds = message_expiry_seconds self.expiry_seconds = message_expiry_seconds
async def handle_message(self, message: aiogram.types.Message): async def handle_message(self, message: aiogram.types.Message):
"""Handle incoming messages and repeat when a threshold is met""" """Handle incoming messages and repeat when a threshold is met"""
chat_id = message.chat.id chat_id = message.chat.id
text = message.text content = ''
if message.text:
content = message.text
elif message.sticker:
content = message.sticker.file_id
if not config.is_feature_enabled('repeater', message.chat.id): if not config.is_feature_enabled('repeater', message.chat.id):
return return
if not text:
return
# Clean expired messages # Clean expired messages
self._clean_expired_messages(chat_id) self._clean_expired_messages(chat_id)
# Increment message count # Increment message count
self.message_counts[chat_id][text] += 1 self.message_counts[chat_id][content] += 1
self.message_timestamps[chat_id][text] = time.time() self.message_timestamps[chat_id][content] = time.time()
# If a message appears twice and hasn't been repeated yet # If a message appears twice and hasn't been repeated yet
if (self.message_counts[chat_id][text] >= 2 and if (content == self.last_messages[chat_id] and
text not in self.repeated_messages[chat_id]): self.message_counts[chat_id][content] >= 2 and
content not in self.repeated_messages[chat_id]):
# Mark as repeated and send the message # Mark as repeated and send the message
self.repeated_messages[chat_id].add(text) self.repeated_messages[chat_id].add(content)
await message.answer(text) await message.copy_to(chat_id)
self.last_messages[chat_id] = content
def _clean_expired_messages(self, chat_id: int): def _clean_expired_messages(self, chat_id: int):
"""Remove messages older than expiry_seconds""" """Remove messages older than expiry_seconds"""

View file

@ -18,8 +18,6 @@ async def handle_stats_command(message: Message):
except (FileNotFoundError, json.JSONDecodeError): except (FileNotFoundError, json.JSONDecodeError):
stats = {}.get(chat_id) stats = {}.get(chat_id)
print(stats)
if not stats: if not stats:
await message.reply("暂无统计数据") await message.reply("暂无统计数据")
return return
@ -38,7 +36,7 @@ async def handle_stats_command(message: Message):
text += "🏆 发言排行榜:\n" text += "🏆 发言排行榜:\n"
for i, (user_id, user_data) in enumerate(sorted_users[:10], 1): for i, (user_id, user_data) in enumerate(sorted_users[:10], 1):
name = user_data['first_name'] or user_data['username'] or str(user_id) name = user_data['name'] or user_data['username'] or str(user_id)
text += f"{i}. {name}: {user_data['message_count']}\n" text += f"{i}. {name}: {user_data['message_count']}\n"
await message.reply(text) await message.reply(text)

View file

@ -9,7 +9,6 @@ async def handle_unpin_channel_message(message: Message):
return return
try: try:
regex_pattern = config.get_feature_config('unpin', message.chat.id)['regex'] regex_pattern = config.get_feature_config('unpin', message.chat.id)['regex']
print(regex_pattern)
# If a regex pattern exists, check if the message matches # If a regex pattern exists, check if the message matches
if regex_pattern: if regex_pattern:
import re import re