Skip to content

Commit 3468594

Browse files
committed
bot
0 parents  commit 3468594

File tree

6 files changed

+210
-0
lines changed

6 files changed

+210
-0
lines changed

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Async Telegram Bot Moderator
2+
This is a simple realization of an asynchronous telegram bot moderator.
3+
## Bot Functions
4+
- deleting duplicate messages
5+
- deleting abusive messages
6+
- deleting messages with external urls
7+
- muting users
8+
9+
## Requirements
10+
```pip install -r requirements.txt```
11+
12+
## Usage
13+
- create a bot in ```@BotFather``` then run the command in BotFather's menu ```/setprivacy``` and set up current status in: **Disable**
14+
- add the bot to your group and set administrator rights for it
15+
- add received bot's token in ```config.py``` and fill other fields
16+
17+
## Mute Users
18+
First you need to get the user ID
19+
- run ```!info <full name>```<br>
20+
Example: ```!info John Doe```<br>
21+
You will receive a message from the bot with user data, something like this ```[('1234567', 'John Doe', '2021-08-25 23:02:37')]```
22+
- for mute user, run ```!mute <id>```<br>
23+
Example: ```!mute 1234567```
24+
## Start
25+
```python bot.py```

bot.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import logging
2+
import filters
3+
from aiogram import Bot, Dispatcher, executor, types
4+
from config import TOKEN, ACCESS_DENIED_MESSAGE, BAN_MESSAGE, MUTE_TIME
5+
from db_writer import DataWriter
6+
7+
8+
db_write = DataWriter()
9+
10+
logging.basicConfig(level=logging.INFO)
11+
12+
bot = Bot(token=TOKEN)
13+
dp = Dispatcher(bot)
14+
15+
16+
@dp.message_handler(commands=['mute', 'info'], commands_prefix='!')
17+
async def admin_command(message: types.Message):
18+
user_status = ['creator', 'administrator']
19+
member = await bot.get_chat_member(message.chat.id, message.from_user.id)
20+
21+
if member['status'] in user_status:
22+
if message.text.startswith('!mute'):
23+
await message.delete()
24+
user_id = message.text.replace('!mute', '').strip()
25+
await bot.restrict_chat_member(message.chat.id, user_id, until_date=int(message.date.timestamp() + MUTE_TIME * 3600))
26+
await message.answer(f'{db_write.get_user_name(user_id)} - {BAN_MESSAGE}!')
27+
elif message.text.startswith('!info'):
28+
full_name = message.text.replace('!info', '').strip()
29+
await bot.send_message(message.from_user.id, db_write.get_user_info(full_name))
30+
else:
31+
await message.reply(ACCESS_DENIED_MESSAGE)
32+
33+
34+
@dp.message_handler()
35+
async def filter_message(message: types.Message):
36+
user_id = message.from_user.id
37+
user_name = message.from_user.username
38+
full_name = message.from_user.full_name
39+
msg_date = message.date
40+
msg = message.text.lower()
41+
timestamp = message.date.timestamp()
42+
43+
check_msg = await filters.filter_text(msg, user_id, int(timestamp))
44+
if check_msg:
45+
await message.delete()
46+
47+
if str(message.from_user.id) not in db_write.get_all_users_id():
48+
db_write.save_user_data(user_id, user_name, full_name, msg_date, msg, timestamp)
49+
else:
50+
db_write.update_user_data(user_id, user_name, full_name, msg_date, msg, timestamp)
51+
52+
53+
if __name__ == '__main__':
54+
executor.start_polling(dp, skip_updates=True)

config.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# bot token
2+
TOKEN = ''
3+
4+
# abusive words
5+
BAD_WORDS = ['bad', 'word', 'very bad']
6+
7+
# allowed domains
8+
# if you want to allow all urls, this array must be empty
9+
GOOD_DOMAINS = ['domain.com', 'example.net']
10+
11+
ACCESS_DENIED_MESSAGE = 'Access denied'
12+
13+
BAN_MESSAGE = 'You were blocked'
14+
15+
# maximum time to user mute in hours
16+
MUTE_TIME = 24
17+
18+
# maximum message sending frequency in seconds
19+
MESSAGE_SEND_FREQUENCY = 3

