Вы наверняка видели все эти чаты, где сидит 100500 человек, а общается от силы 5–10. Да что уж там, вероятно, вы сами админ такого чата и все порываетесь навести порядок. Да только вечно то одно, то другое, и вместо уютного места для своих получается эдакое «шоу Трумана», где есть вы, ваши братюни и куча греющих уши мертвых душ. Удручает, не правда ли?
Но ведь вычищать их ручками необязательно — можно просто запустить бот, который сам будет следить за активом и кикать молчунов. Об этом и расскажем ниже.
Какие задачи решает бот для кика мертвых душ
Но сначала пара слов о том, для чего нужен бот, кикающий мертвые души. А нужен он, как ни странно, не только для непосредственной автоматизации киков, но еще и для:
Поддержания активности в чате — если чат реально уникальный и с какой-то эксклюзивной инфой, юзеры, всего скорее, не захотят из него вылетать.
Противодействия парсингу — не то чтоб абсолютно эффективно, но все же ушлым вуайеристам придется вручную перезаходить с новых акков.
Нативной капчи — у бота есть белый список, что подразумевает возможность связаться с админом и запросить себе возможность молчать. При этом это происходит по инициативе юзера — что куда более нативно, чем капча в лоб.
Ну и по традиции любые задачи, которые вы сами себе придумаете, он тоже может решать. Ну то есть при условии, что он уже решал их до того, как вы их придумали. Ну вы поняли :D А мы идем дальше.
Принцип работы бота для кика мертвых душ
А дальше у нас разбор того, как бот работает. И, к счастью, тут тоже все простенько:
- Бот авторизуется на аккаунте и слушает эфир.
- Параллельно он создает файл active_chats.json, в котором хранит чаты, добавленные для очистки мертвых душ.
- Если аккаунт, на котором авторизован бот, пишет в каком-то чате /addkick — добавляет его в active_chats.json
- Параллельно бот создает ID.json, имя которого соответствует ID чата, и записывает в него всех участников и текущую метку времени.
- Админам бот автоматически присваивает флаг a.
- При этом если чата в active_chats.json нет, то любые другие команды он игнорирует.
- А если есть — то реагирует на них в соответствии с командой.
- Удаляет чат из active_chats.json при вводе /delkick.
- Присваивает юзеру флаг w внутри ID.json, при вводе /whitelist в ответ на сообщение юзера.
- Удаляет юзеру флаг w внутри ID.json, при вводе /unwhitelist в ответ на сообщение юзера.
- Раз в сутки проверяет, не прошло ли 7 дней с момента последней активности пользователя. Если прошли — кикает его. Если нет — не кикает.
Здесь важно уточнить, что под активностью подразумевается любое действие, кроме простановки реакций и молчаливого чтения. Текст, ГС, кружки, да хоть сброшенная в чат геолокация — все это будет считаться активностью. Также заметим, что «проверка раз в сутки» и «активность раз в 7 дней» — хоть и зашиты в код, но могут быть изменены. Для этого достаточно указать собственные CHECK_INTERVAL и INACTIVE_DELTA.
Решение сделать константы вместо переменных обусловлено тем, чтобы «слепо копирующим» читателям не снесло аккаунты из-за бездумной простановки своих значений. Все же одно дело — удалять кого-то каждую минуту, и совсем другое — раз в стуки. Да и участники чата вас не поймут, если вы будете их кикать за малейший неактив. Все же нужно дать людям право помолчать хотя бы недельку.
Кто будет делать бот осознанно, без труда сможет поменять значения на свои. А мы переходим к тому, как, собственно, сделать бот.
Пошаговая инструкция, как сделать бот для кика мертвых душ
Как обычно, начинаем с развертывания сервера. И как обычно, если вы не понимаете, как его развернуть, то держите эту статью. Там все изи-пизи, а главное — бесплатно. Но в идеале, конечно, деплоить на полноценном серваке. Далее настройка. Вводим в консоль сервера вот это:
pip install telethon
pip install asyncio
После чего делаем вот что:
- Авторизуемся в веб-версии Телеги.
- Нажимаем на «API development tools».
- Заполняем анкету.
- Копипастим api_id и api_hash.
Затем:
1. Создаем файл kick.py в корне сервака.
2. Копируем туда:
from telethon import TelegramClient, events
from telethon.tl.types import ChannelParticipantsAdmins
from datetime import datetime, timedelta, timezone
import asyncio
import json
import os
api_id = ваш api_id
api_hash = "ваш api_hash"
session_name = "session"
CHECK_INTERVAL = 24 * 3600 # 24 часа по умолчанию
#CHECK_INTERVAL = 60 # тест
INACTIVE_DELTA = timedelta(days=7)
#INACTIVE_DELTA = timedelta(minutes=1) # тест
CHATS_JSON = "active_chats.json"
def load_active_chats():
if os.path.exists(CHATS_JSON):
with open(CHATS_JSON, "r") as f:
return json.load(f)
return {}
def save_active_chats(data):
with open(CHATS_JSON, "w") as f:
json.dump(data, f, indent=2)
active_chats = load_active_chats()
def load_db(chat_id):
filename = f"{chat_id}.json"
if os.path.exists(filename):
with open(filename, "r") as f:
return json.load(f)
return {}
def save_db(chat_id, data):
filename = f"{chat_id}.json"
with open(filename, "w") as f:
json.dump(data, f, indent=2)
def update_activity(chat_id, user_id):
db = active_chats[str(chat_id)]
if str(user_id) not in db:
db[str(user_id)] = {"last_activity": datetime.now(timezone.utc).isoformat(), "flags": []}
else:
db[str(user_id)]["last_activity"] = datetime.now(timezone.utc).isoformat()
save_db(chat_id, db)
def set_flag(chat_id, user_id, flag):
db = active_chats[str(chat_id)]
if str(user_id) not in db:
db[str(user_id)] = {"last_activity": datetime.now(timezone.utc).isoformat(), "flags": []}
if flag not in db[str(user_id)]["flags"]:
db[str(user_id)]["flags"].append(flag)
save_db(chat_id, db)
def remove_flag(chat_id, user_id, flag):
db = active_chats[str(chat_id)]
if str(user_id) in db and flag in db[str(user_id)]["flags"]:
db[str(user_id)]["flags"].remove(flag)
save_db(chat_id, db)
client = TelegramClient(session_name, api_id, api_hash)
@client.on(events.NewMessage(chats=None))
async def handler_update(event):
if not event.out:
return
chat_id = str(event.chat_id)
if chat_id not in active_chats:
return
user = await event.get_sender()
if user:
update_activity(chat_id, user.id)
@client.on(events.NewMessage(pattern=r"/addkick"))
async def cmd_addkick(event):
if not event.out:
return
chat_id = event.chat_id
try:
entity = await client.get_entity(chat_id)
except Exception:
return
db = load_db(chat_id)
async for member in client.iter_participants(entity):
uid = member.id
if str(uid) not in db:
db[str(uid)] = {"last_activity": datetime.now(timezone.utc).isoformat(), "flags": []}
async for member in client.iter_participants(entity):
uid = member.id
try:
perms = await client.get_permissions(entity, member)
if getattr(perms, "is_admin", False) or getattr(perms, "is_creator", False):
if "a" not in db[str(uid)]["flags"]:
db[str(uid)]["flags"].append("a")
except Exception:
continue
save_db(chat_id, db)
active_chats[str(chat_id)] = db
save_active_chats(active_chats)
print(f"✅ Чат {chat_id} активирован для кика молчунов.")
@client.on(events.NewMessage(pattern=r"/delkick"))
async def cmd_delkick(event):
if not event.out:
return
chat_id = str(event.chat_id)
if chat_id in active_chats:
del active_chats[chat_id]
save_active_chats(active_chats)
print(f"ℹ Чат {chat_id} деактивирован.")
@client.on(events.NewMessage(pattern=r"/whitelist"))
async def cmd_whitelist(event):
if not event.out:
return
chat_id = str(event.chat_id)
db = active_chats.get(chat_id)
if not db:
return
if event.is_reply:
target = await event.get_reply_message()
user_id = target.sender_id
set_flag(chat_id, user_id, "w")
print(f"🟢 Пользователь {user_id} добавлен в белый список чата {chat_id}.")
@client.on(events.NewMessage(pattern=r"/unwhitelist"))
async def cmd_unwhitelist(event):
if not event.out:
return
chat_id = str(event.chat_id)
db = active_chats.get(chat_id)
if not db:
return
if event.is_reply:
target = await event.get_reply_message()
user_id = target.sender_id
remove_flag(chat_id, user_id, "w")
print(f"🔴 Пользователь {user_id} удалён из белого списка чата {chat_id}.")
async def cleanup_chat(chat_id):
db = active_chats[chat_id]
now = datetime.now(timezone.utc)
try:
entity = await client.get_entity(int(chat_id))
except Exception:
return
async for member in client.iter_participants(entity):
uid = member.id
flags = db.get(str(uid), {}).get("flags", [])
if "a" in flags or "w" in flags:
continue
last_activity_str = db.get(str(uid), {}).get("last_activity")
if not last_activity_str:
update_activity(chat_id, uid)
continue
last_activity = datetime.fromisoformat(last_activity_str)
if now - last_activity > INACTIVE_DELTA:
try:
await client.kick_participant(entity, uid)
print(f"❌ Кикнут {uid} из чата {chat_id}")
except Exception:
continue
async def scheduled_loop():
while True:
if active_chats:
print(f"🚀 Запуск проверки активности для {len(active_chats)} чатов...")
for chat_id in list(active_chats.keys()):
await cleanup_chat(chat_id)
print("✅ Проверка завершена.")
else:
print("ℹ Нет активированных чатов, жду /addkick...")
await asyncio.sleep(CHECK_INTERVAL)
async def main():
await client.start()
print("✅ Userbot запущен!")
print(f"⏱ Проверка активности будет каждые {CHECK_INTERVAL} секунд")
asyncio.create_task(scheduled_loop())
await client.run_until_disconnected()
asyncio.run(main())
3. Подставляем вместо api_id = ваш api_id и api_hash = "ваш api_hash" свои данные.
4. Пишем в консоль python kick.py чтобы запустить бот.
5. Тестим работоспособность.
Демонстрация работы
Подводя итоги
Как видите, создать бота для кика мертвых душ не так уж и сложно. В особенности если вы следите за нашей Телегой и первыми узнаете о новых ботах для арбитража трафика. А на этом все — the конец.