refa: clean verify user message

This commit is contained in:
xtaodada 2024-08-07 23:33:57 +08:00
parent 4f0607c034
commit f1f10b454a
Signed by: xtaodada
GPG Key ID: 4CBB3F4FA8C85659
14 changed files with 190 additions and 396 deletions

View File

@ -1,5 +1,4 @@
import contextlib import contextlib
from datetime import datetime, timedelta
from cashews import cache from cashews import cache
from pyrogram import filters from pyrogram import filters
@ -8,17 +7,45 @@ from pyrogram.types import ChatMemberUpdated
from pyromod.utils.errors import TimeoutConversationError from pyromod.utils.errors import TimeoutConversationError
from sticker.languages import MSG_PUBLIC, ADMIN_MSG, MSG, VERIFY_TIME from sticker.languages import MSG_PUBLIC, ADMIN_MSG, MSG, VERIFY_TIME
from sticker.scheduler import add_delete_message_job from sticker.scheduler import add_ban_chat_member_job
from sticker.service_message import ServiceMessage from sticker.service_message import ServiceMessage
from sticker.single_utils import Client from sticker.single_utils import Client, Message
from sticker import bot, log from sticker import bot, log, LogAction
async def start_verify(client: "Client", chat, user):
key = f"wait:{chat.id}:{user.id}"
await cache.set(key, "True", expire=VERIFY_TIME + 5)
try:
msg: "Message" = await client.send_message(
chat.id, MSG % (user.mention, user.mention)
)
except Exception:
return
await log(chat, user, LogAction.REQUEST)
try:
msg_: "Message" = await client.listen(
chat.id, filters=filters.user(user.id), timeout=VERIFY_TIME
)
await msg.delay_delete(1)
await msg_.delay_delete(1)
if not msg_.sticker:
add_ban_chat_member_job(chat.id, user.id)
await log(chat, user, LogAction.FAIL_ERROR)
await ServiceMessage.try_delete(user.id, chat.id)
else:
await cache.delete(key)
await log(chat, user, LogAction.ACCEPT)
except TimeoutConversationError:
await msg.delay_delete(1)
add_ban_chat_member_job(chat.id, user.id)
await log(chat, user, LogAction.FAIL_TIMEOUT)
await ServiceMessage.try_delete(user.id, chat.id)
@bot.on_chat_member_updated() @bot.on_chat_member_updated()
async def invite(client: Client, chat_member_updated: ChatMemberUpdated): async def invite(client: Client, chat_member_updated: ChatMemberUpdated):
chat = chat_member_updated.chat chat = chat_member_updated.chat
if await cache.get(f"cid:{chat.id}"):
return
member = chat_member_updated.new_chat_member member = chat_member_updated.new_chat_member
old_member = chat_member_updated.old_chat_member old_member = chat_member_updated.old_chat_member
if not member: if not member:
@ -27,6 +54,17 @@ async def invite(client: Client, chat_member_updated: ChatMemberUpdated):
return return
user = member.user user = member.user
old_user = old_member.user if old_member else None old_user = old_member.user if old_member else None
if user.is_self:
if member.status not in {
ChatMemberStatus.ADMINISTRATOR,
ChatMemberStatus.MEMBER,
}:
return
await log(chat, chat_member_updated.from_user, LogAction.NEW_GROUP)
if chat.username:
with contextlib.suppress(Exception):
await client.send_message(chat.id, MSG_PUBLIC)
return
if user.is_verified or user.is_bot or user.is_deleted or user.is_support: if user.is_verified or user.is_bot or user.is_deleted or user.is_support:
return return
if member.status not in {ChatMemberStatus.MEMBER}: if member.status not in {ChatMemberStatus.MEMBER}:
@ -43,13 +81,6 @@ async def invite(client: Client, chat_member_updated: ChatMemberUpdated):
} }
): ):
return return
if user.is_self:
with contextlib.suppress(Exception):
await log(chat, chat_member_updated.from_user, "NEW_GROUP")
if chat.username:
with contextlib.suppress(Exception):
await client.send_message(chat.id, MSG_PUBLIC)
return
from_user = chat_member_updated.from_user from_user = chat_member_updated.from_user
if from_user and from_user.id == user.id: if from_user and from_user.id == user.id:
from_user = None from_user = None
@ -61,42 +92,8 @@ async def invite(client: Client, chat_member_updated: ChatMemberUpdated):
and (await bot.get_chat_member(chat.id, from_user.id)).status and (await bot.get_chat_member(chat.id, from_user.id)).status
in {ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.OWNER} in {ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.OWNER}
): ):
try: with contextlib.suppress(Exception):
msg = await client.send_message(chat.id, ADMIN_MSG) msg: "Message" = await client.send_message(chat.id, ADMIN_MSG)
except Exception: await msg.delay_delete()
return return
add_delete_message_job(msg) await start_verify(client, chat, user)
return
try:
msg = await client.send_message(chat.id, MSG % (user.mention, user.mention))
except Exception:
return
try:
with contextlib.suppress(Exception):
await log(chat, user, "REQUEST")
msg_ = await client.listen(chat.id, filters=filters.user(user.id), timeout=VERIFY_TIME)
with contextlib.suppress(Exception):
await msg.delete()
if not msg_.sticker:
with contextlib.suppress(Exception):
await bot.ban_chat_member(
chat.id, user.id, datetime.now() + timedelta(minutes=5)
)
with contextlib.suppress(Exception):
await log(chat, user, "FAIL_ERROR")
await ServiceMessage.try_delete(user.id, chat.id)
else:
with contextlib.suppress(Exception):
await log(chat, user, "ACCEPT")
with contextlib.suppress(Exception):
await msg_.delete()
except TimeoutConversationError:
with contextlib.suppress(Exception):
await msg.delete()
with contextlib.suppress(Exception):
await bot.ban_chat_member(
chat.id, user.id, datetime.now() + timedelta(minutes=5)
)
with contextlib.suppress(Exception):
await log(chat, user, "FAIL_TIMEOUT")
await ServiceMessage.try_delete(user.id, chat.id)

