- PVSM.RU - https://www.pvsm.ru -

Telegram в IntelliJ: как устроен IDEGram и что он умеет

Плагин для JetBrains-IDE, который встраивает полноценный Telegram прямо в редактор. Плюс шифрованный шеринг кода, подсветка синтаксиса в теме получателя и магия с метаданными в обычном тексте сообщения. Разбираю изнутри.

TL;DR

IDEGram [1] — это плагин для IntelliJ IDEA, PyCharm, WebStorm и других IDE на платформе JetBrains. Внутри живёт TDLib-клиент Telegram: чаты, реакции, форварды, голосовые, видео, threads в каналах. Сверху — три специфически-девовские фичи: отправка кода в Saved Messages одной кнопкой, шифрованный шеринг сниппетов через короткую ссылку (ключ не уходит на сервер) и peer-mode, где код красится подсветкой синтаксиса по теме получателя, а не отправителя.

Текущее состояние: версия 1.6.1, 192 установки, без рекламы. Эта статья — про то, что реально работает в коде сейчас, а не про дорожную карту.


Зачем это вообще

Каждый, кто работал в опенспейсе, знает приём: подходит тимлид — Alt+Tab. Telegram стоит на втором мониторе, и каждое переключение — это маленькое палево. У меня была вторая раздражалка: я постоянно копировал куски кода в чаты, и каждый раз — открой клиент, найди чат, вставь, оберни в ```, не забудь указать язык. Десять секунд на одну отправку, повторённые сто раз в неделю, складываются в "хочу одну кнопку".

IDEGram — это и есть та одна кнопка. Точнее, четыре action'а в IDE и tool window с полным Telegram-клиентом.

Telegram в IntelliJ: как устроен IDEGram и что он умеет - 1

Базовый слой: это реально полноценный Telegram, а не превью

Клиент построен на TDLib (нативная библиотека от Telegram), забандленной прямо в плагин. NativeLoader детектит платформу при старте и грузит libtdjni из ресурсов — пользователю не нужно ничего ставить отдельно. Поддерживаются macOS x64/arm64, Windows x64, Linux x64. Linux ARM64 — в планах, см. WIP-секцию.

Что реально работает прямо сейчас:

  • Чаты, папки, архив. Список чатов с фильтрами и folder-tabs, синхронизация с Telegram-десктопом. Поиск глобальный и локальный по сообщениям в чате, плюс фильтр по отправителю — очень полезно, когда нужно найти "что Петя писал про этот баг".

  • Полное форматирование текста. Bold, italic, underline, strike, code, pre, spoilers. Парсятся как entities из TDLib, рендерятся в Compose-канвасе.

  • Реакции. И обычные Unicode, и кастомные эмодзи (включая анимированные через Skottie / TGS).

  • Reply и forward. У форварда нормальные опции: можно скрыть оригинального автора (sendCopy) или убрать подпись.

  • Threads и комментарии в каналах. Подгружается через GetMessageThreadHistory, рендерится отдельным режимом с заголовком "What is this thread about".

  • Голосовые с waveform. Записываются прямо в IDE средствами Java (OGG Vorbis), не через TDLib. Играются с визуализацией.

  • Видео и GIF. Сначала через JCodec (быстрый старт без зависимостей), потом плагин апгрейдит плеер до JCEF (embedded Chromium) — поддерживается полноценное видео с управлением.

  • Видео-кружочки. Тот же JCEF, но в круглом контейнере.

  • Поллы. Голосовать можно. Создавать — пока нет (см. WIP).

  • Pin / Unpin с отдельной панелью закреплённых сообщений и поддержкой "favourites" — мини-избранные сообщения пользователя.

  • Schedule send, silent send. Кнопка в composer'е разворачивает меню с "Send normal / Schedule / Send silently / Send when online". Дата и время — через нативный диалог.

  • Mute и notification settings с правильной иерархией: сначала смотрятся настройки конкретного чата, если не заданы — scope defaults (private/group/channel). Синхронизируется с TG при старте.

  • Drag-and-drop файлов прямо в окно чата.

  • Custom emoji как реакции и как inline big-emoji (когда отправляешь только эмодзи, оно рендерится крупно).

  • Link previews — passthrough из TDLib + расширенные OG-теги от собственного snippet-сервиса для ссылок на сниппеты.

Из того, что специально не делает (и не претендует пока):

  • не отправляет стикеры (только принимает),

  • не создаёт поллы,

  • не отправляет контакты, геолокацию и venue (входящие — только в списке чатов превью-строкой).

Telegram в IntelliJ: как устроен IDEGram и что он умеет - 2

Это базовая часть. Дальше идут вещи, ради которых плагин, собственно, и делался.


Killer feature #1: Send to Saved Messages

Самая утилитарная фича. Контекстное меню → "Send to Saved Messages" → выделенный кусок (или весь файл) улетает в твой self-chat в Telegram. Без диалогов выбора чата, без подтверждений.

Что под капотом:

  • Если текст больше 4000 символов (лимит Telegram), он автоматически режется по границам строк на несколько сообщений.

  • Бинарные файлы блокируются: проверяется первые 4 КБ, если NUL-байтов больше 5% — экшен молча отказывает, чтобы случайно не отправить себе скомпилированный .exe вместо логов.

  • AtomicBoolean inFlight блокирует повторные клики, пока запрос летит.

Реальный кейс: ставишь брейкпоинт, копируешь содержимое переменной в Run Debug, выделяешь в консоли, Send to Saved Messages — теперь оно у тебя на телефоне, можно дома посмотреть, можно переслать коллеге.

Telegram в IntelliJ: как устроен IDEGram и что он умеет - 3

Killer feature #2: шифрованный шеринг сниппетов

Здесь интереснее.

Стандартный сценарий: тебе надо скинуть коллеге кусок кода — функцию, traceback, конфиг. Что делают обычно:

  • кидают как текст в TG → теряется подсветка, страдают длинные простыни;

  • кидают через Carbon → красиво, но картинка, не копируется;

  • кидают через GitHub Gist → нужен аккаунт, ссылка длинная, и код физически лежит на чужом сервере в plaintext.

Последнее — реальная проблема для многих компаний, у которых политики безопасности запрещают Pastebin и аналоги. Поэтому в IDEGram сделано так:

  1. Шифрование происходит на стороне IDE. Плагин генерит случайный AES-256-GCM ключ, шифрует сниппет, отправляет на сервер только шифротекст.

  2. Ключ кладётся в URL-фрагмент: idegram.app/s/<id>#<key>. По спецификации HTTP всё после # в браузере не уходит на сервер — обрабатывается только на клиенте.

  3. Сервер хранит шифротекст + неконфиденциальную метадату (язык, число строк, размер, имя файла если разрешил). Расшифровать он не может — у него нет ключа.

  4. Получатель открывает ссылку, JS на странице читает ключ из фрагмента, делает GET за шифротекстом, дешифрует локально.

То есть код физически не покидает машину разработчика в открытом виде. Сервер у компании-провайдера (то есть у меня) можно фактически взломать, и злоумышленник получит набор шифротекстов и сможет узнать, что Вася делился 47 строками на Python — но не узнает, что именно там было.

Метадата в превью (язык, число строк, имя файла, никнейм автора) опциональна и настраивается в Settings → Code Sharing → URL share:

  • "Include filename in metadata"

  • "Include console context header when sharing stacktraces" — если шеришь из Run/Debug консоли, в превью добавляется имя конфигурации запуска.

Под капотом: ShareViaIdegramUseCase, проверка фича-флага SNIPPET_SHARE (есть/нет в текущем тире), RunContentManager для подтягивания имени Run-конфига, AES-256-GCM в JCA, base64url для фрагмента.

Telegram в IntelliJ: как устроен IDEGram и что он умеет - 4

Killer feature #3: peer-mode и подсветка темы получателя

Это самая моя любимая фича технически.

Когда отправитель и получатель оба сидят в IDEGram, ссылка не нужна вообще. Сниппет уходит прямо как Telegram-сообщение, без upload'а на наш сервер. Но рендерится он у получателя как полноценный код-блок с подсветкой.

И вот тут — нюанс. Код красится не темой отправителя, а темой получателя. То есть если ты отправляешь Kotlin-сниппет из своего "Dracula", а коллега сидит в "Light", он увидит подсветку под Light. Получатель читает свой стандартный EditorColorsManager.globalScheme и SyntaxHighlighterFactory — то есть это буквально тот же подсвечиватель, который красит код в его IDE прямо сейчас. Поддерживается ~20 языков через alias-map (js→JavaScript, kt→kotlin, py→Python, и т.д.). Fallback на plain mono.

Никакой Pastebin, никакой Carbon, никакая GitHub Gist такого делать в принципе не могут — они не знают, какая тема в редакторе у того, кто откроет ссылку. А IDEGram знает, потому что получатель открывает у себя, в своей IDE.

Magic protocol

Возникает вопрос: а как peer-mode вообще понимает, что это сниппет, а не обычное сообщение? Telegram же не знает ничего про IDEGram.

Ответ: метадата кодируется прямо в текст сообщения. Незаметно для пользователя — там есть специальный header с языком, именем файла, range строк, плюс хеш-маркер. MagicProtocol.kt парсит это на получателе, и если маркер найден, сообщение рендерится как PeerSnippetBubble вместо обычного текста.

Если получатель в обычном Telegram-клиенте, он увидит сообщение как код-блок в ``` — потому что мы заворачиваем содержимое в обычный TG-codeblock, и magic-маркер прячется в незначащих символах. Так что фолбэк на обычный TG работает прозрачно.

