Проект: Телеграм-антиспам для каждого и каждой  Публичный пост
7 февраля 2025  590
Телеграм-антиспам для каждого и каждой
https://github.com/illright/telegram-antispam

Картинка сгенерирована с помощью Gemini

Вастрик.Клубу уже известен один бот для борьбы со спамом в Телеграме, но мне кажется, мне есть, что добавить в этой сфере.

Короче, в чём отличие?

  • Упор на бесплатный бездумный самостоятельный хостинг
  • Классификация с помощью ML, но открытой моделью
  • Минимум кода + навигатор по коду в readme, чтоб все могли прочитать и удостовериться, что бот делает именно то, что должен

Контекст и почему не хватает существующих решений

Я — администратор довольно крупного чата (5к участников) в Телеграм. Спам в этот чат поступает регулярно, и до создания бота я и другие админы удаляли спам вручную + была какая-то защита от Shieldy с помощью капчи.

Этот чат мультиязычный, что представляет некоторую проблему для капчи — требование ввести её поступает в топик русского языка, и только на одном языке. Не хотелось бы оттолкнуть нерусскоговорящих от нашего сообщества просто потому что они пропустили момент, когда надо было ввести капчу.

Антиспам-ботов в Телеграме есть немало, и некоторые из них ещё и платные. Чат никак не монетизируется, поэтому мне не очень хотелось платить, а бесплатных ботов надо ещё поискать, и в любом случае, этим ботам нужно ещё и доверять. Когда речь идет про модерацию и доступ ко всем сообщениям, мой порог необходимого доверия очень высокий, и любого бота с подворотни я бы в свои чаты добавлять не стал.

А задача-то, по факту, не очень сложная в плане кода, главное — найти классификатор сообщений, или хотя бы датасет спама, на котором можно было бы натренировать свой. На тот момент мне не было известно про https://lols.bot/, а других датасетов мне найти не удалось. Удалось, однако, найти открытый классификатор ruSpamNS на Hugging Face, разработанный NeuroSpaceX и лицензированный под CC-BY-NC-4.0.

В общем, сел писать своего бота :)

Дизайн-решения

Раз уж я пишу бота сам, то в моих руках все карты. Дизайн-решения я принимал, исходя из своих склонностей к движению FOSS (free open-source software) и этических соображений при работе с AI. Получились следующие требования к проекту:

  • Код должен быть открытым, но под не слишком расслабленной лицензией (AGPL-3.0)
  • Бота должно быть возможно использовать, никого не ставив в известность
  • Код должен быть насколько можно простым и читаемым, чтоб обеспечить доверие минимальными усилиями
  • Бота должно быть легко захостить самостоятельно с минимальными требуемыми ресурсами
  • Решения, которые принимает бот, должны быть видны человеку, чтоб можно было вмешаться
  • Бот должен сделать всё возможное, чтоб обеспечить забаненным возможность оспорить решение
  • Не стоит использовать LLM для классификации, это чересчур ресурсозатратно
  • Не стоит проверять каждое сообщение, достаточно проверять лишь первое

Выбор стека и хостинга

Ранее я писал ботов на Python, которые хостились на выделенных серверах и работали круглосуточно (в режиме поллинга). Затем в какой-то момент мне понадобилось написать супер-маленького утилитарного бота, которому бы поступали запросы раз в месяц, и ради этого не хотелось держать целый сервер, а тем более, платить за него :D. Решил хостить на Cloudflare Workers в режиме веб-хука, но тогда пришлось переписать бота на TypeScript.

Когда пришло время выбирать стек для этого антиспам-бота, я по привычке потянулся за TypeScript, чтоб захостить бесплатно на Cloudflare. Прикинув, я осознал, что непонятно, где хранить файл классификатора (~100 МБ в самой маленькой форме). Не хотелось скачивать его каждый раз, когда надо проверить сообщение, и не хотелось долго возиться с экосистемой Cloudflare и их хранилищами. Тем более, что я уже тогда поставил себе дополнительную цель — дать другим возможность тоже легко захостить этого бота.

