Картинка сгенерирована с помощью 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. Самое абсурдное в этой ситуации (помимо моей борьбы) было то, с какой целью эти спамеры действовали. В био спам-аккаунтов была ссылка на Телеграм-канал с… порно? казино? криптой? Нет, с рецептами еды. Я полистал этот канал, там реально были просто видео-рецепты (скорее всего, сворованные с тематических сайтов), и в этих видео не было ничего подозрительного. Также там у каждого рецепта ссылка на текстовую версию, где описаны только ингредиенты. Я, честно, до сих пор репу чешу насчет того, зачем существует этот канал. Моя главная теория — это канал на продажу с накрученным количеством подписчиков, чтоб можно было распространять пропаганду? Если интересно посмотреть на этот канал, напишите мне в личку, я вам его скину.
Нужны ли какие-то советы или помощь Клуба?
Пользуйтесь сами и распространите! Искать анти-спам ботов оказалось весьма непросто, особенно найти первую наводку, дальше уже легче. Я считаю, что не видеть спам — фундаментальное право интернет-безопасности, и пока Телеграм не может (или не хочет?) исправить эту ситуацию, нам остаётся лишь бороться со спамом самим.
Если попробуете — дайте, пожалуйста, фидбек о процессе настройки! Я постарался сделать его максимально коротким, но для этого пришлось добавить предусловие — чтоб было комфортно работать с терминалом. Я буду и дальше стараться упростить этот процесс, чтоб максимально демократизировать хостинг этого бота, и любые предложения приветствуются :)
а я, которую просили специально писать спам-сообщения в группу на 5к человек, чтобы тестировать этого самого бота, получила ноль внимания в этой истории.....
понятно, вклад простых работяг опять остался недооценён
Больше антиспам ботов!
Круто, молодец. Пытался считать сколько false positive сейчас?
Пытался бороться с "шлюхоботами", которые пишут адекватные ответы с помощью чатгпт, но на аватарке/в био всякие онлифансы и прочее?
Видел про тех, кто ставит реакции, но по моему опыту это редкость
Реакции можно репортить. По крайней мере в десктопной версии: правой кнопкой на реакцию, левой кнопкой на профиль, открывается профиль. Но в отличие от других способов открывания профиля, в этот раз есть кнопка вроде "BAN AND REPORT" под "SEND MESSAGE".
оч прикольно видеть использование Modal в не-стартап контексте!
прорекламирую другого бота, которого мы используем аж в двух группах на 8к человек суммарно: https://github.com/umputun/tg-spam
отдельный классный бонус -- можно указать ему админский чат, в который он будет писать кого забанил и почему (вероятность спама по нескольким критериям), с возможностью это решение отменить прям кнопкой под сообщением.
Сделай, пожалуйста, саас версию бота, чтобы быстро протестить его на своем чате.
Я бы заплатил сколько то рублей за месяц теста, с мыслью что потом перейду на хостед (но вероятно забил бы и остался на подписке).
Можно не пилить прям сервис с лендингом, просто дай указания и скажи куда заплатить доллар.