17
plugins/clean_message.py Normal file
View File

@ -0,0 +1,17 @@
from cashews import cache
from pyrogram import filters
from sticker import bot
from sticker.single_utils import Message
@bot.on_message(filters=filters.group & ~filters.service, group=1)
async def clean_message(_, message: "Message"):
if not message.from_user:
return
cid = message.chat.id
uid = message.from_user.id
key = f"wait:{cid}:{uid}"
result = await cache.get(key)
if result:
await message.delay_delete(1)

View File

@ -1,13 +1,12 @@
import contextlib import contextlib
from cashews import cache
from pyrogram.types import ChatJoinRequest from pyrogram.types import ChatJoinRequest
from pyrogram import filters from pyrogram import filters
from sticker.languages import MSG, MSG_SUCCESS, MSG_FAILURE, VERIFY_TIME from sticker.languages import MSG, MSG_SUCCESS, MSG_FAILURE, VERIFY_TIME
from sticker.single_utils import Client from sticker.single_utils import Client
from sticker.scheduler import add_decline_request_job, rem_decline_request_job from sticker.scheduler import add_decline_request_job, rem_decline_request_job
from sticker import bot, log from sticker import bot, log, LogAction
from pyromod.utils.errors import TimeoutConversationError from pyromod.utils.errors import TimeoutConversationError
@ -15,24 +14,24 @@ from pyromod.utils.errors import TimeoutConversationError
@bot.on_chat_join_request() @bot.on_chat_join_request()
async def new_member(client: Client, chat_join_request: ChatJoinRequest): async def new_member(client: Client, chat_join_request: ChatJoinRequest):
chat = chat_join_request.chat chat = chat_join_request.chat
await cache.set(f"cid:{chat.id}", "True", expire=3600, exist=True)
user = chat_join_request.from_user user = chat_join_request.from_user
add_decline_request_job(chat_join_request) add_decline_request_job(chat_join_request)
try: try:
with contextlib.suppress(Exception): await log(chat, user, LogAction.REQUEST)
await log(chat, user, "REQUEST") await client.ask(
await client.ask(user.id, MSG % (chat.title, chat.title), filters=filters.sticker, timeout=VERIFY_TIME) user.id,
MSG % (chat.title, chat.title),
filters=filters.sticker,
timeout=VERIFY_TIME,
)
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
await client.send_message(user.id, MSG_SUCCESS) await client.send_message(user.id, MSG_SUCCESS)
await chat_join_request.approve() await chat_join_request.approve()
with contextlib.suppress(Exception): await log(chat, user, LogAction.ACCEPT)
await log(chat, user, "ACCEPT")
with contextlib.suppress(Exception):
rem_decline_request_job(chat_join_request) rem_decline_request_job(chat_join_request)
except TimeoutConversationError: except TimeoutConversationError:
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
await client.send_message(user.id, MSG_FAILURE) await client.send_message(user.id, MSG_FAILURE)
with contextlib.suppress(Exception): with contextlib.suppress(Exception):
await chat_join_request.decline() await chat_join_request.decline()
with contextlib.suppress(Exception): await log(chat, user, LogAction.FAIL_TIMEOUT)
await log(chat, user, "FAIL_TIMEOUT")

