just_moderator/mod.py

605 lines
17 KiB
Python
Raw Normal View History

2023-10-01 19:01:42 +00:00
import telebot
import os
import json
from telebot import types,util
global users, la
2023-10-08 00:26:55 +00:00
####### CREATE DB IF NOT EXIST
2023-10-01 19:01:42 +00:00
if not os.path.exists('db.json'):
db = {'token': 'None'}
2023-10-08 00:26:55 +00:00
js = json.dumps(db, indent=2)
with open('db.json', 'w') as outfile:
2023-10-08 00:26:55 +00:00
outfile.write(js)
2023-10-01 19:01:42 +00:00
2023-10-08 00:26:55 +00:00
print('Input token in "None" (db.json)')
exit()
2023-10-01 19:01:42 +00:00
2023-10-08 00:26:55 +00:00
if not os.path.exists('users.json'):
users = {}
js = json.dumps(users, indent=2)
with open('users.json', 'w') as outfile:
2023-10-08 00:26:55 +00:00
outfile.write(js)
2023-12-18 18:49:22 +00:00
if not os.path.exists('la.json'):
la = {}
js = json.dumps(la, indent=2)
with open('la.json', 'w') as outfile:
2023-10-14 14:10:21 +00:00
outfile.write(js)
2023-10-08 00:26:55 +00:00
############WORK WITH DBs##########
def read_db():
with open('db.json', 'r') as openfile:
db = json.load(openfile)
return db
def write_db(db):
js = json.dumps(db, indent=2)
with open('db.json', 'w') as outfile:
outfile.write(js)
2023-10-08 00:26:55 +00:00
def read_users():
global users
with open('users.json', 'r') as openfile:
users = json.load(openfile)
2023-10-08 00:26:55 +00:00
def write_users():
global users
js = json.dumps(users, indent=2)
with open('users.json', 'w') as outfile:
outfile.write(js)
2023-10-01 19:01:42 +00:00
2023-12-18 18:49:22 +00:00
# LA - Low Admin.
# Admin permissions in bot without admin rights.
def read_la():
with open('la.json', 'r') as openfile:
la = json.load(openfile)
return la
def write_la(la):
js = json.dumps(la, indent=2)
with open('la.json', 'w') as outfile:
outfile.write(js)
2023-10-14 14:10:21 +00:00
####################FAST HASH#################
from xxhash import xxh32
# Generate fast hash
def sha(text):
text = str(text)
return xxh32(text).hexdigest()
2023-10-08 00:26:55 +00:00
##################FUNCTIONS########
2023-10-01 19:01:42 +00:00
def get_admins(message):
2023-10-01 21:06:24 +00:00
try:
if bot.get_chat(message.chat.id).type == 'private':
2023-10-08 00:26:55 +00:00
return []
else:
admins = bot.get_chat_administrators(chat_id=message.chat.id)
true_admins = []
for i in admins:
if i.status == 'creator' or i.can_restrict_members == True:
2023-10-08 00:26:55 +00:00
true_admins.append(i.user.id)
2023-10-01 21:06:24 +00:00
return true_admins
except Exception as e:
catch_error(message, e)
2023-10-01 21:06:24 +00:00
return None
2023-10-01 19:01:42 +00:00
2023-10-14 14:10:21 +00:00
# Fix for anon admins, all anon (not premium) users == admins
def is_anon(message):
if message.from_user.username == 'Channel_Bot' or message.from_user.username == 'GroupAnonymousBot':
2023-12-18 18:49:22 +00:00
if message.from_user.is_premium == None:
return True
2023-10-14 14:10:21 +00:00
else:
return False
2023-10-01 19:01:42 +00:00
# Return id from db/chat of user
2023-10-01 19:01:42 +00:00
def get_target(message):
try:
2024-01-18 22:16:46 +00:00
global users
spl = message.text.split()
2024-01-23 16:14:04 +00:00
if ( len(spl) > 1 and spl[1][0] == '@' ) or ( len(spl) > 2 and spl[2][0] == '@' ):
for i in spl:
if i[0] == '@':
username = i[1:]
break
2024-01-18 22:16:46 +00:00
read_users()
if sha(username) in users:
return users[sha(username)]
else:
return None
2023-10-08 00:26:55 +00:00
else:
target = message.reply_to_message.from_user.id
if target not in get_admins(message):
return target
else:
return None
except:
return None
2023-10-01 19:01:42 +00:00
def get_name(message):
try:
text = message.text.split()
# If message with @username
if len(text) > 1 and text[1][0] == '@':
return text[1]
2024-01-23 16:14:04 +00:00
if len(text) > 2 and text[2][0] == '@':
2024-01-18 22:16:46 +00:00
return text[2]
# Reply to message
else:
return telebot.util.user_link(message.reply_to_message.from_user)
except Exception as e:
catch_error(message, e)
# Get time for '/mute'
# [time, time_in_sec, format]
def get_time(message):
formats = {'s':[1, 'секунд(ы)'], 'm':[60, 'минут(ы)'], 'h': [3600,'час(а)'], 'd': [86400,'день/дня']}
text = message.text.split()[1:] ; time = None
# Find format in text
for i in text:
if time:
break
for f in list(formats.keys()):
if f in i:
2024-01-23 16:14:04 +00:00
try:
time = [i[:-1], int(i[:-1]) * formats[i[-1]][0] , formats[i[-1]][1] ]
break
except:
pass
return time
2023-12-18 18:49:22 +00:00
def have_rights(message, set_la = False):
la = read_la()
2023-12-18 18:49:22 +00:00
if message.from_user.id in get_admins(message):
return True
elif is_anon(message):
return True
elif str(message.chat.id) in la and not set_la:
if str(message.from_user.username) in la[str(message.chat.id)]:
return True
else:
bot.reply_to(message, 'Увы, но у вас нету прав.')
2023-12-18 18:49:22 +00:00
2023-10-08 00:26:55 +00:00
def key_by_value(dictionary, key):
for i in dictionary:
if dictionary[i] == key:
return i
return None
2023-10-01 19:01:42 +00:00
2023-10-08 00:26:55 +00:00
def analytic(message):
global users
2023-10-14 14:10:21 +00:00
read_users()
2023-10-08 00:26:55 +00:00
if key_by_value(users, message.from_user.id) == message.from_user.username:
pass
elif message.from_user.username == 'None':
pass
2023-10-08 00:26:55 +00:00
else:
users[sha(message.from_user.username)] = message.from_user.id
2023-10-08 00:26:55 +00:00
write_users()
2023-10-01 19:38:47 +00:00
2023-10-08 00:26:55 +00:00
#############TOKEN INIT#####
2023-10-01 19:38:47 +00:00
2023-10-08 00:26:55 +00:00
db = read_db()
read_users()
2023-10-08 00:26:55 +00:00
bot = telebot.TeleBot(db['token'])
##################COMMANDS#######
@bot.message_handler(commands=['start', 'faq'])
2023-10-01 19:01:42 +00:00
def send_welcome(message):
bot.reply_to(message, '''Колотушка работает 🔨
2023-10-01 19:01:42 +00:00
Что это такое?
2024-01-23 16:19:50 +00:00
Это минимальный бот-модератор без слежки с открытым кодом.
2024-07-11 08:07:54 +00:00
Код: https://gitea.del.pw/justuser/just_moderator
2023-10-01 19:01:42 +00:00
2023-10-01 19:38:47 +00:00
Список команд - /help
''')
2023-10-01 19:38:47 +00:00
@bot.message_handler(commands=['help'])
def help(message):
bot.reply_to(message, '''
2023-10-01 19:38:47 +00:00
Список команд:
2023-10-14 14:10:21 +00:00
/mute Мут человека в ответ на сообщение
/unmute Снятие мута
/kick Кик
/ban Бан
/unban Снятие бана
/setwelcome Приветственное сообщение
/welcome Демонстрация текущего сообщения
/lock Блокировка чата (для обычных пользователей)
/unlock Снятие блокировки чата
/chatid Айди чата
2023-12-18 18:49:22 +00:00
/del Удаление сообщения
2023-10-14 14:10:21 +00:00
/la - всё о режиме 'low admin'
2023-10-14 14:10:21 +00:00
/secret Функция для получения ссылки html на пользователя в лс.
/html <code> Отправка текста сообщения в режиме формата html.
2023-10-14 15:15:49 +00:00
/support Написать разработчику. Прошу писать по делу.
''')
2023-10-01 19:01:42 +00:00
@bot.message_handler(commands=['mute'])
def mute(message):
2023-10-01 21:06:24 +00:00
try:
2023-12-18 18:49:22 +00:00
if have_rights(message):
2023-10-01 19:01:42 +00:00
target = get_target(message)
time = get_time(message)
2023-10-08 00:26:55 +00:00
if target:
if time:
bot.restrict_chat_member(message.chat.id, target, until_date = message.date + time[1])
answer = f'Пользователь { get_name(message) } был заглушён на {time[0]} {time[2]}.'
2023-10-08 00:26:55 +00:00
else:
bot.restrict_chat_member(message.chat.id, target, until_date = message.date)
answer = f'Пользователь { get_name(message) } был заглушен.'
try:
bot.reply_to(message, answer, parse_mode='HTML')
except:
bot.reply_to(message, answer)
2023-10-01 19:01:42 +00:00
else:
catch_error(message, 'None', 'no_user')
except Exception as e:
catch_error(message, e)
2023-10-01 19:01:42 +00:00
@bot.message_handler(commands=['unmute'])
def unmute(message):
2023-10-01 21:06:24 +00:00
try:
2023-12-18 18:49:22 +00:00
if have_rights(message):
2023-10-01 19:01:42 +00:00
target = get_target(message)
2023-10-08 00:26:55 +00:00
if target:
bot.restrict_chat_member(message.chat.id, target, can_send_messages=True
, can_send_other_messages = True, can_send_polls = True
, can_add_web_page_previews = True, until_date = message.date)
bot.reply_to(message, f'''Пользователь { get_name(message) } снова имеет дар речи.
''', parse_mode='HTML')
2023-10-08 00:26:55 +00:00
else:
catch_error(message, None, 'no_user')
except Exception as e:
catch_error(message, e)
2023-10-01 19:01:42 +00:00
@bot.message_handler(commands=['kick'])
def kick(message):
2023-10-01 21:06:24 +00:00
try:
2023-12-18 18:49:22 +00:00
if have_rights(message):
2023-10-01 19:01:42 +00:00
target = get_target(message)
2023-10-08 00:26:55 +00:00
if target:
bot.ban_chat_member(message.chat.id, target)
bot.unban_chat_member(message.chat.id, target)
2023-10-01 19:01:42 +00:00
bot.reply_to(message, f'''Пользователь { get_name(message) } был исключён.
''', parse_mode='HTML')
2023-10-08 00:26:55 +00:00
else:
catch_error(message, None, 'no_user')
except Exception as e:
catch_error(message, e)
2023-10-01 19:01:42 +00:00
@bot.message_handler(commands=['ban'])
def ban(message):
2023-10-01 21:06:24 +00:00
try:
2023-12-18 18:49:22 +00:00
if have_rights(message):
2023-10-01 21:06:24 +00:00
target = get_target(message)
2023-10-08 00:26:55 +00:00
if target:
bot.ban_chat_member(message.chat.id, target)
bot.reply_to(message, f'''Пользователь { get_name(message) } исключён и заблокирован.
''', parse_mode='HTML')
2023-10-08 00:26:55 +00:00
else:
catch_error(message, None, 'no_user')
except Exception as e:
catch_error(message, e)
2023-10-01 19:01:42 +00:00
@bot.message_handler(commands=['unban'])
def unban(message):
2023-10-01 21:06:24 +00:00
try:
2023-12-18 18:49:22 +00:00
if have_rights(message):
2023-10-01 21:06:24 +00:00
target = get_target(message)
2023-10-08 00:26:55 +00:00
if target:
bot.unban_chat_member(message.chat.id, target)
bot.reply_to(message, f'''Пользователь { get_name(message) } разблокирован.
''', parse_mode='HTML')
2023-10-08 00:26:55 +00:00
else:
catch_error(message, None, 'no_user')
except Exception as e:
catch_error(message, e)
2023-10-01 19:01:42 +00:00
@bot.message_handler(commands=['setwelcome'])
def setwelcome(message):
2023-10-01 21:06:24 +00:00
try:
2023-12-18 18:49:22 +00:00
if have_rights(message):
db = read_db()
db[str(message.chat.id)] = message.html_text[ message.text.find(' ') + 1 :]
2023-10-08 00:26:55 +00:00
bot.reply_to(message, f'''Установлено новое приветственное сообщение:
\n{db[str(message.chat.id)]}''', parse_mode='HTML')
write_db(db)
except Exception as e:
catch_error(message, e)
2023-10-01 19:01:42 +00:00
@bot.message_handler(commands=['welcome'])
def welcome(message):
2023-10-01 21:06:24 +00:00
try:
db = read_db()
bot.reply_to(message, f'''Приветственное сообщение:
\n{db[str(message.chat.id)]}''', parse_mode='HTML')
except Exception as e:
catch_error(message, e)
2023-10-01 19:01:42 +00:00
2023-10-01 19:32:43 +00:00
@bot.message_handler(commands=['lock'])
def lock(message):
2023-10-01 21:06:24 +00:00
try:
2023-12-18 18:49:22 +00:00
if have_rights(message):
2023-10-01 19:32:43 +00:00
bot.set_chat_permissions(message.chat.id, telebot.types.ChatPermissions(can_send_messages=False, can_send_other_messages = False, can_send_polls = False))
bot.reply_to(message, 'Чат был заблокирован 🔒')
2023-10-01 21:06:24 +00:00
else:
bot.reply_to(message, 'Увы, но у вас нету прав.')
except Exception as e:
catch_error(message, e)
2023-10-01 19:32:43 +00:00
@bot.message_handler(commands=['unlock'])
def unlock(message):
2023-10-01 21:06:24 +00:00
try:
2023-12-18 18:49:22 +00:00
if have_rights(message):
2023-10-01 19:32:43 +00:00
bot.set_chat_permissions(message.chat.id, telebot.types.ChatPermissions(can_send_messages=True, can_send_other_messages = True, can_send_polls = True))
bot.reply_to(message, 'Чат был разблокирован 🔓')
except Exception as e:
catch_error(message, e)
2023-10-08 00:26:55 +00:00
@bot.message_handler(commands=['id'])
def getid(message):
try:
2023-12-18 18:49:22 +00:00
if have_rights(message):
bot.reply_to(message, 'ID: ' + telebot.formatting.hcode(str(get_target(message))), parse_mode='HTML' )
except Exception as e:
catch_error(message, e)
2023-10-08 00:26:55 +00:00
2023-12-18 18:49:22 +00:00
@bot.message_handler(commands=['del'])
2024-01-18 22:16:46 +00:00
def delete(message):
2023-12-18 18:49:22 +00:00
try:
if have_rights(message):
bot.delete_message(message.chat.id, message.reply_to_message.id)
bot.delete_message(message.chat.id, message.id)
except Exception as e:
catch_error(message, e)
2023-12-18 18:49:22 +00:00
@bot.message_handler(commands=['pin'])
def pin(message):
try:
if have_rights(message):
bot.pin_chat_message(message.chat.id, message.reply_to_message.id)
except:
catch_error(message, e)
@bot.message_handler(commands=['unpin'])
def unpin(message):
try:
if have_rights(message):
bot.unpin_chat_message(message.chat.id, message.reply_to_message.id)
except:
catch_error(message, e)
### EXPEREMENTAL
2023-10-08 00:26:55 +00:00
@bot.message_handler(commands=['secret'])
def secret(message):
try:
2023-12-18 18:49:22 +00:00
if have_rights(message):
bot.send_message(message.from_user.id, telebot.util.user_link(message.reply_to_message.from_user))
bot.delete_message(message.chat.id, message.id)
except Exception as e:
catch_error(message, e)
@bot.message_handler(commands=['html'])
def html(message):
try:
text = ' '.join( message.text.split()[1:] )
bot.send_message(message.chat.id , text, parse_mode='HTML')
bot.delete_message(message.chat.id, message.id)
except Exception as e:
catch_error(message, e)
###
2023-10-14 14:10:21 +00:00
@bot.message_handler(commands=['chatid'])
def chatid(message):
try:
2023-12-18 18:49:22 +00:00
if have_rights(message):
bot.reply_to(message, 'Айди чата: ' + telebot.formatting.hcode( str(message.chat.id) ), parse_mode='HTML')
2023-10-14 14:10:21 +00:00
else:
bot.reply_to(message, 'Увы, но у вас нету прав.')
except Exception as e:
catch_error(message, e)
2023-12-18 18:49:22 +00:00
############ LOW-ADMIN ##############
def have_la(message):
2023-12-18 18:49:22 +00:00
try:
id = message.from_user.id
la = read_la()
2023-12-18 18:49:22 +00:00
if id in la:
return True
else:
la[id] = []
write_la(la)
2023-12-18 18:49:22 +00:00
return True
except Exception as e:
catch_error(message, e)
2023-12-18 18:49:22 +00:00
@bot.message_handler(commands=['la'])
def la(message):
bot.reply_to(message, f'''Доступные команды:
{telebot.formatting.hcode('/la-list')} - список администраторов в режиме low-admin
{telebot.formatting.hcode('/la-add @nick')} - добавить в администраторы
{telebot.formatting.hcode('/la-del @nick')} - удалить из администраторов
''', parse_mode = 'HTML')
2023-12-18 18:49:22 +00:00
@bot.message_handler(commands=['la-list'])
def la_list(message):
try:
if have_rights(message, set_la=True):
la = read_la()
if have_la(message):
s = 'Список администраторов в режиме low-admin:\n'
2023-12-18 18:49:22 +00:00
for i in la[str(message.chat.id)]:
s = s + '\n@' + i
bot.reply_to(message, s, parse_mode='HTML')
except Exception as e:
catch_error(message, e)
2023-12-18 18:49:22 +00:00
@bot.message_handler(commands=['la-add'])
def la_add(message):
try:
if have_rights(message, set_la=True):
la = read_la()
if have_la(message):
2023-12-18 18:49:22 +00:00
nick = message.text.split()[1][1:]
print(la)
la[str(message.chat.id)].append(nick)
print(la)
write_la(la)
bot.reply_to(message, f'Пользователь @{nick} успешно добавлен в список администраторов.')
except Exception as e:
catch_error(message, e)
2023-12-18 18:49:22 +00:00
@bot.message_handler(commands=['la-del'])
def la_del(message, set_la=True):
try:
if have_rights(message, set_la=True):
la = read_la()
if have_la(message):
2023-12-18 18:49:22 +00:00
nick = message.text.split()[1][1:]
if nick in la[str(message.chat.id)]:
la[str(message.chat.id)].remove(nick)
write_la(la)
bot.reply_to(message, f'Пользователь @{nick} был исключён из списка администраторов.')
except Exception as e:
catch_error(message, e)
2023-12-18 18:49:22 +00:00
#######################JOIN REQUEST #############
@bot.chat_join_request_handler()
def join_request(message: telebot.types.ChatJoinRequest):
try:
bot.send_message(message.chat.id, f'''Поступила заявка на вступление от { telebot.util.user_link(message.from_user) }
Принять: { telebot.formatting.hcode(f'/accept {message.from_user.id}') }''', parse_mode='HTML')
analytic(message)
except Exception as e:
catch_error(message, e)
2023-12-18 18:49:22 +00:00
@bot.message_handler(commands=['accept'])
def accept_request(message):
try:
if have_rights(message):
if len(message.text.split()) == 2:
bot.approve_chat_join_request(message.chat.id, message.text.split()[1] )
bot.reply_to(message, 'Заявка принята.')
except Exception as e:
catch_error(message, e)
2023-12-18 18:49:22 +00:00
2023-10-08 00:26:55 +00:00
######################SUPPORT########
2023-10-01 19:32:43 +00:00
@bot.message_handler(commands=['support'])
def support(message):
2023-10-01 21:06:24 +00:00
try:
bot.reply_to(message, f'''Связь с аднимистратором в @just_anonchat_bot
Адрес - {telebot.formatting.hcode(':justuser')}''', parse_mode='HTML')
except Exception as e:
catch_error(message, e)
2023-10-01 19:32:43 +00:00
2023-10-08 00:26:55 +00:00
#####################WELCOME#####
@bot.message_handler(content_types=['new_chat_members'])
2023-10-08 00:26:55 +00:00
def handler_new_member(message):
try:
db = read_db()
if str(message.chat.id) not in db:
db[str(message.chat.id)] = 'Приветственное сообщение не задано.\n Задайте его с помощью /setwelcome ...'
la = read_la()
la[str(message.chat.id)] = []
write_la(la)
2023-10-08 00:26:55 +00:00
bot.reply_to(message, db[str(message.chat.id)], parse_mode='HTML')
analytic(message)
except Exception as e:
catch_error(message, e)
2023-10-08 00:26:55 +00:00
##############ANALYTIC########
2023-10-14 14:10:21 +00:00
@bot.message_handler()
2023-10-08 00:26:55 +00:00
def catch_all_messages(message):
analytic(message)
2023-10-08 00:26:55 +00:00
# For what?
2023-10-14 14:10:21 +00:00
# This add users to db for using command like:
# /ban @username
# Without reply to message. All usernames hashed.
2023-10-08 00:26:55 +00:00
##################CATCH ERRORS####
2023-10-01 19:32:43 +00:00
2023-10-08 00:26:55 +00:00
import logging
import traceback
2023-10-01 19:32:43 +00:00
2023-10-08 00:26:55 +00:00
from io import StringIO # For catch log to variable
2023-10-01 19:32:43 +00:00
2023-10-08 00:26:55 +00:00
# Basic init
global log_stream
log_stream = StringIO()
logging.basicConfig(stream=log_stream)
2023-10-01 19:01:42 +00:00
# Known errors
known_errs = {
'A request to the Telegram API was unsuccessful. Error code: 400. Description: Bad Request: not enough rights to restrict/unrestrict chat member': 'Увы, но у бота не хватает прав для этого.'
}
# message error err_type ('no_user', ...)
def catch_error(message, e, err_type = None):
2023-10-08 00:26:55 +00:00
if not err_type:
global log_stream, known_errs
e = str(e)
2023-10-01 19:01:42 +00:00
# Check error in known_errs
print(e)
if e in known_errs:
bot.send_message(message.chat.id, known_errs[e])
else:
logging.error(traceback.format_exc()) # Log error
err = log_stream.getvalue() # Error to variable
2023-10-08 00:26:55 +00:00
bot.send_message(message.chat.id, 'Critical error (свяжитись через /support ) :\n\n' + telebot.formatting.hcode(err), parse_mode='HTML')
2023-10-08 00:26:55 +00:00
log_stream.truncate(0) # Clear
log_stream.seek(0) # Clear
elif err_type == 'no_user':
bot.send_message(message.chat.id, 'Не указан пользователь.')
2023-10-08 00:26:55 +00:00
##################MAIN THREAD#####
#'''
2023-10-08 00:26:55 +00:00
while True:
2023-10-01 21:06:24 +00:00
try:
2023-10-08 00:26:55 +00:00
bot.polling()
except KeyboardInterrupt:
exit()
2023-10-01 21:06:24 +00:00
except:
pass
'''
bot.polling()
'''