feat(spamblock): add SpamBot spamblock check and language support

This commit is contained in:
2026-08-02 02:14:19 +05:00
parent c96a335352
commit 7e3b31f32a
4 changed files with 69 additions and 15 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ logger = logging.getLogger(__name__)
async def main(): async def main():
logger.debug("Инициализация Worker") logger.debug("Инициализация Worker")
async with Worker() as worker: async with Worker(lang_code="ru") as worker: # Russian for SpamBot check
logger.debug("Worker успешно инициализирован") logger.debug("Worker успешно инициализирован")
await worker.check_all() await worker.check_all()
logger.debug("Worker завершил работу") logger.debug("Worker завершил работу")
+42 -5
View File
@@ -27,6 +27,7 @@ class Result:
me: Optional[User] = None me: Optional[User] = None
stars: Optional[int] = None stars: Optional[int] = None
country: Optional[str] = None country: Optional[str] = None
spamblock: Optional[bool] = None
contacts: Optional[List[User]] = None contacts: Optional[List[User]] = None
chats: Optional[List[Chat]] = None chats: Optional[List[Chat]] = None
@@ -35,9 +36,10 @@ class Result:
class Checker: class Checker:
def __init__(self, path: Path, temp_path: Path): def __init__(self, path: Path, temp_path: Path, lang_code: str = "en"):
self.path = path self.path = path
self.temp_path = temp_path self.temp_path = temp_path
self.lang_code = lang_code
self.client = None self.client = None
logger.debug(f"Создание экземпляра Checker для пути: {path}") logger.debug(f"Создание экземпляра Checker для пути: {path}")
try: try:
@@ -53,7 +55,7 @@ class Checker:
logger.error("TDATA не инициализирована") logger.error("TDATA не инициализирована")
raise SessionInvalid() raise SessionInvalid()
try: try:
await self.__ensure_client() await self.__ensure_client(lang_code=self.lang_code)
except (OpenTeleException, Exception) as e: except (OpenTeleException, Exception) as e:
logger.error(f"Не удалось инициализировать клиент: {e}") logger.error(f"Не удалось инициализировать клиент: {e}")
raise SessionInvalid() raise SessionInvalid()
@@ -68,10 +70,10 @@ class Checker:
except Exception as e: except Exception as e:
logger.warning(f"Ошибка при отключении клиента: {e}") logger.warning(f"Ошибка при отключении клиента: {e}")
async def __ensure_client(self): async def __ensure_client(self, lang_code: str = "en"):
if self.client is None: if self.client is None:
logger.debug("Конвертация TDATA в Telethon клиент") logger.debug(f"Конвертация TDATA в Telethon клиент с языком '{lang_code}'")
self.client = await self.desktop.convert() self.client = await self.desktop.convert(lang_code=lang_code)
logger.debug("Telethon клиент успешно создан") logger.debug("Telethon клиент успешно создан")
async def check_stars(self, me: User) -> int: async def check_stars(self, me: User) -> int:
@@ -160,6 +162,39 @@ class Checker:
logger.warning(f"Не удалось проверить админские права: {e}") logger.warning(f"Не удалось проверить админские права: {e}")
return [] return []
async def check_spamblock(self) -> bool:
logger.debug("Проверка spamblock через @SpamBot")
try:
await self.client.send_message("@SpamBot", "/start")
logger.debug("Отправлено сообщение /start в @SpamBot")
# Ждем ответ от SpamBot
import asyncio
await asyncio.sleep(2)
# Получаем последние сообщения от SpamBot
messages = await self.client.get_messages("@SpamBot", limit=1)
if messages and len(messages) > 0:
response_text = messages[0].message
logger.debug(f"Ответ от SpamBot: {response_text[:50]}...")
# Проверяем, содержит ли ответ текст об отсутствии ограничений
if "свободен от каких-либо ограничений" in response_text.lower():
logger.debug("Аккаунт не имеет spamblock")
return False
else:
logger.debug("Аккаунт имеет spamblock")
return True
else:
logger.warning("Не удалось получить ответ от SpamBot")
return None
except Exception as e:
logger.warning(f"Не удалось проверить spamblock: {e}")
return None
async def check_all(self) -> Result: async def check_all(self) -> Result:
logger.debug("Начало полной проверки аккаунта") logger.debug("Начало полной проверки аккаунта")
try: try:
@@ -172,6 +207,7 @@ class Checker:
stars = await self.check_stars(me=me) stars = await self.check_stars(me=me)
country = await self.check_country(me=me) country = await self.check_country(me=me)
spamblock = await self.check_spamblock()
contacts = await self.check_contacts() contacts = await self.check_contacts()
chats = await self.check_chats() chats = await self.check_chats()
channels = await self.check_channels(chats=chats) if chats else [] channels = await self.check_channels(chats=chats) if chats else []
@@ -184,6 +220,7 @@ class Checker:
me=me, me=me,
stars=stars, stars=stars,
country=country, country=country,
spamblock=spamblock,
contacts=contacts, contacts=contacts,
chats=chats, chats=chats,
channels=channels, channels=channels,
+3 -3
View File
@@ -107,7 +107,7 @@ class TDATA:
logger.debug("Отключение клиента после валидации") logger.debug("Отключение клиента после валидации")
await client.disconnect() await client.disconnect()
async def convert(self) -> TelegramClient: async def convert(self, lang_code: str = "en") -> TelegramClient:
logger.debug("Начало конвертации TDATA в Telethon сессию") logger.debug("Начало конвертации TDATA в Telethon сессию")
if not await self.validate(): if not await self.validate():
logger.error("TDATA невалидна, конвертация невозможна") logger.error("TDATA невалидна, конвертация невозможна")
@@ -116,9 +116,9 @@ class TDATA:
tempPath = self.__gen_session_path() tempPath = self.__gen_session_path()
try: try:
logger.debug(f"Создание Telethon сессии по пути '{tempPath}'") logger.debug(f"Создание Telethon сессии по пути '{tempPath}' с языком '{lang_code}'")
client = await self.desktop.ToTelethon( client = await self.desktop.ToTelethon(
session=tempPath, flag=UseCurrentSession, api=self.api session=tempPath, flag=UseCurrentSession, api=self.api, lang_code=lang_code
) )
logger.debug("Валидация созданной сессии") logger.debug("Валидация созданной сессии")
+23 -6
View File
@@ -16,17 +16,23 @@ class Worker:
input_path: str = "tdata", input_path: str = "tdata",
output_path: str = "data", output_path: str = "data",
temp_path: str = "temp", temp_path: str = "temp",
lang_code: str = "en",
): ):
logger.debug(f"Инициализация Worker с путями: input={input_path}, output={output_path}, temp={temp_path}") logger.debug(
f"Инициализация Worker с путями: input={input_path}, output={output_path}, temp={temp_path}, lang={lang_code}"
)
self.input_path = Path(input_path).absolute() self.input_path = Path(input_path).absolute()
self.output_path = Path(output_path).absolute() self.output_path = Path(output_path).absolute()
self.temp_path = Path(temp_path).absolute() self.temp_path = Path(temp_path).absolute()
self.lang_code = lang_code
self.valid_path = self.output_path.joinpath("valid") self.valid_path = self.output_path.joinpath("valid")
self.invalid_path = self.output_path.joinpath("invalid") self.invalid_path = self.output_path.joinpath("invalid")
self.all_path = self.valid_path.joinpath("all.txt") self.all_path = self.valid_path.joinpath("all.txt")
logger.debug(f"Пути настроены: valid={self.valid_path}, invalid={self.invalid_path}") logger.debug(
f"Пути настроены: valid={self.valid_path}, invalid={self.invalid_path}"
)
async def __aenter__(self): async def __aenter__(self):
logger.debug("Вход в контекстный менеджер Worker") logger.debug("Вход в контекстный менеджер Worker")
@@ -105,10 +111,15 @@ class Worker:
logger.debug(f"Не удалось получить флаг для страны '{result.country}': {e}") logger.debug(f"Не удалось получить флаг для страны '{result.country}': {e}")
flag = "🌐" flag = "🌐"
spamblock_status = "unknown"
if result.spamblock is not None:
spamblock_status = "true" if result.spamblock else "false"
return ( return (
f"👤 [{flag} {result.country}] {result.me.phone}{result.me.id}\n" f"👤 [{flag} {result.country}] +{result.me.phone}{result.me.id}\n"
f"⭐️ {result.stars}\n" f"⭐️ {result.stars}\n"
f"💎 Premium: {'true' if result.me.premium else 'false'}\n" f"💎 Premium: {'true' if result.me.premium else 'false'}\n"
f"🚫 Spamblock: {spamblock_status}\n"
f"👥 {len(result.chats)}/{len(result.contacts)}\n" f"👥 {len(result.chats)}/{len(result.contacts)}\n"
f"🍀 {len(result.admin_channels)}" f"🍀 {len(result.admin_channels)}"
) )
@@ -162,11 +173,17 @@ class Worker:
logger.info(f"Проверка TDATA: {tdata.name}") logger.info(f"Проверка TDATA: {tdata.name}")
try: try:
async with Checker(path=tdata_absolute, temp_path=self.temp_path) as checker: async with Checker(
path=tdata_absolute, temp_path=self.temp_path, lang_code=self.lang_code
) as checker:
result = await checker.check_all() result = await checker.check_all()
logger.info(f"Проверка завершена: {result.me.first_name} (+{result.me.phone})") logger.info(
self.__save_valid(user_id=result.me.id, result=result, tdata=tdata_absolute) f"Проверка завершена: {result.me.first_name} (+{result.me.phone})"
)
self.__save_valid(
user_id=result.me.id, result=result, tdata=tdata_absolute
)
except SessionInvalid: except SessionInvalid:
logger.warning(f"TDATA невалидна: {tdata.name}") logger.warning(f"TDATA невалидна: {tdata.name}")