View File

@ -1,25 +1,23 @@
import contextlib from cashews import cache
from pyrogram import filters from pyrogram import filters
from pyrogram.enums import ChatMemberStatus from pyrogram.enums import ChatMemberStatus
from datetime import datetime, timedelta
from pyromod.utils.errors import TimeoutConversationError from pyromod.utils.errors import TimeoutConversationError
from sticker.languages import RE_MSG, VERIFY_TIME from sticker.languages import RE_MSG, VERIFY_TIME
from sticker.scheduler import add_delete_message_job from sticker.scheduler import add_ban_chat_member_job
from sticker.single_utils import Message, Client from sticker.single_utils import Message, Client
from sticker import bot, log from sticker import bot, log, LogAction
@bot.on_message(filters=filters.group & filters.command("reverify")) @bot.on_message(filters=filters.group & filters.command("reverify"))
async def re_verify(client: Client, message: Message): async def re_verify(client: Client, message: Message):
if not message.from_user or not message.reply_to_message: reply_to: "Message" = message.reply_to_message
if not message.from_user or not reply_to:
msg: Message = await message.reply("请回复一条消息来使 Ta 重新验证。") msg: Message = await message.reply("请回复一条消息来使 Ta 重新验证。")
add_delete_message_job(message, 10) await message.delay_delete(10)
add_delete_message_job(msg, 10) await msg.delay_delete(10)
return return
if not message.reply_to_message.from_user: if not reply_to.from_user:
return return
chat = message.chat chat = message.chat
user = message.from_user user = message.from_user
@ -27,7 +25,7 @@ async def re_verify(client: Client, message: Message):
if member.status not in [ChatMemberStatus.OWNER, ChatMemberStatus.ADMINISTRATOR]: if member.status not in [ChatMemberStatus.OWNER, ChatMemberStatus.ADMINISTRATOR]:
return return
user = message.reply_to_message.from_user user = reply_to.from_user
if ( if (
user.is_self user.is_self
or user.is_verified or user.is_verified
@ -37,46 +35,36 @@ async def re_verify(client: Client, message: Message):
): ):
return return
member = await client.get_chat_member(chat.id, user.id) member = await client.get_chat_member(chat.id, user.id)
with contextlib.suppress(Exception): await message.delay_delete(1)
await message.delete() key = f"wait:{chat.id}:{user.id}"
await cache.set(key, "True", expire=VERIFY_TIME + 5)
try: try:
msg = await message.reply_to_message.reply(RE_MSG % (user.mention, user.mention)) msg = await reply_to.reply(RE_MSG % (user.mention, user.mention))
except Exception as _: except Exception as _:
return return
try: try:
msg_ = await client.listen(chat.id, filters=filters.user(user.id), timeout=VERIFY_TIME) msg_ = await client.listen(
with contextlib.suppress(Exception): chat.id, filters=filters.user(user.id), timeout=VERIFY_TIME
await msg.delete() )
await msg.delay_delete(1)
await msg_.delay_delete(1)
if not msg_.sticker: if not msg_.sticker:
with contextlib.suppress(Exception): await reply_to.delay_delete(1)
await message.reply_to_message.delete()
if member.status not in [ if member.status not in [
ChatMemberStatus.OWNER, ChatMemberStatus.OWNER,
ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.ADMINISTRATOR,
]: ]:
with contextlib.suppress(Exception): add_ban_chat_member_job(chat.id, user.id)
await bot.ban_chat_member( await log(chat, user, LogAction.FAIL_ERROR)
chat.id, user.id, datetime.now() + timedelta(minutes=5)
)
with contextlib.suppress(Exception):
await log(chat, user, "FAIL_ERROR")
else: else:
with contextlib.suppress(Exception): await cache.delete(key)
await log(chat, user, "ACCEPT") await log(chat, user, LogAction.ACCEPT)
with contextlib.suppress(Exception):
await msg_.delete()
except TimeoutConversationError: except TimeoutConversationError:
with contextlib.suppress(Exception): await msg.delay_delete(1)
await msg.delete() await reply_to.delay_delete(1)
with contextlib.suppress(Exception):
await message.reply_to_message.delete()
if member.status not in [ if member.status not in [
ChatMemberStatus.OWNER, ChatMemberStatus.OWNER,
ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.ADMINISTRATOR,
]: ]:
with contextlib.suppress(Exception): add_ban_chat_member_job(chat.id, user.id)
await bot.ban_chat_member( await log(chat, user, LogAction.FAIL_TIMEOUT)
chat.id, user.id, datetime.now() + timedelta(minutes=5)
)
with contextlib.suppress(Exception):
await log(chat, user, "FAIL_TIMEOUT")

