Update bot.py

parent b97f6b52
...@@ -30,19 +30,33 @@ active_users = {} ...@@ -30,19 +30,33 @@ active_users = {}
# Список спамных слов и фраз # Список спамных слов и фраз
SPAM_KEYWORDS = [ SPAM_KEYWORDS = [
# Финансовый и кредитный спам
"кредит", "займ", "ипотека", "долг", "быстрые деньги", "кредитная история", "погашение", "погасить долг", "без процентов",
"плохая кредитная история", "микрозайм", "рассрочка", "деньги в долг", "без отказа",
# Здоровье и БАДы
"омоложение", "избавиться от морщина", "чудо-средство", "волшебная таблетка", "исцеление", "лечение без врач", "без операция",
"навсегда вылечить", "секретное средство", "мощный эффект", "чистка организм", "сбросить вес", "секрет стройность",
"похудеть", "без диет", "без физическая нагрузка", "здоровье навсегда", "природное лекарство", "безопасное лечение", "детокс",
# Коммерческий спам # Коммерческий спам
"скидка", "акция", "мы снова", "спрос", "бонус", "витрина", "бесплатно","платить" , "купить", "покупать", "продать", "продажа", "дешево", "скидка", "акция", "мы снова", "спрос", "бонус", "витрина", "бесплатно","платить","монетизация" , "купить", "покупать", "продать", "продажа", "дешево",
"доставка", "магазин", "следить за новости", "реклама", "распродажа", "экономия", "дешевле", "недорого", "доставка", "магазин", "следить за новости", "реклама", "распродажа", "экономия", "дешевле", "недорого",
"спецпредложение", "уникальное предложение", "только сегодня", "лютая жиза", "мерч", "продукция", "коллекция", "спецпредложение","эксклюзивный предложение","мой тг канал", "уникальное предложение", "только сегодня", "лютая жиза", "мерч", "продукция", "коллекция",
# Работа # Работа
"удалённая работа", "бакс", "доллар", "$", "нужен человек", "нужен помощник", "вакансии", "удаленка","условия труда", "писать в лс", "удалённая работа","удалённая работа", "бакс", "доллар", "$", "нужен человек", "нужен помощник", "вакансии", "удаленка","условия труда", "писать лс", "писать в лс", "бабки", "пасивный заработок","без вложений",
# Мошенничество # Мошенничество
"лотерея", "быстрый выигрыш", "выигрыш", "приз", "деньги", "халява" "заработать", "прибыль", "заработок", "зп", "подработка", "легкий заработок", "лотерея", "быстрый выигрыш", "выигрыш", "приз", "деньги", "халява", "прибыль", "заработок", "зп", "подработка", "легкий заработок",
"мгновенно", "доход", "доход онлайн", "как заработать", "схема заработка", "мгновенно", "доход", "доход онлайн", "как заработать", "схема заработка",
"пассивный доход", "быстро заработать", "богатство", "всего за", "инвестировать", "инвестиция", "пассивный доход", "быстро заработать", "богатство", "всего за", "инвестировать", "инвестиция",
"биткоин", "криптовалюта", "forex", "деньги на карта", "дивиденд", "процент", "депозит", "выплата", "невероятный доход", "статус", "биткоин", "криптовалюта", "forex", "деньги на карта", "дивиденд", "процент", "депозит", "выплата", "невероятный доход", "статус","гарантированный доход", "секрет богатство", "без риск",
# Психология, манипуляции и самопомощь
"гипноз", "секрет уверенность", "как стать успешный", "формула успех", "психотренинг", "управление человек", "контроль над разум", "манипуляция", "техника влияния", "мгновенный успех",
"секрет богатый", "стать счастливый",
# Продажа услуг и мошеннические предложения # Продажа услуг и мошеннические предложения
"гадалка", "приворот", "заговор", "магия", "ритуал", "расклад таро", "ясновидение", "гадалка", "приворот", "заговор", "магия", "ритуал", "расклад таро", "ясновидение",
...@@ -50,7 +64,7 @@ SPAM_KEYWORDS = [ ...@@ -50,7 +64,7 @@ SPAM_KEYWORDS = [
"снять порчу", "порча", "снять порчу", "порча",
# Фишинг и подозрительные ссылки # Фишинг и подозрительные ссылки
"кликнуть сюда", "нажать сюда", "писать сюда", "переходить здесь", "переходить по ссылка", "перейти по ссылка", "кнопка", "кнопка ниже", "узнать больше", "узнать тут", "суперпредложение", "уникальный", "карта", "кликнуть сюда", "нажать сюда", "писать сюда", "переходите", "переходить здесь", "переходить по ссылка", "перейти по ссылка", "кнопка", "кнопка ниже", "узнать больше", "узнать тут", "суперпредложение", "уникальный", "карта",
# Иностранный спам # Иностранный спам
"discount", "free", "sale", "limited offer", "bitcoin", "crypto", "click here", "discount", "free", "sale", "limited offer", "bitcoin", "crypto", "click here",
...@@ -59,26 +73,26 @@ SPAM_KEYWORDS = [ ...@@ -59,26 +73,26 @@ SPAM_KEYWORDS = [
# Продвижение подписок, лайков и сервисов # Продвижение подписок, лайков и сервисов
"подписка", "раскрутка", "продвижение", "лайк", "подписчик", "просмотр", "подписка", "раскрутка", "продвижение", "лайк", "подписчик", "просмотр",
"отзыв", "рейтинг", "рейтинг магазин", "работа", "вакансия", "отзыв", "рейтинг", "рейтинг магазин", "вакансия",
"раскрутка аккаунт", "реферальная ссылка", "реферал", "экономия", "раскрутка аккаунт", "реферальная ссылка", "реферал", "экономия",
# Политический спам # Политический спам
"митинг", "партия", "агитация", "голосовать", "выборы", "кандидат", "поддержка", "митинг", "партия", "агитация", "голосовать", "выборы", "кандидат", "поддержка",
"голосование", "поддерживать мы", "голосование", "поддерживать мы", "убийство", "изнасилование", "секс", "для взрослых", "кража",
# Вредоносные URL # Вредоносные URL
".tinyurl", ".bitly", ".ly", ".click", ".top", ".app", ".info", ".xyz", ".vip", ".tinyurl", ".bitly", ".ly", ".click", ".top", ".app", ".info", ".xyz", ".vip",
".tk", ".pw", ".cc", ".link", ".tk", ".pw", ".cc", ".link",
# Общее (агрессивные призывы, массовая рассылка) # Общее (агрессивные призывы, массовая рассылка)
"добрый время сутки", "поделиться", "отправить", "регистрироваться по ссылка", "перейти", "переходить", "рассказать все", "срочно", "обязательно прочитать", "написать", "пересылать", "передать друг", "добрый время сутки", "поделиться", "отправить", "регистрироваться по ссылка" "рассказать все", "срочно", "обязательно прочитать", "написать", "пересылать", "передать друг",
# Контент, связанный с азартными играми # Контент, связанный с азартными играми
"время действовать", "пополнить", "счет", "джекпот", "игрок","азарт", "баланс", "казино", "розыгрыш", "ставка", "азартная игра", "рулетка", "выигрыш в казино","выигрывать", "промокод", "слоты", "подарок", "забрать подарок", "получить подарок", "время действовать", "пополнить", "счет", "джекпот", "игрок","азарт", "баланс", "казино", "розыгрыш", "ставка", "азартная игра", "рулетка", "выигрыш в казино","выигрывать", "промокод", "слоты", "подарок", "забрать подарок", "получить подарок",
"казино онлайн", "бесплатные фишки", "ставки на спорт", "играть", "победить", "победитель", "выигрывать", "фриспин", "получить выигрыш","casino", "без цензуры", "казино онлайн", "бесплатные фишки", "ставки на спорт", "играть", "победить", "победитель", "выигрывать", "фриспин", "получить выигрыш","casino", "без цензуры",
# Эмодзи, часто используемые в спаме # Эмодзи, часто используемые в спаме
"🎁", "🔥", "💸", "💰", "💎", "🤑", "🤩", "⚡", "⭐", "💥", "✅", "🏆", "✋", "💖", "💝", "⚔️", "🥇", "💯", "💳", "🔞" "🎁", "🔥", "💸", "💰", "💲", "💎", "🤑", "🤩", "⚡", "⭐", "💥", "✅", "🏆", "✋", "💖", "💝", "⚔️", "🥇", "💯", "💳", "🔞", "🥳", "😱"
] ]
def has_mixed_layout(text): def has_mixed_layout(text):
...@@ -100,6 +114,21 @@ def has_mixed_layout(text): ...@@ -100,6 +114,21 @@ def has_mixed_layout(text):
morph = MorphAnalyzer() morph = MorphAnalyzer()
# Регулярное выражение для распознавания эмодзи
emoji_pattern = re.compile("["
u"\U0001F600-\U0001F64F" # emoticons
u"\U0001F300-\U0001F5FF" # symbols & pictographs
u"\U0001F680-\U0001F6FF" # transport & map symbols
u"\U0001F700-\U0001F77F" # alchemical symbols
u"\U0001F780-\U0001F7FF" # Geometric Shapes Extended
u"\U0001F800-\U0001F8FF" # Supplemental Arrows-C
u"\U0001F900-\U0001F9FF" # Supplemental Symbols and Pictographs
u"\U0001FA00-\U0001FA6F" # Chess Symbols
u"\U0001FA70-\U0001FAFF" # Symbols and Pictographs Extended-A
u"\U00002702-\U000027B0" # Dingbats
u"\U0001F004-\U0001F0CF" # Playing Cards
"]+", flags=re.UNICODE)
def normalize_text_to_infinitive(text): def normalize_text_to_infinitive(text):
""" """
Приводит текст к нижнему регистру, нормализует слова до начальной формы, Приводит текст к нижнему регистру, нормализует слова до начальной формы,
...@@ -112,17 +141,20 @@ def normalize_text_to_infinitive(text): ...@@ -112,17 +141,20 @@ def normalize_text_to_infinitive(text):
# Приведение текста к единой форме Unicode (NFKC) # Приведение текста к единой форме Unicode (NFKC)
text = unicodedata.normalize("NFKC", text) text = unicodedata.normalize("NFKC", text)
text = re.sub(r'(\w)\.(\w)', r'\1 \2', text) # Точка внутри слова # Заменяем все знаки препинания и спецсимволы внутри слов на пробелы
text = ''.join(ch for ch in text if ch.isalnum() or ch.isspace() or emoji.is_emoji(ch)) text = re.sub(r'[\.,;!?"()\-:—/\\\[\]{}<>]', ' ', text) # Заменяем все знаки препинания на пробелы
text = re.sub(r'\s+', ' ', text) # Убираем лишние пробелы
# Приведение текста к нижнему регистру
text = text.lower()
text = re.sub(r'([.,!?])', r' \1 ', text) # Пробел вокруг пунктуации # Оставляем только алфавитные символы, цифры и эмодзи
# Убираем лишние пробелы text = ''.join(ch for ch in text if ch.isalnum() or ch.isspace() or emoji.is_emoji(ch))
text = re.sub(r'\s+', ' ', text).strip()
# Приведение к нижнему регистру # Токенизация
words = text.lower().split() words = text.split()
# Нормализация слов до начальной формы # Нормализация слов до начальной формы (с использованием морфологического анализатора)
normalized_words = [] normalized_words = []
for word in words: for word in words:
try: try:
...@@ -141,29 +173,56 @@ def preprocess_spam_keywords(keywords): ...@@ -141,29 +173,56 @@ def preprocess_spam_keywords(keywords):
SPAM_KEYWORDS = preprocess_spam_keywords(SPAM_KEYWORDS) SPAM_KEYWORDS = preprocess_spam_keywords(SPAM_KEYWORDS)
def extract_emojis(text): def extract_emojis(text):
return text.join(c for c in text if unicodedata.category(c).startswith('So')) #return text.join(c for c in text if unicodedata.category(c).startswith('So'))
return ''.join(c for c in text if emoji.is_emoji(c))
def is_spam(text): def is_spam(text):
"""Проверяет, содержит ли текст спам."""
# Нормализуем текст # Нормализуем текст
normalized_words = normalize_text_to_infinitive(text) normalized_words = normalize_text_to_infinitive(text)
# Извлекаем эмодзи
emojis = extract_emojis(text) emojis = extract_emojis(text)
emoji_count = len(emojis)
# Проверка, состоит ли сообщение только из эмодзи и длина >= 10
if len(text) >= 9 and all(char in emojis for char in text):
return True # Если все символы — эмодзи и длина >= 10, то это спам
# Извлекаем только спамные эмодзи из списка SPAM_KEYWORDS
emoji_count = sum(1 for emoji in emojis if emoji in SPAM_KEYWORDS)
# Добавляем эмодзи в нормализованный текст
normalized_words += emojis normalized_words += emojis
# Объединяем нормализованные слова в выражения длиной 1, 2 и 3 # Создание фраз из нормализованных слов
phrases = set() phrases = set()
for n in range(1, 4): for n in range(1, 4):
phrases.update(" ".join(normalized_words[i:i+n]) for i in range(len(normalized_words) - n + 1)) phrases.update(" ".join(normalized_words[i:i+n]) for i in range(len(normalized_words) - n + 1))
# Подсчитываем количество совпадений с ключевыми словами/выражениями ############
spam_count = sum(keyword in phrases for keyword in SPAM_KEYWORDS) spam_count = 0
spam_count = spam_count + emoji_count matched_keywords = [] # Список для хранения совпавших ключевых слов
for keyword in SPAM_KEYWORDS:
if keyword in phrases:
spam_count += 1
matched_keywords.append(keyword) # Добавляем совпавшее слово в список
spam_count += emoji_count # Учитываем только спамные эмодзи
# Выводим совпавшие ключевые слова для диагностики
if matched_keywords:
print(f"Обнаружены спамные ключевые слова: {', '.join(matched_keywords)}")
########
# Подсчитываем совпадения с ключевыми словами (и учитываем спамные эмодзи)
#spam_count = sum(keyword in phrases for keyword in SPAM_KEYWORDS)
#spam_count += emoji_count # Учитываем только спамные эмодзи
# Возвращаем True, если найдено два или более совпадений # Возвращаем True, если найдено два или более совпадений
return spam_count >= 2 return spam_count >= 2
def generate_math_problem(): def generate_math_problem():
"""Генерация простого математического примера.""" """Генерация простого математического примера."""
a = random.randint(1, 10) a = random.randint(1, 10)
...@@ -182,8 +241,8 @@ async def welcome_new_user(event: ChatMemberUpdated): ...@@ -182,8 +241,8 @@ async def welcome_new_user(event: ChatMemberUpdated):
welcome_message = await bot.send_message( welcome_message = await bot.send_message(
chat_id=event.chat.id, chat_id=event.chat.id,
text=f"Здравствуйте, {new_user.first_name}! Добро пожаловать в нашу группу!\n\n" text=f"Здравствуйте, {new_user.first_name}! Добро пожаловать в нашу группу!\n\n"
f"Нам необходимо удостовериться, что вы человек. Вот математический пример: {math_problem}\n" f"Нам необходимо удостовериться, что вы человек.\n"
f"Решите его, пожалуйста, в течение 1 минуты! В качестве ответа отправьте одно число." f"Решите математический пример в течение 2-х минут! В качестве ответа отправьте одно число.\n\n{math_problem}\n"
) )
# Сохраняем данные о пользователе # Сохраняем данные о пользователе
...@@ -205,8 +264,8 @@ async def welcome_new_user(event: ChatMemberUpdated): ...@@ -205,8 +264,8 @@ async def welcome_new_user(event: ChatMemberUpdated):
await check_answer(new_user.id) await check_answer(new_user.id)
async def check_answer(user_id): async def check_answer(user_id):
"""Проверка ответа пользователя через 1 минуту.""" """Проверка ответа пользователя через 2 минуты."""
await asyncio.sleep(60) await asyncio.sleep(120)
user_data = active_users.get(user_id) user_data = active_users.get(user_id)
if user_data and not user_data["user_answered"]: if user_data and not user_data["user_answered"]:
...@@ -261,18 +320,20 @@ async def handle_message(message: Message): ...@@ -261,18 +320,20 @@ async def handle_message(message: Message):
print(f"Ошибка при проверке статуса пользователя {message.from_user.id}. Ошибка: {e}") print(f"Ошибка при проверке статуса пользователя {message.from_user.id}. Ошибка: {e}")
text = message.text or message.caption or "" text = message.text or message.caption or ""
text = " ".join(normalize_text_to_infinitive(text)) # Убедимся, что это строка
# Проверка на смешанную раскладку # Проверка на смешанную раскладку
if text and has_mixed_layout(text): if text and has_mixed_layout(text):
try: try:
await message.delete() await message.delete()
print(f"Удалено сообщение с смешанной раскладкой от пользователя {message.from_user.id}: {message.text}") print(f"Удалено сообщение с смешанной раскладкой от пользователя {message.from_user.id}: {text}")
return return
except Exception as e: except Exception as e:
print(f"Ошибка при удалении сообщения с смешанной раскладкой. Ошибка: {e}") print(f"Ошибка при удалении сообщения с смешанной раскладкой. Ошибка: {e}")
# Проверка на мультимедиа (фото/видео) # Проверка на мультимедиа (фото/видео) и его подпись
if message.photo or message.video or message.document: if message.photo or message.video or message.document:
if text.strip(): # Проверяем, есть ли текст
try: try:
if is_spam(text): # Проверяем подпись к мультимедиа if is_spam(text): # Проверяем подпись к мультимедиа
await message.delete() await message.delete()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment