Загрузка данных
import asyncio
from telethon import TelegramClient
from telethon.errors import (
FloodWaitError,
UsernameInvalidError,
UsernameNotOccupiedError,
ChannelPrivateError,
)
# Твои личные ключи
API_ID = 35901392
API_HASH = "08ab29c9da01a4f3eaf10f3baa7200f2"
INPUT_FILE = "usernames.txt"
# Файлы для категорий
CAT_1 = "cat_1_bec_o365.txt"
CAT_2A = "cat_2a_active_hacking.txt"
CAT_2B = "cat_2b_ads_hacking.txt"
CAT_3 = "cat_3_unrelated_russian_inactive.txt"
CAT_4 = "cat_4_dead_groups.txt"
# Английские ключевые слова для Категории 1 (O365)
KW_O365 = [
"o365",
"office 365",
"microsoft 365",
"outlook",
"smtp",
"imap",
"exchange",
"mail access",
"logs",
"imap logs",
"mail pass",
"mailbase",
"azure",
"entra id",
"office365",
]
# Английские ключевые слова для Категории 2 (Хакинг / Фрод)
KW_HACKING = [
"hacking",
"exploit",
"fraud",
"carding",
"stealer",
"cves",
"pentest",
"ddos",
"botnet",
"phishing",
"malware",
"credentials",
"combolists",
]
# Ключевые слова для разделения на рекламные (2b)
KW_ADS = [
"selling",
"buying",
"price",
"pm",
"escrow",
"vcc",
"for sale",
"shop",
"store",
]
async def write_file(filename, text):
with open(filename, "a", encoding="utf-8") as f:
f.write(text + "\n")
def is_russian(text):
# Проверка на кириллицу
return any("\u0400" <= char <= "\u04ff" for char in text.lower())
async def main():
# Очищаем файлы перед запуском
for filename in [CAT_1, CAT_2A, CAT_2B, CAT_3, CAT_4]:
open(filename, "w", encoding="utf-8").close()
try:
with open(INPUT_FILE, "r", encoding="utf-8") as f:
usernames = [line.strip().lstrip("@") for line in f if line.strip()]
except FileNotFoundError:
print(f"Ошибка: Не найден файл {INPUT_FILE}!")
return
print(
f"Загружено {len(usernames)} групп. Запуск автоматической сортировки...\n"
)
async with TelegramClient("session_checker", API_ID, API_HASH) as client:
for idx, username in enumerate(usernames, 1):
while True:
try:
entity = await client.get_entity(username)
title = getattr(entity, "title", "") or ""
about = ""
try:
full_info = await client.get_full_info(entity)
about = getattr(full_info.full_chat, "about", "") or ""
except Exception:
pass
text_to_check = f"{title} {about}"
text_lower = text_to_check.lower()
# 1. Проверка на Категорию 1 (O365 / BEC) — строго английский текст
if not is_russian(text_to_check) and any(
kw in text_lower for kw in KW_O365
):
await write_file(CAT_1, f"@{username} | {title}")
print(
f"[{idx}/{len(usernames)}] [Категория 1 (O365)]: @{username}"
)
break
# 2. Проверка на Категорию 2 (Хакинг / Фрод) — строго английский текст
if not is_russian(text_to_check) and any(
kw in text_lower for kw in KW_HACKING
):
if any(ad in text_lower for ad in KW_ADS):
await write_file(CAT_2B, f"@{username} | {title}")
print(
f"[{idx}/{len(usernames)}] [Категория 2b (Реклама)]: @{username}"
)
else:
await write_file(CAT_2A, f"@{username} | {title}")
print(
f"[{idx}/{len(usernames)}] [Категория 2a (Актив)]: @{username}"
)
break
# 3. Всё остальное: русские группы, неактивные, крипта, мусор, неопознанные темы
await write_file(CAT_3, f"@{username} | {title}")
print(
f"[{idx}/{len(usernames)}] [Категория 3 (Рус/Неподходящие/Мусор)]: @{username}"
)
break
except (
UsernameInvalidError,
UsernameNotOccupiedError,
ValueError,
ChannelPrivateError,
):
# 4. Мертвые группы (без оплаты)
await write_file(CAT_4, f"@{username}")
print(
f"[{idx}/{len(usernames)}] [Категория 4 (Мертвая)]: @{username}"
)
break
except FloodWaitError as e:
print(f"\n[!] Лимит Telegram. Ждем {e.seconds} сек...")
await asyncio.sleep(e.seconds + 2)
except Exception:
await write_file(CAT_4, f"@{username}")
print(
f"[{idx}/{len(usernames)}] [Категория 4 (Ошибка/Мертвая)]: @{username}"
)
break
await asyncio.sleep(1.5)
print("\n" + "=" * 40)
print("Сортировка завершена!")
print(f"Результаты разложены по файлам: {CAT_1}, {CAT_2A}, {CAT_2B}, {CAT_3}, {CAT_4}")
print("=" * 40)
if __name__ == "__main__":
asyncio.run(main())