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

TL;DR

IDEGram — это плагин для 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, а не превью

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

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


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 — теперь оно у тебя на телефоне, можно дома посмотреть, можно переслать коллеге.


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 для фрагмента.


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, большие — через зашифрованную ссылку.


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

Это список вещей, которые не вошли в 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 по архитектуре приватности (зашифрованный шеринг достоин отдельного разбора с криптографами);

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

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

Комментарии (7)


  1. vasyakolobok77
    15.05.2026 19:41

    шифрованный шеринг сниппетов

    Ключ кладётся в URL-фрагмент: idegram.app/s/<id>#<key>

    Т.е. любой, кто получит урл с фрагментом, может прочитать сообщение. В т.ч. если человек случайно перешлет кому-то сообщение, расшарит ссылку и т.п.


    1. mamadra Автор
      15.05.2026 19:41

      Всё верно, и это сознательное архитектурное решение, а не баг. Шифрование защищает от одной конкретной угрозы — компрометации нашего сервера. Если завтра нас взломают и сольют всю БД, атакующий получит набор шифротекстов без ключей, потому что ключи физически никогда у нас не были (по HTTP-спецификации часть URL после # на сервер не отправляется, она живёт только в браузере получателя). Так же это работает в PrivateBin, Bitwarden Send и бывшем Firefox Send. От второй угрозы — что получатель сам перешлёт ссылку дальше — ни мы, ни любая другая система защититься в принципе не может. Если ты отправил человеку кусок кода, он его получил и волен делать с ним что угодно. Это ровно та же модель, что у обычного TG-сообщения, GitHub Gist или скрина в Slack: пересылается = расшарено. Поэтому формулировка “end-to-end” тут означает буквально то, что означает — код доступен только на эндпоинтах, отправитель и получатель. Если получателю доверять нельзя — проблема не в транспорте, а в выборе получателя, и никакой инструмент это не лечит. Что мы можем сверху дать (и планируется в следующих версиях): TTL на ссылку, лимит просмотров, отзыв ссылки одной кнопкой из IDE. Это не решает фундаментальную проблему “получатель сделал скриншот”, но сильно сужает окно злоупотребления при случайной пересылке.


  1. hoan51
    15.05.2026 19:41

    beeper.com давно не платный


  1. tr0ublekat
    15.05.2026 19:41

    не осилил после

    Эта статья — про то, что реально работает в коде сейчас, а не про дорожную карту.


    1. Virviil
      15.05.2026 19:41

      100% слоп.