Этот документ показывает, как устроена текущая реализация: где живет Telegram-сессия,
как команды запускаются через Docker, как работает синхронизация чтения сообщений
и каким образом это интегрируется с SSH и Yandex Cloud Functions.
Локальный .venv остается в проекте для чтения кода и быстрых проверок, но
продовый запуск команд на этом сервере идет через Docker.
Колесо python-telegram содержит bundled libtdjson.so.
На Ubuntu 24.04 эта библиотека локально требует libssl.so.1.1, которого на хосте нет.
Образ ghcr.io/paul-nameless/tg:latest уже совместим и работает без дополнительных плясок.
Where The Session Lives
Состояние Telegram-клиента хранится в tdlib_session/. Это живая TDLib-сессия,
которую переиспользуют все последующие команды.
phone.txt хранит номер телефона.
База и binlog позволяют не логиниться заново при каждом вызове.
Каталог исключен из git, потому что он приватный и машинозависимый.
Execution Flow
Клиент или browser вызывает HTTP endpoint cloud function.
Cloud function формирует SSH-команду или строит whitelist-команду Telegram API.
SSH на сервере запускает wrapper вроде /home/evgeny/.local/bin/tg_get.
Wrapper строит docker run и монтирует репозиторий как /workspace.
В контейнере выполняется python3 tg_cli.py ....
Wrapper очищает служебный stderr TDLib и возвращает чистый результат.
Cloud Function Split
Generic SSH Executor
Выполняет произвольные shell-команды и должен оставаться приватным, потому что это
фактически удаленный shell.
Dedicated Telegram API
Принимает только list, get, send, search,
resolve и сам собирает безопасную команду через абсолютные пути.
How tg_get Works Now
Главная техническая доработка в текущей версии касается свежести чтения сообщений. Раньше короткоживущий
клиент успевал увидеть только тот хвост истории, который TDLib уже подтянул локально после старта.
Теперь чтение синхронизируется заметно строже.
tg_get проходит авторизацию на уже существующей TDLib-сессии.
По нужному чату выполняется openChat, чтобы TDLib приоритизировал апдейты именно для него.
В цикле опрашиваются getChat и getChatHistory(..., only_local=False).
Сравнивается верхнее сообщение истории с chat.last_message.id.
После совпадения выдерживается короткое окно стабилизации.
Возвращается лучший согласованный snapshot, затем выполняется closeChat.
Это не "магическая абсолютная гарантия" для бесконечно активного чата при любом таймауте,
а практический режим "верни максимально свежую голову, которую TDLib успел синхронизировать
в заданное окно времени".