new_chat_member + ban + refactoring warns

This commit is contained in:
SantaSpeen
2022-03-21 22:03:55 +03:00
parent edf9742d13
commit f60ff3164c
6 changed files with 192 additions and 69 deletions

View File

@@ -28,15 +28,13 @@ $ python3 main.py
{ {
"bot_token": "BOT_TOKEN", "bot_token": "BOT_TOKEN",
"remote_chat": -1000, "remote_chat": -1000,
"new_member_message": "Привет, @%(username)-s!\nДобро пожаловать в наше IT - сообщество.\nЧтобы люди могли в будущем найти тебя, напиши вступительное сообщение о себе с хештегом %(<)-s#знакомство%(</)-s. Приятного времяпрепровождения!",
"static_message": { "static_message": {
"start": { "help": "Я бот, ничем не могу помочь, сорян..."
"allow": "private",
"msg": "Привет, я бот \"Ял\".\nДля ознакомления с возможностями - /help"
},
"help": {
"allow": "all",
"msg": "Помощь уже в пути!"
}
} }
} }
``` ```
### License
License: MIT

View File

@@ -1,14 +1,29 @@
from peewee import Model, SqliteDatabase, IntegerField, DoubleField, DoesNotExist from peewee import Model, SqliteDatabase, IntegerField, DoubleField, BooleanField, TextField
class BasicModel(Model):
class Meta:
database = SqliteDatabase('sqlite3.db')
class Users(Model): class Users(BasicModel):
id = IntegerField(null=True) id = IntegerField(null=True)
user_id = IntegerField() user_id = IntegerField()
warns = IntegerField(null=True, default=0) warns = IntegerField(null=True, default=0)
muted_until = DoubleField(null=True, default=0.0) muted_until = DoubleField(null=True, default=0.0)
banned_until = DoubleField(null=True, default=0.0) banned = BooleanField(null=True, default=False)
ban_by = IntegerField(null=True)
ban_msg = TextField(null=True)
class Meta: class Meta:
table_name = 'users' table_name = 'users'
database = SqliteDatabase('sqlite3.db')
class Mailing(BasicModel):
id = IntegerField(null=True)
user_id = IntegerField()
enable = BooleanField(null=True, default=True)
class Meta:
table_name = 'mailing'

View File

@@ -19,6 +19,9 @@ class Config:
self.remote_chat: int = None self.remote_chat: int = None
self.messages_object: str = None self.messages_object: str = None
self.new_member_message: str = None
self.start_message: str = None
self.static_message: dict = None
self._read_config() self._read_config()
@@ -34,3 +37,6 @@ class Config:
self.bot_token = self.raw_config.get("bot_token") self.bot_token = self.raw_config.get("bot_token")
self.remote_chat = self.raw_config.get("remote_chat") self.remote_chat = self.raw_config.get("remote_chat")
self.messages_object = self.raw_config.get("messages") self.messages_object = self.raw_config.get("messages")
self.new_member_message = self.raw_config.get("new_member_message")
self.start_message = self.raw_config.get("start_message")
self.static_message = self.raw_config.get("static_message")

View File

