Читаем telegram-каналы в виде новостной ленты (+ бонусом rss)
Предпосылки и проблематика
Когда я переключился с ВК на телеграм, выбрав последний основным мессенджером, я столкнулся с рядом неудобств: в телеге нет привычной ленты новостей и весь контент надо собирать по каналам. ВК имеет функционал групп (сообщения из которых и собираются в ленту), но меня всегда бесило наличие рекламы явной, рекламных постов и прочего мусора, видеть который я в ленте не хотел.
Одно время, когда ВК начал пихать в ленту свои рекомендации (неотключаемые вообще никак), я пользовался адблоком, альтернативными андроид-клиентами (kate mobile), но все эти полумеры напрягали.
В телеге же, как только количество каналов подросло, очень напрягала необходимость заходить в каждый. И, когда их набралось штук 30, я стал забивать на некоторые, т.к. утомлялся туда-сюда по ним перемещаться.
Плюс, как-то внезапно, много каналов начали спамить крос-сылками с рекламой. И ладно, если это партнерские посты из схожих по тематике каналов. Чаще это были всякие курсы английского, питона, а иногда вообще скам про казино или крипту.
Идея и реализация
Так появилась мысль сделать агрегатор телеграм-каналов с фильтрацией по ключевым словам (которые в рекламных постах достаточно часто попадаются).
Я в курсе про функционал группировки каналов в некоторых клиентах, но по некоторым причинам он мне не подходит:
группировка работает только на уровне клиента. Т.е. сгруппированные в мобильном приложении каналы не будут сгруппированы в веб-версии или другом клиенте
нельзя (по крайней мере я не нашел) группировать чаты и каналы
фильтрация спама и рекламы недоступна
я собирался экспортировать агрегированный контент в rss (об этом во второй части статьи)
Погуглив существующие инструменты для работы с телегой, я остановился на питоновской библиотеке telethon. Ее ключевой особенностью была возможность работать в режиме клиента, а не бота (об этом ниже, в нюансах).
Что еще капотом:telethon как telegram-клиент
asyncio для асинхронности
peewee и sqlite3 для хранения инфы кто на что подписался.
Сами посты из подписок не сохраняются, пересылаются на лету
Название придумал быстро: я люблю соединять слова, так что агрегатор телеграма быстро превратился в Телегрегатор.
Нюансы агрегатора
Процесс установки и использования самой библиотеки я не буду расписывать, в доках все достаточно подробно. Остановлюсь на нескольких технических нюансах, которые всплыли в процессе создания Телегрегатора:
Поскольку меня напрягают висячие непрочитанные сообщения (а так же больше 5–7 вкладок в браузере), я хотел, чтобы агрегатор вместо меня подписывался на каналы и пересылал мне сообщения в специально заведенный для этого чат/канал (я это назвал поток, feed).
Как следствие из п.1, агрегатор должен был самостоятельно подписываться на каналы (в т.ч. закрытые), вступать в группы и чаты. А это значило, что вариант с ботом не подходил, т.к. он пассивен и его может добавить только участник чата или владелец канала. Здесь и пригодилась возможность telethon’а эмулировать клиент. Т.е. telethon-клиент авторизуется с номером телефона и кодом из смс и эмулирует обычного юзера. Может реагировать на сообщения о наборе текста, заходить в каналы, группы, чаты, пересылать сообщения, и всё это в реалтайме. В общем, полноценный пользователь.
Как следствие из п.2, возможности бота (кастомные клавиатуры и команды) оказались мне недоступны (или я не нашел, как клиентом это делать). Если знаете как — напишите в комментах. Так что пришлось велосипедить с обработкой пользовательских команд.
Была идея, что пользователю надо общаться с ботом, а тот уже под капотом передает команды клиенту (подписаться на канал), но это показалось слишком сложным для mvp.
Как попробовать?
Сейчас процесс выглядит так:
Получаете название канала (либо инвайт-ссылку, для приватных каналов), который хотите добавить в агрегатор.
Создаёте новый канал (приватный или публичный), который будет выступать в роли потока (ленты)
Находите через поиск и добавляете в поток пользователя Телегрегатор (@telegregator) и даёте права на публикацию сообщений (через меню администраторов).
Телегрегатор поздоровается и покажет доступные команды.
Отправляете команду /join @имя_канала (из. п.1), после чего Телегрегатор подписывается на нужный канал. Можно указать пачку каналов, через пробел (займет некоторое время, ограничение порядка 50 каналов в минуту).
Можно просто переслать в поток сообщение из любого канала, Телегрегатор сам подпишется на канал.
Все новые сообщения из подписанных каналов Телегрегатор будет прислать в этот поток.
Потоков может быть несколько. Вы можете добавлять для каждого потока фильтры по стопсловам (это пока тестовая функция, так что если вдруг что-то перестало работать — сбросьте фильтры).
Ограничения и планы
Есть несколько ограничений: альбом из фоток, которые пришли в оригинальный канал в одном сообщении, Телегрегатор пересылает отдельными сообщениями. Или репост в поток иногда происходит не мгновенно, а спустя 5–10 секунд. Иногда Телегрегатор падает (рестарт автоматически), и может пропустить какое-то сообщение. Это редко, но случается.
Видимо, это особенности протокола. Если заметите странное поведение — напишите мне.
В планах добавить следующий функционал:
показать случайный пост из случайного канала
топ самых популярных каналов (самых редких, как вариант)
предлагает случайный канал
Я люблю находить годноту в телеге. Порой, в канале всего человек 200, и о нём вообще не узнать, кроме как по рекомендациям друзей.
Сам пользуюсь Телегрегатором где-то полгода, решил поделиться, вдруг кому-то зайдет. Из своего аккаунта я удалил все подписки, теперь ими рулю через потоки, полет нормальный.
Исходный код пока грязный, так что публиковать не стал.
все-так бот или клиент?Как я уже писал выше, есть альтернативный способ реализации задуманного мной функционала:
Я должен взаимодействовать с ботом, отправляя ему команды о создании потока, после чего он сам создает нужный канал, добавляет туда меня, выставляет нужные права. Дальнейшее управление каналом тоже происходит через бота. Если такая схема выглядит удобнее — дайте знать.
Часть вторая, про RSS
В процессе работы над Телегрегатором появилась мысль экспортировать это все в RSS-ленту. Я многократно встречал статьи, в т.ч. на Хабре, как автор читает вообще всё через rss, собирая его из разных источников. Кто-то пошел дальше: из rss собирает подборку и формирует ежедневную рассылку на почту. Планирую прийти к такому варианту. Если вы имеете такой опыт — отпишитесь, пожалуйста, в комментах, очень интересна ваша реализация.
Генераторов rss из соцсетей много, пару примеров:
http://feed.exileed.com/
https://rsshub.app/telegram/channel/temablog
Но у них есть недостатки:
не умеют читать приватные каналы
редко обновляют кеш
не отображают вложения (фото, видео, музыку)
медленно или нестабильно работают (иногда падают)
Поэтому, вторым очевидным шагом стало создание моста telegram→rss. По факту, это тот же клиент-Телегрегатор, который по имени канала получает последние сообщения из канала (без подписки) и возвращает в виде rss-ленты. В планах сделать подписку на запрашиваемый канал, тогда можно будет получать ленту и из приватных каналов, но пока так. Отпишитесь, если такой функционал востребован. Проверить можно здесь: http://tg2rss.prosto-tak.ru/.
По вопросам или замечаниям можете писать сюда в личку, в телегу @parotikov или на nik.parotikov@gmail.com.
P.S. В «Я пиарюсь» не хватает кармы. Для телеграма вообще нет хаба, странно.