PeerModeDecider автоматически выбирает, как отправить (peer-mode vs link-mode) в зависимости от размера сниппета и regsitry-флагов. Маленькие куски идут peer-mode, большие — через зашифрованную ссылку.

Telegram в IntelliJ: как устроен IDEGram и что он умеет - 5

Маленькие штуки, которые радуют

Это список вещей, которые не вошли в killer-features, но которые я ловил кайф пилить и которые делают плагин приятным.

  • Темная тема «из коробки». Своих палитр у плагина нет — все цвета берутся из EditorColorsManager IDE. Меняешь тему в IDE — IDEGram перерисовывается. Compose-for-IntelliJ + Jewel дают это бесплатно.

  • Throttling уведомлений. Один балон на чат не чаще раза в две секунды (THROTTLE_MS = 2000 в MessageNotificationService). Иначе при массовых апдейтах в групповом чате IDE превращается в дискотеку.

  • Тулвиндоу без шортката. У ToggleToolWindow намеренно не назначен hotkey. JetBrains-плагины часто грешат тем, что захватывают Ctrl+Shift+T «потому что у нас же тест‑фреймворк». Я считаю это хамством. Пользователь сам биндит в Settings → Keymap.

  • Auto-scroll на unread + ленивая пагинация вверх. Открываешь чат — прыжок на первое непрочитанное. Свайп вверх подгружает историю.

  • Sender filter в поиске сообщений. Можно отфильтровать поиск конкретно по отправителю.

  • Глобальный кэш в PathManager.getSystemPath(). TDLib-база, файлы, стикеры, GIF, JCEF — все живут в одной общей папке инсталляции IDE, а не в <project>/.idegram/. Старая папка по проектам — legacy, плагин показывает уведомление один раз и предлагает мигрировать.

  • PasswordSafe для credentials. Номер телефона и флаг активной сессии хранятся в OS keychain через стандартный IDE API, а не в plain-text JSON.

  • JcefStickerOverlay + автоочистка scratch-папки. Раз в час PluginInitializer.sweepStickerScratchDir() чистит мусор из …/idegram/jcef/, иначе она разрастается.

  • Compose DragAndDropTarget в MessageViewPanel — файл бросаешь прямо в чат, не нужно открывать attach-меню.

  • Re-entry guard через AtomicBoolean inFlight на ShareViaIdegram и SendToSavedMessages — даблклик не отправит две копии.