@@ -2,7 +2,7 @@ import logging
from aiogram import Bot, types from aiogram import Bot, types
from aiogram.dispatcher import Dispatcher from aiogram.dispatcher import Dispatcher
from aiogram.types import ParseMode from aiogram.types import ParseMode, ChatType
from aiogram.utils import executor from aiogram.utils import executor
from config import Config from config import Config
@@ -16,9 +16,18 @@ dp = Dispatcher(bot)
tools = Tools(config, dp) tools = Tools(config, dp)
@dp.message_handler(commands=["start"], chat_type=ChatType.PRIVATE)
async def start(msg: types.Message):
log.info(f"New message from {msg.from_user.id}(@{msg.from_user.username}) in {msg.chat.id}: '{msg.text}'")
user_id = msg.from_user.id
registered = tools.register_user(user_id)
if not registered:
await msg.reply(config.start_message)
@dp.message_handler(commands=['admins']) @dp.message_handler(commands=['admins'])
async def bot_admins(msg: types.Message): async def bot_admins(msg: types.Message):
log.info(f"New message from {msg.from_user.id}({msg.from_user.username}) in {msg.chat.id}: '{msg.text}'") log.info(f"New message from {msg.from_user.id}(@{msg.from_user.username}) in {msg.chat.id}: '{msg.text}'")
message = "Администраторы нашего сообщества:\n%(owner)-s" message = "Администраторы нашего сообщества:\n%(owner)-s"
admins = await tools.admins admins = await tools.admins
i = 1 i = 1
@@ -35,9 +44,9 @@ async def bot_admins(msg: types.Message):
await msg.reply(message, parse_mode=ParseMode.MARKDOWN) await msg.reply(message, parse_mode=ParseMode.MARKDOWN)
@dp.message_handler(regexp=r"\A(?:.|\/)(?:warn|пред)", is_chat_admin=True) @dp.message_handler(regexp=r"\A(?:.|\/)(?:warn|пред)", is_chat_admin=True, chat_type=ChatType.SUPERGROUP)
async def wanrs(msg: types.Message): async def wanr(msg: types.Message):
log.info(f"New message from {msg.from_user.id}({msg.from_user.username}) in {msg.chat.id}: '{msg.text}'") log.info(f"New message from {msg.from_user.id}(@{msg.from_user.username}) in {msg.chat.id}: '{msg.text}'")
reply_message = msg.reply_to_message reply_message = msg.reply_to_message
if reply_message: if reply_message:
@@ -50,12 +59,13 @@ async def wanrs(msg: types.Message):
else: else:
message = "Сначала надо выбрать пользователя." message = "Сначала надо выбрать пользователя."
await msg.reply(message, parse_mode=ParseMode.MARKDOWN) if message:
await msg.reply(message)
@dp.message_handler(regexp=r"\A(?:.|\/)(?:reset|прости)", is_chat_admin=True) @dp.message_handler(regexp=r"\A(?:.|\/)(?:reset|прости)", is_chat_admin=True, chat_type=ChatType.SUPERGROUP)
async def unwarn(msg): async def unwarn(msg: types.Message):
log.info(f"New message from {msg.from_user.id}({msg.from_user.username}) in {msg.chat.id}: '{msg.text}'") log.info(f"New message from {msg.from_user.id}(@{msg.from_user.username}) in {msg.chat.id}: '{msg.text}'")
reply_message = msg.reply_to_message reply_message = msg.reply_to_message
if reply_message: if reply_message:
@@ -63,14 +73,77 @@ async def unwarn(msg):
user_id = warn_user.id user_id = warn_user.id
user_username = warn_user.username user_username = warn_user.username
message = await tools.reset_warn(user_id, user_username) message = tools.reset_warn(user_id, user_username)
else: else:
message = "Сначала надо выбрать пользователя." message = "Сначала надо выбрать пользователя."
await msg.reply(message, parse_mode=ParseMode.MARKDOWN) await msg.reply(message, parse_mode=ParseMode.MARKDOWN)
tools.bind_static_messages() @dp.message_handler(regexp=r"\A(?:.|\/)(?:mute|тсс)", is_chat_admin=True, chat_type=ChatType.SUPERGROUP)
async def mute(msg: types.Message):
pass
@dp.message_handler(regexp=r"\A(?:.|\/)(?:unmute|говори)", is_chat_admin=True, chat_type=ChatType.SUPERGROUP)
async def unmute(msg: types.Message):
pass
@dp.message_handler(regexp=r"\A(?:.|\/)(?:ban|заскамить)", is_chat_admin=True, chat_type=ChatType.SUPERGROUP)
async def ban(msg: types.Message):
reply_message = msg.reply_to_message
if reply_message:
if len(msg.text.split(" ")) > 1:
message = await tools.ban_user(msg)
else:
message = "Укажи причину бана: `/ban [причина]`"
else:
message = "Сначала надо выбрать пользователя."
if message:
await msg.reply(message, parse_mode=ParseMode.MARKDOWN)
@dp.message_handler(content_types=['new_chat_members'], chat_type=ChatType.SUPERGROUP)
async def new_chat_member(msg: types.Message):
for user in msg.new_chat_members:
user_id = user['id']
log.info(f"New member: {user['id']}(@{user['username']})")
banned, ban_msg, ban_by = tools.is_banned(user_id)
if banned:
await bot.send_message(msg.chat.id,
f"@{user['username']}, вы забанены [Администратором](tg://user?id={ban_by})\n",
parse_mode=ParseMode.MARKDOWN)
await bot.kick_chat_member(msg.chat.id, user_id)
else:
message = config.new_member_message % {
"username": user['username'],
"<": "<code>", # Start codeblock
"</": "</code>" # Close codeblock
}
await bot.send_message(msg.chat.id, message, parse_mode=ParseMode.HTML)
@dp.message_handler(content_types=['text', 'photo', 'document', 'audio', 'sticker', 'animation', 'voice', 'video_note'])
async def all_messages(msg: types.Message):
text = msg.text
user_id = msg.from_user.id
log.info(f"New message from {user_id}(@{msg.from_user.username}) in {msg.chat.id}: '{text}'; "
f"Type: {msg.content_type}")
if msg.chat.type in [ChatType.SUPERGROUP, ChatType.GROUP]: # Если сообщение пришло из группы
pass
for k, v in config.static_message.items():
if k == text[1:len(k) + 1]:
await msg.reply(config.static_message[k], parse_mode=ParseMode.MARKDOWN)
return
if __name__ == '__main__': if __name__ == '__main__':
executor.start_polling(dp) executor.start_polling(dp)