db_writer.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import sqlite3
2+
3+
4+
class DataWriter:
5+
def __init__(self):
6+
self.conn = sqlite3.connect('data.sqlite3')
7+
self.cur = self.conn.cursor()
8+
self.cur.execute(
9+
"""
10+
CREATE TABLE IF NOT EXISTS users(
11+
id INTEGER PRIMARY KEY AUTOINCREMENT,
12+
tg_id TEXT NOT NULL,
13+
user_name TEXT,
14+
full_name TEXT,
15+
date_time TEXT,
16+
message TEXT,
17+
active_time INTEGER
18+
);
19+
"""
20+
)
21+
self.conn.commit()
22+
23+
def get_user_msg(self, user_id):
24+
self.cur.execute(f"SELECT message, active_time FROM users WHERE tg_id = '{str(user_id)}';")
25+
user_info = self.cur.fetchall()
26+
return user_info
27+
28+
def get_user_info(self, name):
29+
self.cur.execute(f"SELECT tg_id, full_name, date_time FROM users WHERE full_name = '{name}';")
30+
db_user = self.cur.fetchall()
31+
print(db_user)
32+
return db_user
33+
34+
def get_user_name(self, user_id):
35+
self.cur.execute(f"SELECT full_name FROM users WHERE tg_id = '{user_id}';")
36+
name_user = self.cur.fetchall()
37+
return name_user[0][0]
38+
39+
def get_all_users_id(self):
40+
user_data = []
41+
self.cur.execute("SELECT tg_id FROM users;")
42+
db_users = self.cur.fetchall()
43+
44+
for i in db_users:
45+
user_data.append(''.join(i))
46+
47+
return user_data
48+
49+
def save_user_data(self, tg_id, user_name, full_name, date_time, msg, timestamp):
50+
self.cur.execute(f"""INSERT INTO users(tg_id, user_name, full_name, date_time, message, active_time)
51+
VALUES('{tg_id}', '{user_name}', '{full_name}', '{date_time}', '{msg}', '{timestamp}');""")
52+
self.conn.commit()
53+
54+
def update_user_data(self, user_tg_id, username, fullname, datetime, msg, timestamp):
55+
self.cur.execute(f"""UPDATE users
56+
SET date_time = '{datetime}',
57+
user_name = '{username}',
58+
full_name = '{fullname}',
59+
message = '{msg}',
60+
active_time = '{timestamp}'
61+
WHERE tg_id = '{user_tg_id}'
62+
""")
63+
self.conn.commit()
64+

filters.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import re
2+
3+
from config import GOOD_DOMAINS, BAD_WORDS, MESSAGE_SEND_FREQUENCY
4+
from db_writer import DataWriter
5+
6+
7+
db_info = DataWriter()
8+
9+
10+
regex = r'(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-]{,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}'
11+
12+
13+
async def filter_text(message: str, user_tg_id: int, timestamp: float):
14+
# check spam
15+
msg_and_time = db_info.get_user_msg(user_tg_id)
16+
msg = msg_and_time[0][0]
17+
time = msg_and_time[0][1]
18+
sec = timestamp - time
19+
if sec <= MESSAGE_SEND_FREQUENCY or message.lower() == msg:
20+
return True
21+
22+
# urls filter
23+
domains = re.findall(regex, message.lower())
24+
if GOOD_DOMAINS:
25+
if domains:
26+
for domain in GOOD_DOMAINS:
27+
if domain in domains:
28+
domains.remove(domain)
29+
if domains != []:
30+
return True
31+
32+
# bad words filter
33+
for word in BAD_WORDS:
34+
if word.lower() in message.lower():
35+
return True
36+

requirements.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
aiogram==2.14.3
2+
aiohttp==3.7.4.post0
3+
async-timeout==3.0.1
4+
attrs==21.2.0
5+
Babel==2.9.1
6+
certifi==2021.5.30
7+
chardet==4.0.0
8+
idna==3.2
9+
multidict==5.1.0
10+
pytz==2021.1
11+
typing-extensions==3.10.0.0
12+
yarl==1.6.3

0 commit comments

Comments
 (0)