PagerMaid_Plugins_Pyro/clean_member/main.py
2023-07-01 20:18:58 +08:00

146 lines
5.4 KiB
Python

import contextlib
from asyncio import sleep
from random import uniform
from pyrogram.enums import ChatMemberStatus
from pyrogram import filters
from pyrogram.errors import (
ChatAdminRequired,
FloodWait,
UserAdminInvalid,
PeerIdInvalid,
BadRequest,
)
from datetime import datetime, timedelta
from pagermaid.listener import listener
from pagermaid.enums import Message, Client
from pagermaid.services import bot
async def check_self_and_from(message: Message):
cid = message.chat.id
data = await bot.get_chat_member(cid, (await bot.get_me()).id)
if data.status not in [ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.OWNER]:
return False
if not message.from_user:
return False
if message.outgoing:
return True
data = await bot.get_chat_member(cid, message.from_user.id)
return data.status in [ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.OWNER]
async def kick_chat_member(cid, uid, only_search: bool = False):
if only_search:
return
try:
with contextlib.suppress(UserAdminInvalid, PeerIdInvalid, BadRequest):
await bot.ban_chat_member(cid, uid, datetime.now() + timedelta(minutes=5))
except FloodWait as e:
await sleep(e.value + uniform(0.5, 1.0))
await kick_chat_member(cid, uid, only_search)
async def process_clean_member(
message: Message, mode: str, day: int, only_search: bool = False
):
member_count = 0
try:
async for member in bot.get_chat_members(message.chat.id):
if (
mode == "1"
and member.user.last_online_date
and member.user.last_online_date < datetime.now() - timedelta(days=day)
):
member_count += 1
await kick_chat_member(message.chat.id, member.user.id, only_search)
if mode == "2":
now = datetime.now() - timedelta(days=day)
async for message in bot.search_messages(
message.chat.id, limit=1, from_user=member.user.id
):
if message.date < now:
member_count += 1
await kick_chat_member(
message.chat.id, member.user.id, only_search
)
elif mode == "3":
try:
count = await bot.search_messages_count(
message.chat.id, from_user=member.user.id
)
except PeerIdInvalid:
continue
if count < day:
member_count += 1
await kick_chat_member(message.chat.id, member.user.id, only_search)
if mode == "4" and member.user.is_deleted:
member_count += 1
await kick_chat_member(message.chat.id, member.user.id, only_search)
if mode == "5":
member_count += 1
await kick_chat_member(message.chat.id, member.user.id, only_search)
if not only_search:
await message.edit(f"成功清理了 `{member_count}` 人。")
else:
await message.edit(f"查找到了 `{member_count}` 人。")
except ChatAdminRequired:
await message.edit("你好像并不拥有封禁用户权限。")
except FloodWait:
return await message.edit("处理失败,您已受到 TG 服务器限制。")
@listener(
command="clean_member", need_admin=True, groups_only=True, description="多种方式清理群成员"
)
async def clean_member(client: Client, message: Message):
if not await check_self_and_from(message):
return await message.edit("您不是群管理员,无法使用此命令")
uid = message.from_user.id
mode, day = "0", 0
reply = await message.edit(
"请选择清理模式:\n\n"
"1. 按未上线时间清理\n"
"2. 按未发言时间清理(大群慎用)\n"
"3. 按发言数清理\n"
"4. 清理死号\n"
"5. 清理所有人(大群慎用)"
)
try:
async with client.conversation(
message.chat.id, filters=filters.user(uid)
) as conv:
await sleep(1)
res: Message = await conv.get_response()
mode = res.text
await res.safe_delete()
if mode in ["1", "2"]:
await res.safe_delete()
await reply.edit("请输入清理天数:")
await sleep(1)
res = await conv.get_response()
day = max(int(res.text), 7)
await res.safe_delete()
elif mode == "3":
await res.safe_delete()
await reply.edit("清理发言少于多少条的群成员:")
await sleep(1)
res = await conv.get_response()
day = int(res.text)
await res.safe_delete()
elif mode == "4":
pass
elif mode != "5":
raise ValueError("清理模式错误")
await reply.edit("查找还是清理?")
await sleep(1)
res = await conv.get_response()
only_search = res.text == "查找"
await res.safe_delete()
except ValueError as e:
return await reply.edit(f"{e}")
await reply.edit("遍历成员中。。。")
await process_clean_member(reply, mode, day, only_search)