В Telegram-чатах и группах проблема спама и подозрительных сообщений стоит особенно остро. Боты-рассыльщики, мошенники и пользователи, пытающиеся обойти модерацию, используют различные уловки: скрытые ссылки, текст с заменёнными символами (например, "пр4ивет"), флуд повторяющимися символами и другие методы.
SuspiciousMessagesMiddleware — это middleware для Telegram-бота, который автоматически анализирует сообщения в группах и супергруппах, выявляет подозрительный контент и принимает меры: удаляет спам, уведомляет участников чата и сохраняет контекст переписки.
В этой статье разберём:
- Как работает этот промежуточный слой?
- Какие сообщения считаются подозрительными?
- Как можно кастомизировать фильтры под свои задачи?
🛠 Как это работает?
1. Проверка входящих сообщений
message = event.message or event.edited_message
if not message:
return await handler(event, data)
# Пропускаем служебные сообщения от Telegram
if self._is_service_message(message):
return await handler(event, data)
if message.chat.type not in [ChatType.GROUP, ChatType.SUPERGROUP]:
return await handler(event, data)
Middleware анализирует только:
- Обычные и отредактированные сообщения (message или edited_message).
- Сообщения в группах и супергруппах (ChatType.GROUP, ChatType.SUPERGROUP).
- Игнорирует служебные уведомления (вход/выход участников, закреплённые сообщения и т. д.).
def _is_service_message(self, message: Message) -> bool:
"""Проверяет, является ли сообщение служебным от Telegram"""
# Сообщения без отправителя (системные)
if not message.from_user:
return True
# Пользователь Telegram имеет ID 777000 (служебные уведомления)
if message.from_user.id == 777000:
return True
# Сообщения о входе в чат, закреплении и т.д.
if message.new_chat_members or message.left_chat_member or message.pinned_message:
return True
return False
2. Детекция подозрительного контента
Метод _is_suspicious проверяет текст на:
🔸 Цифры внутри слов ("пр4ивет", "Tele5ram")
🔸 Повторяющиеся символы ("привеееет!!!" — более 3 одинаковых подряд)
🔸 Разделённые пробелами буквы ("п р и в е т")
🔸 Отсутствие пробелов (слишком длинные слитные слова)
🔸 Спецсимволы внутри слов ("пр@ивет", "tele#gram")
def _is_suspicious(self, text: str) -> bool:
"""Определяет подозрительные сообщения"""
# Цифры среди букв в слове (например "пр4вет")
if re.search(r'\b\w+\d+\w+\b', text):
return True
# Повторяющиеся символы (более 3 подряд)
if any(len(list(g)) > 3 for _, g in groupby(text.lower())):
return True
# Слова с разделёнными пробелом буквами (п р и в е т)
if re.search(r'(?:^|\s)([а-яa-z]\s){2,}[а-яa-z](?:$|\s)', text.lower()):
return True
# Предложения без пробелов (длиннее 3 символов)
if len(text) > 3 and ' ' not in text:
return True
# Спецсимволы внутри слов
if re.search(r'\b\w+[^\w\s]\w+\b', text):
return True
return False
3. Действия при обнаружении спама
- Сообщение удаляется.
- Участники чата получают уведомление вида:
"⚠️ [User] отправил подозрительное сообщение (возможен спам): [текст]" - Сохраняется reply_to_message, чтобы не терялся контекст обсуждения.
# Сохраняем reply_to_message
reply_to_message_id = message.reply_to_message.message_id if message.reply_to_message else None
try:
await message.delete()
logger.info(f"Deleted suspicious message in chat {message.chat.id}")
except Exception as e:
logger.error(f"Failed to delete suspicious message: {e}")
return await handler(event, data)
user_mention = message.from_user.mention_html() if message.from_user else "Аноним"
await self.bot.send_message(
chat_id=message.chat.id,
text=f"⚠️ {user_mention} отправил подозрительное сообщение (возможен спам):\n{text}",
parse_mode="HTML",
reply_to_message_id=reply_to_message_id
)
💡 Практическое применение
Такой middleware полезен для:
🔹 Борьбы со спам-ботами (автоудаление рекламных сообщений).
🔹 Предотвращения обхода цензуры (фильтрация слов с заменёнными символами).
🔹 Защиты от флуда (повторяющиеся символы, CAPS).
🔹 Поддержания порядка в чатах без постоянного вмешательства админов.
🔗 Готовое решение: Полный исходный код доступен в моем GitHub-репозитории
⚙️ Настройка и расширение функционала
Вы можете доработать детектор, добавив свои правила:
def _is_suspicious(self, text: str) -> bool:
# Базовые проверки...
if "реклама" in text.lower() and "http" in text.lower():
return True
if any(blacklisted_word in text.lower() for blacklisted_word in ["купить", "продам"]):
return True
return False
Также можно:
✅ Добавить анализ медиафайлов (проверка подписей к изображениям).
✅ Внедрить whitelist — список пользователей, которых не проверять.
✅ Интегрировать с внешними антиспам-API (например, для проверки ссылок).
🚀 Готовые решения от ELSE
Нужен мощный бот-модератор для Telegram с индивидуальной настройкой?
Команда ELSE разрабатывает:
✔ Умные антиспам-системы для чатов любого размера.
✔ Кастомные правила модерации под ваши требования.
✔ Интеграцию с внешними сервисами (проверка ссылок, анализ изображений).
🔗 Оставьте заявку на else.com.ru и получите бота с защитой от спама!
Теги:
#Telegram #Программирование #Боты #Кибербезопасность #Антиспам #Python #РазработкаБотов #МодерацияЧатов