Так я случайно наткнулся на Modal — бессерверные функции на Python c GPU и бесплатным тарифом. Подойдет! Таким образом, выбор снова пал на Python, с aiogram в качестве библиотеки бота и библиотек Hugging Face для работы с классификатором.

Изначально я использовал GPU-возможности Modal, но потом поэкспериментировал с обычной CPU и понял, что GPU тут, в целом, и не нужен. Самое длительное время анализа сообщения — 2.3 секунды, а в среднем анализ занимает 0.5 секунды. Главный источник задержки — запуск функции, он в хорошем случае занимает 1-2 секунды, но иногда может и 30 секунд занять. Не знаю, с чем это связано, может быть, с нагрузкой и капасити Modal.

Сейчас бот в месяц расходует 15 центов из доступных ежемесячно кредитов на 30 долларов, так что при желании я мог бы этим ботом покрывать ещё большое множество чатов.

С какими самыми неожиданными трудностями пришлось столкнуться?

Когда у тебя на руках полный контроль над поведением бота, а на твоих глазах происходит спам в новой парадигме, очень сложно удержать верность принципу простоты кода — хочется обвесить бота функциями по борьбе со всей несправедливостью! Иногда это доходило до абсурда.

Однажды я обнаружил интересный вид спама — спам реакциями. Спамер заходит в чат посреди ночи и без разбору проставляет сердечки на недавние сообщения, и затем уходит из чата навсегда. Что интересно, спамер ставит не больше одного сердечка на каждого пользователя — видимо, чтоб максимизировать внимание к себе. На аватарке спамерского аккаунта, как правило, фото конвенционально красивой девушки, а в био — ссылка. Самое обидное в такой форме спама то, что ему нельзя эффективно противостоять — нельзя удалить с сообщения реакцию, даже если ты админ, а отреагировавший пользователь вышел из чата. И банить аккаунт тоже нет смысла — он всё равно уже не вернётся. И пожаловаться Телеграму нельзя — можно только на сообщение. Гениальная схема, однако.

Тут понеслось. Я начал думать, как бы тут свершить правосудие, и пришёл к тому, что бот будет банить пользователей, которые ещё не прошли проверку на сообщение, и которые поставили 2 реакции в течение 30 секунд. Так я бы смог хотя бы минимизировать урон от этих злодеев :D. Полёт был нормальный, я видел в логах несколько успешных банов, радовался. Потом, однако, волна таких спамеров сошла на нет, и пошли случайные баны реальных пользователей, которые просто соглашались с тем, что писалось в чате.

В общем, выпилил я эту фичу.

P.S. Самое абсурдное в этой ситуации (помимо моей борьбы) было то, с какой целью эти спамеры действовали. В био спам-аккаунтов была ссылка на Телеграм-канал с… порно? казино? криптой? Нет, с рецептами еды. Я полистал этот канал, там реально были просто видео-рецепты (скорее всего, сворованные с тематических сайтов), и в этих видео не было ничего подозрительного. Также там у каждого рецепта ссылка на текстовую версию, где описаны только ингредиенты. Я, честно, до сих пор репу чешу насчет того, зачем существует этот канал. Моя главная теория — это канал на продажу с накрученным количеством подписчиков, чтоб можно было распространять пропаганду? Если интересно посмотреть на этот канал, напишите мне в личку, я вам его скину.

Нужны ли какие-то советы или помощь Клуба?

Пользуйтесь сами и распространите! Искать анти-спам ботов оказалось весьма непросто, особенно найти первую наводку, дальше уже легче. Я считаю, что не видеть спам — фундаментальное право интернет-безопасности, и пока Телеграм не может (или не хочет?) исправить эту ситуацию, нам остаётся лишь бороться со спамом самим.

