Telegram SSH / Serverless Architecture

Этот документ показывает, как устроена текущая реализация: где живет Telegram-сессия, как команды запускаются через Docker, как работает синхронизация чтения сообщений и каким образом это интегрируется с SSH и Yandex Cloud Functions.

Runtime: Docker-first CLI core: tg_cli.py Session: tdlib_session/ Remote entrypoints: tg_list, tg_get, tg_send Cloud integration: SSH-based

High-Level Scheme

Browser / Client Manual use or automation Calls HTTP endpoint Yandex Cloud Function Generic SSH executor or dedicated Telegram API SSH Session Non-interactive shell Absolute wrapper path User PATH Wrappers tg_list / tg_get / tg_send tg_search / tg_resolve Docker Wrapper Layer bin/_tg_exec.py Builds docker run command Filters TDLib stderr noise Donor Runtime Container ghcr.io/paul-nameless/tg:latest Compatible TDLib environment Avoids OpenSSL 1.1 host issue Application Core tg_cli.py login / list / get / send search / resolve Live Session State tdlib_session/ DB, binlog, files, phone.txt Telegram / TDLib Sync openChat -> getChat -> getChatHistory stabilize head -> return result -> closeChat

Why Docker Is The Real Runtime

Локальный .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

  1. Клиент или browser вызывает HTTP endpoint cloud function.
  2. Cloud function формирует SSH-команду или строит whitelist-команду Telegram API.
  3. SSH на сервере запускает wrapper вроде /home/evgeny/.local/bin/tg_get.
  4. Wrapper строит docker run и монтирует репозиторий как /workspace.
  5. В контейнере выполняется python3 tg_cli.py ....
  6. 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 уже подтянул локально после старта. Теперь чтение синхронизируется заметно строже.

  1. tg_get проходит авторизацию на уже существующей TDLib-сессии.
  2. По нужному чату выполняется openChat, чтобы TDLib приоритизировал апдейты именно для него.
  3. В цикле опрашиваются getChat и getChatHistory(..., only_local=False).
  4. Сравнивается верхнее сообщение истории с chat.last_message.id.
  5. После совпадения выдерживается короткое окно стабилизации.
  6. Возвращается лучший согласованный snapshot, затем выполняется closeChat.
Это не "магическая абсолютная гарантия" для бесконечно активного чата при любом таймауте, а практический режим "верни максимально свежую голову, которую TDLib успел синхронизировать в заданное окно времени".

Supported Commands

tg_login
tg_list --limit 7
tg_get --chat -1001957396718 --limit 15
tg_send --chat -1001957396718 --text "всем чмоки в етим чати"
tg_search --query "вайбе" --limit 5
tg_resolve --chat saved

HTTP API Shape

action=list&limit=7
action=get&chat=-1001957396718&limit=15
action=send&chat=-1001957396718&text=всем чмоки в етим чати
action=search&query=вайбе&limit=5
action=resolve&chat=saved
action=list&limit=7&format=json

Operational Notes