View File

@ -1,21 +0,0 @@
"""
pyromod - A monkeypatcher add-on for Pyrogram
Copyright (C) 2020 Cezar H. <https://github.com/usernein>
This file is part of pyromod.
pyromod is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
pyromod is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with pyromod. If not, see <https://www.gnu.org/licenses/>.
"""
from .filters import dice

View File

@ -1,28 +0,0 @@
"""
pyromod - A monkeypatcher add-on for Pyrogram
Copyright (C) 2020 Cezar H. <https://github.com/usernein>
This file is part of pyromod.
pyromod is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
pyromod is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with pyromod. If not, see <https://www.gnu.org/licenses/>.
"""
import pyrogram
def dice(ctx, message):
return hasattr(message, "dice") and message.dice
pyrogram.filters.dice = dice

View File

@ -1,20 +0,0 @@
"""
pyromod - A monkeypatcher add-on for Pyrogram
Copyright (C) 2020 Cezar H. <https://github.com/usernein>
This file is part of pyromod.
pyromod is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
pyromod is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with pyromod. If not, see <https://www.gnu.org/licenses/>.
"""
from .helpers import ikb, bki, ntb, btn, kb, kbtn, array_chunk, force_reply

View File

@ -1,86 +0,0 @@
from pyrogram.types import (
InlineKeyboardButton,
InlineKeyboardMarkup,
KeyboardButton,
ReplyKeyboardMarkup,
ForceReply,
)
def ikb(rows=None):
if rows is None:
rows = []
lines = []
for row in rows:
line = []
for button in row:
button = btn(*button) # InlineKeyboardButton
line.append(button)
lines.append(line)
return InlineKeyboardMarkup(inline_keyboard=lines)
# return {'inline_keyboard': lines}
def btn(text, value, type="callback_data"):
return InlineKeyboardButton(text, **{type: value})
# return {'text': text, type: value}
# The inverse of above
def bki(keyboard):
lines = []
for row in keyboard.inline_keyboard:
line = []
for button in row:
button = ntb(button) # btn() format
line.append(button)
lines.append(line)
return lines
# return ikb() format
def ntb(button):
for btn_type in [
"callback_data",
"url",
"switch_inline_query",
"switch_inline_query_current_chat",
"callback_game",
]:
value = getattr(button, btn_type)
if value:
break
button = [button.text, value]
if btn_type != "callback_data":
button.append(btn_type)
return button
# return {'text': text, type: value}
def kb(rows=None, **kwargs):
if rows is None:
rows = []
lines = []
for row in rows:
line = []
for button in row:
button_type = type(button)
if button_type == str:
button = KeyboardButton(button)
elif button_type == dict:
button = KeyboardButton(**button)
line.append(button)
lines.append(line)
return ReplyKeyboardMarkup(keyboard=lines, **kwargs)
kbtn = KeyboardButton
def force_reply(selective=True):
return ForceReply(selective=selective)
def array_chunk(input_, size):
return [input_[i : i + size] for i in range(0, len(input_), size)]