Ничего из этого само по себе не «вау‑фича», но в сумме это и есть то, что отличает плагин от прототипа.


Что НЕ работает (честный список)

Хабровская традиция требует, чтобы автор не врал про дорожную карту. Поэтому:

  • Linux ARM64. Нативной TDLib-либы для ARM64 пока нет, я её не собрал. На обычном Linux x64 всё работает.

  • Мультиаккаунты. Архитектура держит ровно одну сессию на инсталляцию IDE. UI для переключения аккаунтов не сделан. Я в курсе, что многие хотят, дойдут руки.

  • Локализация. Все строки захардкожены на английском. messages.properties нет. Если важно — заводите issue.

  • Создание поллов и отправка стикеров отдельно от альбома. Голосовать можно, видеть стикеры можно, отправлять — нет.

  • Отправка контактов / геолокации / video notes. Принимаем (в виде превью в списке чатов), отправлять не умеем.

  • Sticker / GIF download в текущей версии — заглушка. Стикеры через JCEF-оверлей рендерятся из встроенных, но не докачиваются по требованию.


Что дальше

Следующие штуки в очереди (без обещаний по срокам):

  • линуксовая нативная либа (x64 уже работает, ARM64 — собрать);

  • мультиаккаунты;

  • создание поллов;

  • whitepaper по архитектуре приватности (зашифрованный шеринг достоин отдельного разбора с криптографами);

  • собственно платный релиз — сейчас бесплатно, фича-флаг переключу когда наберётся критмасса пользователей.

Спасибо, что дочитали.

Автор: mamadra

Источник [2]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/jetbrains/451687

Ссылки в тексте:

[1] IDEGram: https://plugins.jetbrains.com/plugin/31378-idegram

[2] Источник: https://habr.com/ru/articles/1035758/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1035758