Спам заколебал.
Нет, серьёзно. Эта проблема никак не уникальна для Клубных чатов, просто в телеграме очень плохой антиспам.
Если вы сидите хотя бы одном большом чате, то наверняка видите что-то вроде этого каждый божий день
Зачем?
Не каждый чат из Нетворка закрыт специальной ссылочкой. Некоторые чаты изначально были сделаны открытыми, в них может вступить каждый, например Наука и Книги.
И в них постоянно кто-то предлагал закладки, "удалённый заработок", фотки голых девушек и что ещё там модно нынче у спамеров.
Кажется, что проблема тривиальная, нужно просто поставить капчу на вход и дело в кармане.
Капча так капча
Сначала в качестве капчи я сделал требование #intro.
Так сказать, совместить приятное с полезным, - и спамеров отвадить, и узнать сразу о человеке который только что залетел в чат во что он играет (для Игр) или что он читает (для Книг).
Клубней бот просто вежливо просил написать интро, но не выкидывал тех, кто не написал.
К сожалению, идея не выгорела - люди в основном пишут короткие отписки, действительно полезное интро было у единиц. Капчу заменил на простой "ткни в нужную кнопку".
Если вы давно в Клубе то видели бота "метаадмин" - и тысячу подобных.
Но не тут-то было
Телеграм иногда просто берёт и не присылает эвент "юзер зашёл в чат". Особенно для больших чатов. Особенно для премиум-юзеров. У меня практически шапочка из фольги, но мне кажется что Дуров так мотивирует спамеров покупать премиум, потому что с премиумом спамится гораздо лучше.
Прикручиваем ML
В подкасте Радио-Т Умпутун рекламировал своего бота, затея мне понравилась, но вот спам у них всё равно регулярно проскакивает, да и фич там больше чем мне нужно (и как бот, и как библиотека, и как веб-сервис - и жнец и жрец и на дуде игрец), поэтому, разумеется, есть один выход - написать своё.
В итоге после вечера экспериментов я остановился на фичеризации текста в триграммы букв и мешок слов.
В качестве статистической важности был выбран старый добрый TF-IDF, в качестве оптимизационной целевой функции - простой советский копеечный Stochastic Dual Coordinate Ascent. Пожалуй, единственным недостатком всего этого является то, что библиотека ML.NET не умеет дообучать модели с такой целевой функцией, и каждый раз, когда мы добавляем новый спам, переобучение идёт с нуля. Как показала практика новое сообщение в датасет добавляется один-два раза в неделю, а обучение занимает секунду (две на дохлой VPSке), так что я вряд ли эти минусы хоть сколько-то важны.
Скучная часть (принцип работы)
- Пользователи Клуба с привязанным ботом автоматически добавляются в доверенные
- При эвенте "пользователь вошёл в чат" выдаётся простенькая капча
- Если пользователь уже в доверенных, то все проверки пропускаются
- Если пользователь в известных списках спамеров - нафиг
- Если в сообщении❗❗❗ многовато❗❗❗ 💲💲💲эмодзи💲💲💲 - нафиг
- Если в сообщении есть слова, которые маскируются под русские но имеют английские буквы внутри - нафиг
- Если в сообщении есть стоп-слова типа "заработок в сети" - нафиг
- Дальше сообщение очищается от эмодзи, пунктуации, диакритиков и скармливается ML. Если ML считает что спам - нафиг
- Если пользователь написал несколько нормальных сообщений, он добавляется в доверенные - спамеры крайне редко "втираются в доверие" и обычно выдают всё первым-вторым сообщением
- Автоматически бот только удаляет сообщения, банятся пользователи только вручную из админки чтобы снизить урон ложнопозитивных срабатываний
- Если кого-то в чате забанил не бот, в админку приходит уведомление, возможно бот пропустил спам и его стоит добавить в датасет
Какой технологический стек вы использовали? Почему?
Разумеется, бот написан на C#, а не на питоне. Кто же пишет ML на питоне?
На самом деле для этого есть две простые причины:
- Я в разы быстрее пишу на шарпе
- Моя дешёвая виртуалка на 0.5 CPU и 1Gb RAM которая хостит все мои пет-проекты не вынесет питона и тензорфлоу, разве что с большим скрипом. А тут 40Mb RAM и поехали, перетренировка модели занимает полсекунды.
Первые версии были написаны на Go, ну просто потому что могу, но когда надо было прикручивать ML я перешёл туда, где привычнее и есть готовые средства.
Какие планы на будущее?
Никаких. Надеюсь, и этого хватит надолго.
Аватарка
Разумеется, боту нужно лицо и теперь нейронки прекрасно снабжают нас тысячами картинок на любой цвет и вкус, покажу несколько вариантов которые были:
Разумеется, была выбрана та, что похожа на вышибалу в Клубе. Ведите себя прилично или вас быстро выкинут на мороз!
Вместо послесловия
Сидеть в чате без спама это как пить чистую воду и дышать чистым воздухом - не замечаешь, пока у тебя это не отбирают.
Если вы сидите в Книгах или Науке, то, надеюсь, заметили насколько реже стал пролетать спам (за последние пару недель прорвалось 4 сообщения, и два из них это у меня электричество ночью выключали).
Мое почтение, очень круто
Его можно использовать не только в клубных чатах?
Да, насчёт уведомлений о входе в группу - можно подписаться на специальный тип апдейтов, которые по умолчанию не приходят, и там все стабильно приходит
Отличный проект, отличный подход, отличное решение, отличная статья. Я бы тебя нанял, но я сам простой кодер)
Я вот только не понимаю, почему в клубе плюсов много, а на гитхабе ноль звёзд.
Дорогие плюсующие, поставьте пожалуйста господину каждый по две звезды, страна должна знать своих героев.
Я такой спам в телеграмме не вижу. Вот видел набеги ботов с женскими именами которые ничего не пишут
В группу программистов Краснодара я разработал и подключил вот этого бота https://github.com/krddevdays/bot. Суть в том, что надо поставить определённое эмодзи на приветственное сообщение.
Пока полёт нормальный, количество спама заметно сократилось. Хотя люди тупили и не знали что такое "реакция" :)
Когда-то у нас был небольшой канал и мы использовали combot. Канал рос и бот хотел денег, сначала 20$ в год, потом 100$, сейчас уже почти 400$, поэтому пришлось написать своего.
Т.к. питон я трогал когда-то, а go еще нет, то написал его на go.
При входе юзера у него забираются все права и показывается кнопка типа я человек, по нажатию права возвращаются.
Если долго не нажимать, то удаляем сообщение и кикаем юзера.
Из фильтраций примерно такой список получился:
Но все равно некоторые сообщения последних дней приходится вручную убирать:
Кайфовый пет!
Ооо, поднял у себя, работает!
Только на старте валится с ошибками "не могу найти файлы", их бы по-умолчанию в сборку докера добавить, может? Или хотя бы в инструкцию.
я вот так сделал у себя
Моё уважение автору!
Я в группе на 8к человек с успехом гоняю умпутуновского бота + на входе стоит @JohnRoebot в качестве капча-привратника (в планах написать своего со специфичной для чата капчой)
Кстати могу поделиться датасетом спама и "хороших" сообщений