View File

@ -19,16 +19,18 @@ along with pyromod. If not, see <https://www.gnu.org/licenses/>.
""" """
import asyncio import asyncio
import contextlib
import functools import functools
import pyrogram import pyrogram
from typing import Dict
from sticker.scheduler import add_delete_message_job from sticker.scheduler import add_delete_message_job
from ..utils import patch, patchable from ..utils import patch, patchable
from ..utils.errors import ListenerCanceled, TimeoutConversationError from ..utils.errors import ListenerCanceled, TimeoutConversationError
pyrogram.errors.ListenerCanceled = ListenerCanceled pyrogram.errors.ListenerCanceled = ListenerCanceled
LOCK = asyncio.Lock()
DONE = []
@patch(pyrogram.client.Client) @patch(pyrogram.client.Client)
@ -63,6 +65,7 @@ class Client:
@patchable @patchable
def clear_listener(self, chat_id, future): def clear_listener(self, chat_id, future):
with contextlib.suppress(KeyError):
if future == self.listening[chat_id]["future"]: if future == self.listening[chat_id]["future"]:
self.listening.pop(chat_id, None) self.listening.pop(chat_id, None)
@ -90,25 +93,33 @@ class MessageHandler:
@patchable @patchable
async def resolve_listener(self, client, message, *args): async def resolve_listener(self, client, message, *args):
global LOCK, DONE
async with LOCK:
listener = client.listening.get(message.chat.id) listener = client.listening.get(message.chat.id)
if listener:
with contextlib.suppress(ValueError):
DONE.remove(listener)
if listener and not listener["future"].done(): if listener and not listener["future"].done():
listener["future"].set_result(message) listener["future"].set_result(message)
else: return
if listener and listener["future"].done(): if listener and listener["future"].done():
client.clear_listener(message.chat.id, listener["future"]) client.clear_listener(message.chat.id, listener["future"])
await self.user_callback(client, message, *args) await self.user_callback(client, message, *args)
@patchable @patchable
async def check(self, client, update): async def check(self, client, update):
global LOCK, DONE
async with LOCK:
listener = client.listening.get(update.chat.id) listener = client.listening.get(update.chat.id)
if listener and (listener not in DONE) and (not listener["future"].done()):
if listener and not listener["future"].done(): if callable(listener["filters"]):
return ( result = await listener["filters"](client, update)
await listener["filters"](client, update) if result:
if callable(listener["filters"]) DONE.append(listener)
else True return result
) else:
DONE.append(listener)
return True
return await self.filters(client, update) if callable(self.filters) else True return await self.filters(client, update) if callable(self.filters) else True