View File

@@ -1,11 +1,23 @@
DROP TABLE IF EXISTS `users`; DROP TABLE IF EXISTS `users`;
DROP TABLE IF EXISTS `mailing`;
CREATE TABLE users ( CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT id INTEGER PRIMARY KEY AUTOINCREMENT
UNIQUE, UNIQUE,
user_id INTEGER UNIQUE user_id INTEGER UNIQUE
NOT NULL, NOT NULL,
warns INTEGER DEFAULT (0), warns INTEGER DEFAULT (0),
muted_until DOUBLE DEFAULT (0.0), muted_until DOUBLE DEFAULT (0.0),
banned_until DOUBLE DEFAULT (0.0) banned BOOLEAN DEFAULT (0),
); ban_by INTEGER,
ban_msg TEXT
);
CREATE TABLE mailing (
id INTEGER PRIMARY KEY AUTOINCREMENT
UNIQUE,
user_id INTEGER UNIQUE
NOT NULL,
enable BOOLEAN DEFAULT (1)
);

View File

@@ -2,13 +2,12 @@ import logging
import time import time
import aiogram import aiogram
from aiogram.types import ParseMode
from peewee import DoesNotExist from peewee import DoesNotExist
from SqlModels import Users from SqlModels import Users, Mailing
from config import Config from config import Config
static_log = logging.getLogger('static messages')
class Tools: class Tools:
@@ -18,35 +17,13 @@ class Tools:
self.dispatcher = dispatcher self.dispatcher = dispatcher
self.__admins: dict = {} self.__admins: dict = {}
@staticmethod
async def __message_handler(msg: aiogram.types.Message, **kwargs):
text = msg.text
static_log.info(f"New message from {msg.from_user.id}({msg.from_user.username}) in {msg.chat.id}: '{text}'")
for k, v in kwargs['__messages__'].items():
if k.startswith(text[1:len(k)]):
allow = v['allow']
send = False
if (allow == "all") or \
(allow == "private" and msg.chat.id > 0) or \
(allow == "chat" and msg.chat.id < 0):
send = True
if send:
await msg.reply(v['msg'])
break
def bind_static_messages(self):
__messages__: dict = self.config.raw_config['static_message']
__messages_keys__ = list(__messages__.keys())
l = lambda *x: self.__message_handler(*x, __messages__=__messages__)
self.dispatcher.register_message_handler(l, commands=__messages_keys__)
async def _update_admins_list(self): async def _update_admins_list(self):
admins = await self.dispatcher.bot.get_chat_administrators(self.config.remote_chat) admins = await self.dispatcher.bot.get_chat_administrators(self.config.remote_chat)
ids = list() ids = list()
for admin in admins: for admin in admins:
ids.append(admin['user']['id']) ids.append(admin['user']['id'])
self.__admins = { self.__admins = {
"time": time.time()+60.0, "time": time.time() + 60.0,
"object": {"list": admins, "ids": ids} "object": {"list": admins, "ids": ids}
} }
@@ -59,31 +36,46 @@ class Tools:
return self.__admins['object'] return self.__admins['object']
async def add_warn(self, user_id, user_username, chat_id): @staticmethod
def get_user(user_id):
try: try:
user = Users.get(Users.user_id == user_id) user = Users.get(Users.user_id == user_id)
except DoesNotExist: except DoesNotExist:
user = Users(user_id=user_id) user = Users(user_id=user_id)
return user
async def kick_chat_member(self, chat_id, user_id):
try:
await self.dispatcher.bot.kick_chat_member(chat_id, user_id)
return True
except Exception as e:
await self.dispatcher.bot.send_message(chat_id,
f"Ошибка при исключении [пользователя](tg://user?id={user_id}).\n"
f"Exception: `{e}`",
parse_mode=ParseMode.MARKDOWN)
return False
async def add_warn(self, user_id, user_username, chat_id):
user = self.get_user(user_id)
user.warns += 1 user.warns += 1
user.save() user.save()
if user.warns > 3: if user.warns > 3:
try:
await self.dispatcher.bot.kick_chat_member(chat_id, user_id) if await self.kick_chat_member(chat_id, user_id):
message = f"@{user_username} вёл себя плохо, поэтому теперь он иключён!" message = f"@{user_username} вёл себя плохо, поэтому теперь он иключён!"
except Exception as e: else:
message = f"Ошибка при исключении @{user_username}.\nException: `{e}`" message = None
user.warns = 0
user.save()
else: else:
message = f"@{user_username}, вы получили {user.warns} из 3 предупреждений.\nВпредь ведите себя лучше!" message = f"@{user_username}, вы получили {user.warns} из 3 предупреждений.\nВпредь ведите себя лучше!"
return message return message
@classmethod @classmethod
async def reset_warn(cls, user_id, username): def reset_warn(cls, user_id, username):
try: user = cls.get_user(user_id)
user = Users.get(Users.user_id == user_id)
except DoesNotExist:
user = Users(user_id=user_id)
if user.warns == 0: if user.warns == 0:
message = f"У пользователя @{username} нет предупреждений!" message = f"У пользователя @{username} нет предупреждений!"
else: else:
@@ -92,3 +84,30 @@ class Tools:
user.save() user.save()
return message return message
@classmethod
def is_banned(cls, user_id):
user = cls.get_user(user_id)
return user.banned, user.ban_msg, user.ban_by
async def ban_user(self, msg: aiogram.types.Message):
user = self.get_user(msg.reply_to_message.from_user.id)
if await self.kick_chat_member(msg.chat.id, user.user_id):
user.banned = True
user.ban_msg = " ".join(msg.text.split(" ")[1:])
user.ban_by = msg.from_user.id
user.save()
return f"@{msg.reply_to_message.from_user.username} был забанен по причие `{user.ban_msg}`."
@classmethod
def register_user(cls, user_id):
registered = False
cls.get_user(user_id).save()
try:
Mailing.get(Mailing.user_id == user_id)
registered = True
except DoesNotExist:
Mailing(user_id=user_id).save()
return registered