Telegram Dialogs Overview
Bounded context
backend/tg_client/dialogs is the backend subsystem responsible for:
- accepting WebSocket actions from
/ws/chats/ - routing commands into shard-owned TDLib runtime workers
- building typed response payloads for chats, messages, profiles, sessions, invites, and media
- consuming TDLib updates and converting them into live
chat_updateevents - maintaining short-horizon projections and replay buffers for reconnect/recovery
Current code footprint
10active handler modules undercommands/handlers/104registered commands routed throughcommands.registry- one shared composition root:
backend/tg_client/dialogs/tdlib/facade.py - one transport wrapper:
backend/tg_client/dialogs/tdlib/base.py - one owner runtime entry for command execution and TDLib update processing:
backend/tg_client/account_runtime/owner_worker.py
Module map
| Module | Purpose |
|---|---|
commands/ |
Command registry, handler groups, command context assembly |
tdlib/base.py |
Thin TDLib transport wrapper around call_method() |
tdlib/api/ |
Raw TDLib wrappers grouped by domain |
tdlib/services/ |
Business logic and orchestration layer |
tdlib/normalizers/ |
Result shaping and typed response builders |
domain/ |
Shared payload builders for message/chat/profile structures |
services/update_runtime_service.py |
TDLib update orchestration in owner runtime |
services/media_loader.py |
Async media/cloud resolution pipeline |
cache/dialog_cache.py |
Dialog snapshots, file cache, profile cache, replay buffer |
ws/list_chats/consumers.py |
WebSocket gateway entry point |
Architectural intent
The current implementation is already split into layers:
- Transport / raw API:
TdlibBaseClient+tdlib/api/* - Business logic:
tdlib/services/* - Typed normalization:
tdlib/normalizers/* - Shared payload builders:
dialogs/domain/* - Runtime integration:
commands/*,UpdateRuntimeService,owner_worker.py
Important runtime facts
- commands are no longer executed directly inside the WebSocket consumer
- the gateway publishes commands through messaging subjects and owner runtime handles them
- responses are emitted as live
chat_updatepayloads, not as direct synchronous WebSocket replies - some commands are streaming (
get_chats,get_recently_opened_chats,open_dialog) - some commands acknowledge immediately and then emit extra async events later (
download_file,get_custom_emoji_media)