Всем ку! Пожалуй, стоит начать с того, что меня вообще сподвигло на создание данной версии:

  1. Нежелание некоторых юзеров пользоваться официальной версией для ПК по ряду причин:

    а) Требовательность к железу (даже видеокарту нагружает). А некоторым по работе приходится юзать МАХ на «уставших рабочих лошадках». Заявления, типа «эта тварь жрёт ресурсов больше, чем 1С».

    б) Постоянные обновления с полной переустановкой, а на момент написания статьи полный пакет официального МАХ весил 308 мб.

    в) Некоторые неудобства использования веб‑версии, особенно в режиме «Инкогнито». Чуть подробнее будет дальше в статье.

    г) Слежение за пользователем. Вроде, ничего особо криминального нет во встроенных трекерах, но бесит, когда тебя не спрашивают. Знаете, если Вы выходите из подъезда и бабульки на лавочке интересуются как у вас дела и куда направляетесь — это одно. Ваше дело — отвечать\не отвечать\соврать. А когда Вам при этом ещё и в трусы заглядывают без спроса — это уже другое.

  2. Не нашел хорошую альтернативу. Нет, есть конечно nemax‑mod для ПК, который представляет из себя оболочку для веб‑версии, но так такое... и сырое.

Значит, будем делать своё!

Итак, для начала выберем инструмент разработки, для этого есть некоторое количество моих «юзерфрендли принципов»:

а) Запуск на всём, чём можно. Некоторые из технологий и фреймворков будем использовать «заранее устаревшими». Выбор по старинке остановил на c# +.net framework 4.7. Конечно, можно было использовать более новые.NET 8\9\10, что гораздо упростило бы разработку и решило некоторых сложности, с которыми пришлось столкнуться. Но если у юзера Win10 без предустановленного.NET или даже Win7 (да, и такие отписываются в Issue на гитхабе), это создаст некоторые неудобства при первичном запуске.

б) Малый вес. Как можно меньше. Нет перегруженного интерфейса и прочих свистогуделок и прочего мусора.

в) Максимально простая установка. Поддержка обновлений. Желательно, удобных обновлений.

Ну что ж, приступаем!

  1. Для начала набросал простую оболочку, в которой запускается WebView2 с привязкой к сайту веб‑версии MAX и увидел несколько проблем:

    а) Хорошо, у меня есть окно, но как получать уведомления, если оно свёрнуто?

    б) При авторизации создается папка с файлами и кэшем веб‑версии в appdata. Меня это не устроило по ряду причин — по моему опыту хранение данных локально может быть на руку злоумышленникам. В своё время я легко получал доступ к перепискам различных мессенджеров, благодаря локальному хранению. И вообще, считаю папку с данными WebView2 — мусором. А пользователь не должен об этом задумываться при удалении мессенджера с рабочего компа.

    в) В принципе, при работе в режиме ‑inprivate (сиречь «в режиме Инкогнито»), создается временная папка, которая удаляется при закрытии окна, но тогда придется проходить авторизацию каждый раз при запуске.

  2. Мне понравилась идея с in private, но тогда нужно хранить ключ авторизации. Пишем перехватчик токенов на javascript. Легко и просто перехватываем токен авторизации, но как его хранить? Ответ лежит на поверхности — прямо в реестре с шифрованием по DPAPI — это решит сразу несколько проблем:

  • Не нужно постоянно проходить авторизацию

  • Токен «под рукой» для быстрого удаления

  • Копирование токена на другой комп не позволит использовать его на другой машине, так как DPAPI имеет жесткую привязку к windows user id, device id

  • Токен зашифрован и его нельзя «просто прочитать»

    Вопрос: кто‑то другой сел за комп и открыл эту программу. Либо она запустилась сама при загрузке системы и «посторонний» видит всю переписку. Решение — добавляем функцию пин‑кода. Опциональное, пользователь может отказаться и добавить пин‑код потом или удалить его.

    Логика работы парсера — при инициализации окна парсер проверяет, есть ли ключ авторизации в зашифрованном виде по месту хранения? Если есть — останавливается. Если нет — ждём авторизации от пользователя по QR‑коду. Как только токен перехвачен и сохранен — парсер останавливает работу.

    Не забываем про UX — добавляем в настройки удаление данных авторизации в один клик.

    3. Создаем иллюзию окна как отдельного мессенджера. Имеется ввиду необходимость сохранения положения окна и его размеров при каждом запуске. В том числе при наличии нескольких дисплеев. Сохраняем данные по размерам окна и координатам в реестре. Не шифруем )

Уведомления

  • Проводим опрос среди юзеров. Что нравится и не нравится, когда они используют оригинальную веб‑версию МАХ? Приходим к выводу, что нам необходимо:

  • Корректно всплывающие уведомления типа стандартных, но лучше и функциональнее.

  • Понимать, что было пропущено уведомление, если юзер отошел от компа. А именно — мигание иконки приложения в панели задач, либо красная точка на иконке в трее.

    Значит, делаем уведомления в правом нижнем углу с нуля. Включаем логику определения получения новых сообщений. При взгляде на чат видим, что у нас есть три вида состояния — синий бейдж с количеством сообщений — новое непрочитанное. Серый бейдж — новое непрочитанное в чате, для которого пользователь выключил уведомления. Нет бейджа — нет новых сообщений. Изучаем веб‑страницу, ищем div'ы и классы, отвечающие за бейджи, парсим эти состояния. Дебажим.

    Передаем из javascript в c# данные. Пишем CustomNotification.cs, который будет рисовать нам уведомления в нижнем углу Windows.

    Прописываем определение состояния окна программы (мы же не хотим получать всплывающие уведомления прямо во время переписки?) — окно либо в фокусе, либо нет. Если нет — показываем уведомления. Опять дебажим...

    Парсим данные из чата с синим бейджем — аватар, имя\ник пользователя и тело сообщения. Всё это добавляем в наш нотификатор и снова и снова дебажим. Не забываем про такие нюансы как — крестик на уведомлении для быстрого закрытия, положение уведомления по, скажем так, Z‑координате (мы должны видеть уведомление из нашей программы поверх всех других окон, в том числе в 3D приложениях, но это не должно приводить к их сворачиванию).

    Добавляем функцию «антифлуд» — это когда кто‑то начинает спамить короткими сообщениями, и Вам это не нравится — показываем новые сообщения не чаще чем задано определённым временным лимитом. Добавляем проверку на дубли сообщений — когда Вы получили новое сообщение, то получили и уведомлении в трее, но если Вы его не прочитали в течение отведенного времени, то программа могла отправить уведомление повторно. Чтобы этого не происходило — храним в памяти тело сообщения и, если дубль, то не показываем. Это решает проблему с постоянно всплывающими уведомлениями, когда юзеру тупо некогда ответить на сообщение (допустим, пишет срочное письмо, сценарий, отвечает клиенту). И не придётся постоянно жать на крестик.

    Разыгрываем в голове ситуацию — юзер отошел по своим делам. В это время пришло новое сообщение, появилось уведомление и исчезло спустя несколько секунд. Программа свёрнута и чат не виден. Хорошо, уведомление исчезло через пару секунд, значит, если юзер не отреагировал, то через пару секунд включаем ненадолго мерцающую подсветку иконки в панели задач. Моргнём два‑три раза и дальше будем просто светиться (не надо моргать почем зря, может юзеру не до чата, а так просто оранжевым светится иконка внизу и сильно глаз не мозолит). А если свернуто в трей? Тогда красная точка над иконкой в трее. И без всяких «99+» непрочитанных сообщений, это лишнее.

    (пока писал эту статью, решил, что нужна будет дополнительная настройка «Показывать уведомления поверх других окон» с возможностью отключения, а то вдруг юзер катает‑нагибает? Уведомление может перекрыть ему стратегически важную информацию. Сказано‑сделано)

Собираем билд...

  • Изначально была идея собрать всё в один.exe файл, вес которого был примерно 1–1,5 мб, и потреблял примерно 15 мб RAM. Это успех... но не всё оказалось так просто. Одна из нативных библиотек, написанная на c++ никак не хотела встраиваться. Это рушило «концепцию одного файла» на корню. Да и нужно было еще проработать дополнительную безопасность. Добавляем на всякий случай защиту от XSS‑атак, блокировку трекеров, антидебаггер (с которым хапаем проблем при тестировании и получаем невозможность запуска на виртуальных машинах), отслеживание контрольных сумм. Оставался открытым вопрос последующих обновлений. Понятно, что веб‑версия сама по себе новая при каждом запуске, но как быть с обновлением билдов самой программы? Накидав всяких фич по безопасности заметил, что потребление RAM значительно выросло, но не критично. А в моей RAM еще свежи воспоминания о чаяниях юзеров по поводу полной переустановки десктопного МАХ при каждом обновлении... так быть не должно!

    Подумав немного, решил использовать Velopack для обновлений. По итогу отказался от концепции «одна программа — один файл». Единственное — зашил парсер на javascript внутрь.exe, а то как‑то несекьюрно. Velopack помог решить несколько вопросов сразу:

  • Дельта‑обновления в фоне. Вышел новый билд? При запуске программы Вы получите уведомление о наличии обновлений. В случае согласия обновиться — даже глазом моргнуть не успеете, как программа получит обновления только новых файлов и быстро перезапустится. Только. Новых. Файлов. А не полный реинсталл, чем любят грешить некоторые девелоперы.

  • Пусть библиотеки не будут вшиты в.exe, зато при сборке нового билда и получении обновлённных библиотек юзеру будет проще обновиться с меньшими затратами на трафик.

  • Velopack сам контролит хэш файлов, так что эту функцию, как и несколько других, вырезал из исходного кода за ненадобностью.

  • Что не понравилось? Работа мессенджера в таком режиме потребляет RAM на уровне «телеги», скачками до 100–300 мб RAM. В среднем около 100 мб.

  • Вес установочного файла <10 мб. Пока только win‑x64. Пользуйтесь!

P. S.: У меня на гитхабе есть еще интересные штучки...

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


  1. Furriest
    16.06.2026 12:45

    Ооооочень надо возможность для portable-версии запускаться с разными профилями. Чтобы можно было из двух папок запускать два разных аккаунта Макса.
    Сейчас, как я понимаю, оно в юзерском профиле хранит данные аккаунта, поэтому так не работает.


    1. squ1sh Автор
      16.06.2026 12:45

      В принципе, как я это вижу... в портэйбл версии хранить данные авторизации в каком-нить типа .json файле... например. На досуге проработаю данный вопрос, не вижу тут каких-то сложных препятствий. Может вообще есть смысл не хранить данные в реестре, а полностью перевести всё на .config с шифрованием? Тогда версия всегда будет типа portable, хотя тут возникает вопрос "автозагрузки" как функции (не исключен факт добавления юзером проги в автозагрузку и последующий перенос папки с искажением пути автозагрузки)


      1. Furriest
        16.06.2026 12:45

        Да, для портабл-версии было бы хорошо все данные локализовать в папке.


        А автозапуск отдельной галкой в настройках, которая при установке прописывает текущий путь в реестр. Если папку перенесли - галка самоснимется, потому что не найдет соответствующей записи при открытии настроек. Клиент по ней щелкнет - пропишется новая. Старая останется, правда, но это мелочи, по сути. Редкий кейс, мусор сам вынесет, если что.


  1. Ded_Keygen
    16.06.2026 12:45

    Было бы хорошо иметь клиент для запуска на терминальном сервере:

    • запуск из сетевой папки (или в Remote App, если из сетевой папки невозможно)

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

    • чтобы профиль сохранялся в профиле пользователя, а кэш - во временной папке (чтобы профиль не переполнять)


    1. squ1sh Автор
      16.06.2026 12:45

      • Автообновление затрагивает только мой код. Никакой код самого мессенджера не затрагивается (кроме блокировки трекеров). Обновление как у обычной десктопной версии не происходит (по сути при каждом запуске просто происходит обновление страницы). Обновление программы происходит только при новом релизе на гитхаб, происходит ооочень быстро, заменяются только измененные файлы и обновления используемых библиотек (в основном WebView2)

      • Профиль сохраняется ТОЛЬКО в профиле пользователя (HKCU\SOFTWARE\MaxLight\Auth с шифрованием по DPAPI). Так как я против мусора, то кэш - временная папка, автоматически очищающаяся при выходе из программы. Исключение - аварийное завершение (fatal error, что маловероятно, либо отключение подачи электроэнергии).
        Про всё это написано в статье.
        Что касается терминального сервера... нужно что-то еще для этого?


  1. gotch
    16.06.2026 12:45

    А можно научить клиент просто пересылать все входящие сообщения в Telegram?


    1. squ1sh Автор
      16.06.2026 12:45

      Насколько знаю, у меня один из товарищей делал подобную схему, так как рабочий чат именно в МАХ, а среди работников есть "ярые отказники". Уточню на досуге данный момент


  1. Akuma
    16.06.2026 12:45

    Неофициальный клиент мессенджера для доступа к госуслугам у многих кто им пользуется?

    Что же может пойти не так


    1. squ1sh Автор
      16.06.2026 12:45

      Весь исходный код открыт, лицензия по сути LGPLv2, токен авторизации работает с привязкой к пользователю винды + device id (тырить его смысла нет), во всём остальном это обычная веб-версия мессенджера с отличиями:

      • Заблокированы трекеры слежения

      • Синхронизация сообщений лучше, чем у обычной десктопной версии

      • Малый вес и нагрузка на железо, не хранит кеш локально после завершения работы\перезагрузки компа.

      • Не требует постоянных обновлений 300+ мб. Обновления самой программы - delta-update с заменой только измененных файлов. При том вес самой программы <10 мб

      • С нуля написанная система уведомлений о сообщениях, с дублированием в панели задач\трее (мигание и подсветка иконки\красная точка у иконки)


      1. Akuma
        16.06.2026 12:45

        Да да, я вам верю. Каждая бабушка пойдёт копаться в исходниках и сверять хеши :)


        1. squ1sh Автор
          16.06.2026 12:45

          Каждая бабушка не пойдет, но кто-то да пойдет. И если что не так - выявят. В любом случае, я никому ничего не навязываю. Появился запрос на такую софтинку - я сделал и поделился с другими, как и положено.


  1. user13901705
    16.06.2026 12:45

    «Не то плохо, что мы в жопе, а что мы решили в ней обустраиваться»


  1. sav13
    16.06.2026 12:45

    Нежелание некоторых юзеров пользоваться официальной версией для ПК по ряду причин

    А чем WEB-версия не устраивает?


    1. squ1sh Автор
      16.06.2026 12:45

      Тем, что это лучше, чем просто веб-версия. В статье описано.


  1. aik
    16.06.2026 12:45

    Это просто обёртка над веб-версией получается?


    1. squ1sh Автор
      16.06.2026 12:45

      Нет, это больше, чем просто обёртка. Не просто так столько букав же писал?


      1. aik
        16.06.2026 12:45

        Ну, понятно, что всякие квалити оф лайф есть - пинкод вообще очень полезно. Но работает ведь на базе вебверсии, то есть если там опять сертификаты аннулируют, тоже отвалится, как и браузер?


      1. aik
        16.06.2026 12:45

        PS. По самому клиенту - блокировка пинкодом нужна не только на запуск, но и по таймеру неактивности.


      1. mokhin-denis
        16.06.2026 12:45

        GlobalSign уже отзывает свои ключи. Let's Encrypt уже на подходе. Как ваше приложение будет в WebView открывать MAX, когда ключи протухнут и SSL будет нельзя?


        1. squ1sh Автор
          16.06.2026 12:45

          Думал над этим. Будем решать проблемы по мере поступления. У нас наш местный надзорный орган санкции покруче против своих же влепляет. И ничего, живём. Ищем обходные пути.


  1. Egres
    16.06.2026 12:45

    У меня max открыт в закреплённой вкладке броузера, потому что его десктопная версия глючная и тормозная.


    1. squ1sh Автор
      16.06.2026 12:45

      Это одна из причин появления MAX Light. Сегодня был свидетелем пожирания овер 800 мб рам десктопной версией. Куда блин столько?


      1. Egres
        16.06.2026 12:45

        MAX на мой взгляд слишком важная вещь, чтобы использовать "левые" клиенты. По крайней мере без явного одобрения владельцев.


        1. Vinni37
          16.06.2026 12:45

          1) Это не левый клиент, лишь кастомное окно браузера
          2) +- все тоже самое можно реализовать через расширение браузера, но будет не так удобно.
          3) На счет важности тут вопрос спорный.