View File

@ -1,20 +0,0 @@
"""
pyromod - A monkeypatcher add-on for Pyrogram
Copyright (C) 2020 Cezar H. <https://github.com/usernein>
This file is part of pyromod.
pyromod is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
pyromod is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with pyromod. If not, see <https://www.gnu.org/licenses/>.
"""
from .pagination import Pagination

View File

@ -1,93 +0,0 @@
"""
pyromod - A monkeypatcher add-on for Pyrogram
Copyright (C) 2020 Cezar H. <https://github.com/usernein>
This file is part of pyromod.
pyromod is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
pyromod is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with pyromod. If not, see <https://www.gnu.org/licenses/>.
"""
import math
from ..helpers import array_chunk
class Pagination:
def __init__(self, objects, page_data=None, item_data=None, item_title=None):
default_page_callback = lambda x: str(x)
default_item_callback = lambda i, pg: f"[{pg}] {i}"
self.objects = objects
self.page_data = page_data or default_page_callback
self.item_data = item_data or default_item_callback
self.item_title = item_title or default_item_callback
def create(self, page, lines=5, columns=1):
quant_per_page = lines * columns
page = 1 if page <= 0 else page
offset = (page - 1) * quant_per_page
stop = offset + quant_per_page
cutted = self.objects[offset:stop]
total = len(self.objects)
pages_range = [
*range(1, math.ceil(total / quant_per_page) + 1)
] # each item is a page
last_page = len(pages_range)
nav = []
if page <= 3:
for n in [1, 2, 3]:
if n not in pages_range:
continue
text = f"· {n} ·" if n == page else n
nav.append((text, self.page_data(n)))
if last_page >= 4:
nav.append(("4 " if last_page > 5 else 4, self.page_data(4)))
if last_page > 4:
nav.append(
(
f"{last_page} »" if last_page > 5 else last_page,
self.page_data(last_page),
)
)
elif page >= last_page - 2:
nav.extend(
[
("« 1" if last_page > 5 else 1, self.page_data(1)),
(
f" {last_page - 3}" if last_page > 5 else last_page - 3,
self.page_data(last_page - 3),
),
]
)
for n in range(last_page - 2, last_page + 1):
text = f"· {n} ·" if n == page else n
nav.append((text, self.page_data(n)))
else:
nav = [
("« 1", self.page_data(1)),
(f" {page - 1}", self.page_data(page - 1)),
(f"· {page} ·", "noop"),
(f"{page + 1} ", self.page_data(page + 1)),
(f"{last_page} »", self.page_data(last_page)),
]
buttons = [
(self.item_title(item, page), self.item_data(item, page)) for item in cutted
]
kb_lines = array_chunk(buttons, columns)
if last_page > 1:
kb_lines.append(nav)
return kb_lines

View File

