- PVSM.RU - https://www.pvsm.ru -
Плагин для JetBrains-IDE, который встраивает полноценный Telegram прямо в редактор. Плюс шифрованный шеринг кода, подсветка синтаксиса в теме получателя и магия с метаданными в обычном тексте сообщения. Разбираю изнутри.
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-клиентом.

Клиент построен на 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 (входящие — только в списке чатов превью-строкой).

Это базовая часть. Дальше идут вещи, ради которых плагин, собственно, и делался.
Самая утилитарная фича. Контекстное меню → "Send to Saved Messages" → выделенный кусок (или весь файл) улетает в твой self-chat в Telegram. Без диалогов выбора чата, без подтверждений.
Что под капотом:
Если текст больше 4000 символов (лимит Telegram), он автоматически режется по границам строк на несколько сообщений.
Бинарные файлы блокируются: проверяется первые 4 КБ, если NUL-байтов больше 5% — экшен молча отказывает, чтобы случайно не отправить себе скомпилированный .exe вместо логов.
AtomicBoolean inFlight блокирует повторные клики, пока запрос летит.
Реальный кейс: ставишь брейкпоинт, копируешь содержимое переменной в Run Debug, выделяешь в консоли, Send to Saved Messages — теперь оно у тебя на телефоне, можно дома посмотреть, можно переслать коллеге.

Здесь интереснее.
Стандартный сценарий: тебе надо скинуть коллеге кусок кода — функцию, traceback, конфиг. Что делают обычно:
кидают как текст в TG → теряется подсветка, страдают длинные простыни;
кидают через Carbon → красиво, но картинка, не копируется;
кидают через GitHub Gist → нужен аккаунт, ссылка длинная, и код физически лежит на чужом сервере в plaintext.
Последнее — реальная проблема для многих компаний, у которых политики безопасности запрещают Pastebin и аналоги. Поэтому в IDEGram сделано так:
Шифрование происходит на стороне IDE. Плагин генерит случайный AES-256-GCM ключ, шифрует сниппет, отправляет на сервер только шифротекст.
Ключ кладётся в URL-фрагмент: idegram.app/s/<id>#<key>. По спецификации HTTP всё после # в браузере не уходит на сервер — обрабатывается только на клиенте.
Сервер хранит шифротекст + неконфиденциальную метадату (язык, число строк, размер, имя файла если разрешил). Расшифровать он не может — у него нет ключа.
Получатель открывает ссылку, 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 для фрагмента.

Это самая моя любимая фича технически.
Когда отправитель и получатель оба сидят в 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.
Возникает вопрос: а как peer-mode вообще понимает, что это сниппет, а не обычное сообщение? Telegram же не знает ничего про IDEGram.
Ответ: метадата кодируется прямо в текст сообщения. Незаметно для пользователя — там есть специальный header с языком, именем файла, range строк, плюс хеш-маркер. MagicProtocol.kt парсит это на получателе, и если маркер найден, сообщение рендерится как PeerSnippetBubble вместо обычного текста.
Если получатель в обычном Telegram-клиенте, он увидит сообщение как код-блок в ``` — потому что мы заворачиваем содержимое в обычный TG-codeblock, и magic-маркер прячется в незначащих символах. Так что фолбэк на обычный TG работает прозрачно.
PeerModeDecider автоматически выбирает, как отправить (peer-mode vs link-mode) в зависимости от размера сниппета и regsitry-флагов. Маленькие куски идут peer-mode, большие — через зашифрованную ссылку.

Это список вещей, которые не вошли в 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
Нажмите здесь для печати.