Compare commits
No commits in common. "26e526d12476c7d5782a39629b6c53b227c276fb" and "359f3aee88bc3b2f008c6882c7a138ad2ff43147" have entirely different histories.
26e526d124
...
359f3aee88
6 changed files with 22 additions and 37 deletions
|
@ -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.chat.type.in_({'group', 'supergroup'}))(MessageRepeater().handle_message)
|
router.message(F.text & (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,6 +79,7 @@ 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:
|
||||||
|
|
|
@ -7,22 +7,17 @@ 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).isascii() or '@' in rawtext:
|
if rawtext.replace('/','',1).isalpha() or '@' in rawtext:
|
||||||
print(rawtext.replace('/','',1).isascii())
|
|
||||||
return
|
return
|
||||||
elif " " in message.text:
|
elif " " in message.text:
|
||||||
if rawtext.split(" ")[0].replace('/','',1).isascii():
|
if rawtext.split(" ")[0].replace('/','',1).isalpha():
|
||||||
return
|
return
|
||||||
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)
|
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)
|
||||||
else:
|
else:
|
||||||
await message.reply(f"{from_user} {message.text.replace('/','')}了 {replied_user if message.reply_to_message else '自己'}!",disable_web_page_preview=True)
|
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)
|
||||||
|
|
||||||
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"{from_user} 被 {replied_user if message.reply_to_message else '自己'} {message.text.replace('\\','')}了!",disable_web_page_preview=True)
|
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)
|
|
@ -28,19 +28,10 @@ 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',
|
||||||
'name': name
|
'first_name': event.from_user.first_name if event.from_user else 'Unknown'
|
||||||
}
|
}
|
||||||
|
|
||||||
# 更新统计
|
# 更新统计
|
||||||
|
|
|
@ -10,37 +10,32 @@ 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
|
||||||
content = ''
|
text = message.text
|
||||||
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][content] += 1
|
self.message_counts[chat_id][text] += 1
|
||||||
self.message_timestamps[chat_id][content] = time.time()
|
self.message_timestamps[chat_id][text] = 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 (content == self.last_messages[chat_id] and
|
if (self.message_counts[chat_id][text] >= 2 and
|
||||||
self.message_counts[chat_id][content] >= 2 and
|
text not in self.repeated_messages[chat_id]):
|
||||||
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(content)
|
self.repeated_messages[chat_id].add(text)
|
||||||
await message.copy_to(chat_id)
|
await message.answer(text)
|
||||||
|
|
||||||
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"""
|
||||||
|
|
|
@ -18,6 +18,8 @@ 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
|
||||||
|
@ -36,7 +38,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['name'] or user_data['username'] or str(user_id)
|
name = user_data['first_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)
|
|
@ -9,6 +9,7 @@ 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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue