Git в Telegram? Без JSON, с SQLite, победой над Markdown и security by design. Код, схема БД, факапы и ссылка на бота.— Читать дальше «Git в Telegram: как я избавился от JSON, победил Markdown и получил security by design»
В своём Telegram-канале я время от времени предлагаю подписчикам выбрать очередную «бредовую» идею для реализации. На этот раз победил Git в Telegram: чтобы можно было инитить проекты, пушить файлы, коммитить — и всё это прямо в мессенджере.
С практической точки зрения проект на**й не нужен. Есть GitHub, GitLab и куча нормальных инструментов. Но как эксперимент — почему бы и нет? Чисто посмотреть, можно ли заставить Telegram работать как VCS.
На старте я думал: «Положу всё в JSON, на кой мне база данных?» Проектов мало, пользователей немного, файлы текстовые — чего заморачиваться?
Подергал JSON туда-сюда пару дней и понял: не варик.
Вывод: JSON — для конфигов, а не для данных, которые меняются каждую секунду.
Выбрал SQLite, потому что:
Сущности:
Почему так: я хотел иметь возможность откатиться к любой версии любого файла. Да, база распухнет, но текстовые файлы — это не гигабайты видео. Плюс наличие file_versions и commit_files позволяет делать diff между версиями и смотреть историю изменений.
В коде вместо голых кортежей из SQL — датаклассы:
python@dataclass
class Project:
id: int
name: str
owner_id: int
thread_id: Optional[int] = None
created_at: Optional[datetime] = None
Казалось бы: взял код, обернул в тройные апострофы, кинул в Telegram. Telegram сам подсветит синтаксис, если указать язык. Красота. В теории.
На практике Telegram использует свой диалект Markdown, где куча служебных символов: _ * [ ] ( ) ~ > # + - = | { } . !
Попытка 1: заэкранировать всё подряд. Результат: код превращается в кашу. Вместо def __init__- получается def |_|_init|_|_ — уже не запустишь, и в канале выглядит как говно.
Попытка 2: не экранировать вообще. Telegram шлёт на**й с ошибкой «can't parse entities».
Попытка 3: экранировать только то, что реально ломает разметку. Выяснилось, что порядок важен. Сначала экранируем точки и подчеркивания, потом обратную косую черту. Но и это не панацея — последовательности типа \*
после экранирования превращаются в \\*, и Telegram снова недоволен.
Попытка 4: разбивать на части. Для больших файлов делаю превью (первые 50 строк), экранирую их, отправляю как код, а полную версию — файлом. И тут начался ад: Telegram находил ошибки в тех частях кода, которых в превью вообще не было. Оказывается, он всё равно парсил полный код, даже если отправлялась только его часть.
Попытка 5 (финал): забил на Markdown и перешёл на HTML. Telegram умеет его принимать. Да, он не такой красивый, но зато предсказуемый:
pythondef safe_html(text: str) -> str:
return (text.replace('&', '&')
.replace('<', '<')
.replace('>', '>'))
def format_code_html(filename: str, content: str) -> str:
lang = get_language_from_filename(filename)
content = safe_html(content)
return f'<pre><code class="language-{lang}">{content}</code></pre>'
Никаких точек, подчеркиваний, обратных слешей. Просто экранируем три символа — и код летит как надо.
Когда бот начал обрастать функциями, я задумался о безопасности. Чтобы никто не мог коммитить или удалять чужие файлы, начал писать проверки в каждую команду:
pythonif project.owner_id != user_id:
await message.answer("❌ Это не твой проект")
return
Добавил в /commit. Потом решил с другого аккаунта потестировать команды на чужих файлах. И тут бот на каждую команду стал выдавать «файл не найден» или «проект не найден». И я понял: безопасность уже работает. С самого начала. Из коробки. Без единой строчки кода.
Как так вышло? В таблице projects с самого начала было поле owner_id. При создании проекта я писал туда telegram_id владельца. Все запросы к БД фильтруются по этому полю:
def get_user_projects(self, telegram_id):
return self.execute(
"SELECT * FROM projects WHERE owner_id = ?",
(telegram_id,)
)
Показать проекты — только свои. Найти файл — только в своих проектах. Выбрать проект — только из своих. Никаких лишних проверок. Просто SQL-запросы, которые с самого начала учитывали владельца.
Изначально казалось, что команд будет немного. Но...
Жизнь рассудила иначе.
Итого — уже под два десятка. И это не предел.
В моём коде нет абстрактных базовых классов. Совсем. Потому что они нужны только когда у тебя есть минимум две разные реализации одного и того же. В GitGram всё проще: один способ работать с БД, один способ шифровать, один способ парсить .gitignore.
Если завтра появится вторая реализация — тогда и буду делать интерфейс. А пока это просто оверхед.
В GitGram:
Никаких AbstractMinerShieldEventProcessor, BaseGitGramManager, InterfaceProviderFactory.
Код должен быть тупым. Чем тупее — тем проще его читать и отлаживать.
В планах:
GitGram принимает файлы, режет их на куски если надо, постит в канал с подсветкой. Коммиты ходят, ветки переключаются, диффы показываются. Всё это в тредах, каждый проект отдельно.
На практике GitGram ни к чему. Но сама задумка — Git в Telegram — это же так прикольно. Просто посмотреть, можно ли такое вообще запилить.
Подписывайся на мой TГ-канал — там я публикую все свои эксперименты, код и приглашаю к обсуждению. Только факты, мат и никакой политоты.
| # | Наименование новости | Тональность | Информативность | Дата публикации |
|---|---|---|---|---|
| 1 | Вайб-кодинг в терминале: настраиваем OpenCode с Claude, GPT и Gemini | 0 | 5 | 30-06-2026 |
| 2 | Как объединить инфраструктуру 35 продуктов в единую платформу данных | 0 | 7 | 26-06-2026 |
| 3 | Почему классический CI/CD не справляется с LLM (и какие release gates мы построили, чтобы это исправить) | 0 | 7 | 04-07-2026 |
| 4 | GitLab представила концепцию agentic infrastructure | 0 | 5 | 25-06-2026 |
| 5 | Бесплатный WAF инструмент кибербезопасности, который я использую | 5 | 8 | 01-07-2026 |
| 6 | Куда бежать с github? | -2 | 5 | 03-07-2026 |
| 7 | Как ограничить расходы на OpenAI API, чтобы ИИ-агенты не сожгли бюджет | 0 | 8 | 04-07-2026 |
| 8 | Comment récupérer des messages Telegram supprimés 2024 | 0 | 5 | 17-01-2026 |
| 9 | Pourquoi Telegram ne m’envoie-t-il pas de code ? | 0 | 5 | 12-02-2026 |
| 10 | Кнопка «наверх» в Django: почему в проде это уже не три строки JavaScript | 0 | 7 | 01-07-2026 |