@ -1,5 +1,7 @@
import contextlib import contextlib
import sys import sys
from enum import Enum
from cashews import cache from cashews import cache
from datetime import datetime, timezone from datetime import datetime, timezone
from logging import getLogger, StreamHandler, CRITICAL, INFO, basicConfig, DEBUG from logging import getLogger, StreamHandler, CRITICAL, INFO, basicConfig, DEBUG
@ -54,22 +56,48 @@ bot = Client(
) )
async def log(chat, user, action): class LogAction(str, Enum):
FAIL_ERROR = "FAIL_ERROR"
FAIL_TIMEOUT = "FAIL_TIMEOUT"
ACCEPT = "ACCEPT"
NEW_GROUP = "NEW_GROUP"
REQUEST = "REQUEST"
async def log(chat, user, action: LogAction):
scheduler.add_job(
_log,
args=[chat, user, action],
replace_existing=False,
)
async def _log(chat, user, action: LogAction):
if not Config.LOG_CHANNEL: if not Config.LOG_CHANNEL:
return return
me = await bot.get_me() me = await bot.get_me()
event = { event = {
"FAIL_ERROR": "回答错误", LogAction.FAIL_ERROR: "回答错误",
"FAIL_TIMEOUT": "回答超时", LogAction.FAIL_TIMEOUT: "回答超时",
"ACCEPT": "通过验证", LogAction.ACCEPT: "通过验证",
"NEW_GROUP": "加入群组", LogAction.NEW_GROUP: "加入群组",
"REQUEST": "发起验证", LogAction.REQUEST: "发起验证",
} }
msg = """#%s msg = """#%s
群组: %s 群组: %s
群组id: <code>%s</code> 群组id: <code>%s</code>
用户: #id%s 用户: #id%s
昵称<code>%s</code>
OPBot: #bot%s OPBot: #bot%s
事件: %s""" 事件: %s"""
msg %= (action, chat.title, chat.id, user.id if user else "", me.id, event[action]) user_name = user.full_name if user else ""
msg %= (
action.value,
chat.title,
chat.id,
user.id if user else "",
user_name,
me.id,
event[action],
)
await bot.send_message(Config.LOG_CHANNEL, msg) await bot.send_message(Config.LOG_CHANNEL, msg)

View File

@ -1,4 +1,4 @@
VERIFY_TIME = 60 VERIFY_TIME = 180
MSG_PUBLIC = """您好,我发现此群组为公开群组,您需要联系创建者打开 `管理员批准后才能入群` 功能,我才能更好地工作。""" MSG_PUBLIC = """您好,我发现此群组为公开群组,您需要联系创建者打开 `管理员批准后才能入群` 功能,我才能更好地工作。"""
MSG_SUCCESS = """验证成功,您已经成为群组的一员了! MSG_SUCCESS = """验证成功,您已经成为群组的一员了!

View File

@ -5,6 +5,7 @@ import pytz
from apscheduler.schedulers.asyncio import AsyncIOScheduler from apscheduler.schedulers.asyncio import AsyncIOScheduler
from pyrogram.types import ChatJoinRequest from pyrogram.types import ChatJoinRequest
from sticker.languages import VERIFY_TIME
from sticker.single_utils import Message from sticker.single_utils import Message
scheduler = AsyncIOScheduler(timezone="Asia/ShangHai") scheduler = AsyncIOScheduler(timezone="Asia/ShangHai")
@ -24,6 +25,17 @@ async def decline_request(chat_join_request: ChatJoinRequest):
return False return False
async def ban_chat_member(chat_id: int, user_id: int):
from sticker import bot
with contextlib.suppress(Exception):
await bot.ban_chat_member(
chat_id, user_id, datetime.datetime.now() + datetime.timedelta(minutes=5)
)
return True
return False
def add_delete_message_job(message: Message, delete_seconds: int = 60): def add_delete_message_job(message: Message, delete_seconds: int = 60):
scheduler.add_job( scheduler.add_job(
delete_message, delete_message,
@ -45,7 +57,17 @@ def add_decline_request_job(chat_join_request: ChatJoinRequest):
name=f"{chat_join_request.chat.id}|{chat_join_request.from_user.id}|decline_request", name=f"{chat_join_request.chat.id}|{chat_join_request.from_user.id}|decline_request",
args=[chat_join_request], args=[chat_join_request],
run_date=datetime.datetime.now(pytz.timezone("Asia/Shanghai")) run_date=datetime.datetime.now(pytz.timezone("Asia/Shanghai"))
+ datetime.timedelta(seconds=60), + datetime.timedelta(seconds=VERIFY_TIME),
replace_existing=True,
)
def add_ban_chat_member_job(chat_id: int, user_id: int):
scheduler.add_job(
ban_chat_member,
id=f"{chat_id}|{user_id}|ban_chat_member",
name=f"{chat_id}|{user_id}|ban_chat_member",
args=[chat_id, user_id],
replace_existing=True, replace_existing=True,
) )