Если попробуете — дайте, пожалуйста, фидбек о процессе настройки! Я постарался сделать его максимально коротким, но для этого пришлось добавить предусловие — чтоб было комфортно работать с терминалом. Я буду и дальше стараться упростить этот процесс, чтоб максимально демократизировать хостинг этого бота, и любые предложения приветствуются :)

Аватар Лев Челядинов
Лев Челядинов @illright
Фронтенд-разработчикPromaton
📍Амстердам, Нидерланды

https://github.com/illright
https://t.me/illright

23.999 года, не очень люблю соц. сети, очень люблю опен-сорс разработку. Развиваю проект Feature-Sliced Design.

Из увлечений — шаффл-танцы и умный дом

Связанные посты
9 комментариев 👇
Аня Боронина Дата сайентистка и феминистка 6 февраля в 23:26

а я, которую просили специально писать спам-сообщения в группу на 5к человек, чтобы тестировать этого самого бота, получила ноль внимания в этой истории.....
понятно, вклад простых работяг опять остался недооценён

  Развернуть 1 комментарий

Больше антиспам ботов!

Круто, молодец. Пытался считать сколько false positive сейчас?

Пытался бороться с "шлюхоботами", которые пишут адекватные ответы с помощью чатгпт, но на аватарке/в био всякие онлифансы и прочее?
Видел про тех, кто ставит реакции, но по моему опыту это редкость

  Развернуть 1 комментарий

@TiraelSedai, случайные баны невинных людей были в начале, но я добавил лёгкий тюн через "хорошие" слова в тематике чата, в котором работает бот. Если в сообщении встречается "хорошее" слово, проверка скипается. Последние несколько месяцев не было ни единого случайного бана :)

Насчёт "шлюхоботов" — не пытался как-то направленно с этим бороться. В моем чате они появляются очень редко, и поэтому мне не влом забанить их вручную. Но автор классификатора разрабатывает собственного бота, бесплатного, но с закрытыми исходниками, и у него есть такая функциональность.

  Развернуть 1 комментарий
Egor Suvorov Программист/преподаватель C++ 7 февраля в 10:43

Реакции можно репортить. По крайней мере в десктопной версии: правой кнопкой на реакцию, левой кнопкой на профиль, открывается профиль. Но в отличие от других способов открывания профиля, в этот раз есть кнопка вроде "BAN AND REPORT" под "SEND MESSAGE".

  Развернуть 1 комментарий

@yeputons, ого, действительно, спасибо! Не представляю, как это можно узнать, но теперь буду знать :)

  Развернуть 1 комментарий

оч прикольно видеть использование Modal в не-стартап контексте!

прорекламирую другого бота, которого мы используем аж в двух группах на 8к человек суммарно: https://github.com/umputun/tg-spam

отдельный классный бонус -- можно указать ему админский чат, в который он будет писать кого забанил и почему (вероятность спама по нескольким критериям), с возможностью это решение отменить прям кнопкой под сообщением.

  Развернуть 1 комментарий

@marinegor, не сталкивался с Modal раньше. Это примерно как AWS Lambda?

  Развернуть 1 комментарий

Сделай, пожалуйста, саас версию бота, чтобы быстро протестить его на своем чате.

Я бы заплатил сколько то рублей за месяц теста, с мыслью что потом перейду на хостед (но вероятно забил бы и остался на подписке).

Можно не пилить прям сервис с лендингом, просто дай указания и скажи куда заплатить доллар.

  Развернуть 1 комментарий

@rkn, учитывая, как мало ресурсов потребляет бот на моем чате, готов захостить твой чат на своем инстансе бесплатно :) Это будет проще, чем возиться с сервисом и оплатой. Скинь мне, пожалуйста, в Телеграм ссылку на свой чат

  Развернуть 1 комментарий

😎

Автор поста открыл его для большого интернета, но комментирование и движухи доступны только участникам Клуба

Что вообще здесь происходит?


Войти  или  Вступить в Клуб