2.5 KiB
2.5 KiB
Telegram Transport
Overview
TelegramClient is the single transport for Telegram writes. It owns a
TelegramOutbox that serializes send/edit/delete operations, applies
coalescing, and enforces rate limits + retry-after backoff.
This document captures current behavior so transport changes stay intentional.
Flow
- CLI emits JSON events.
- We render progress on every step and diff against the last output.
- Only deltas enqueue a Telegram edit.
- High-value messages enqueue a send.
- All writes go through the outbox.
Outbox model
- Single worker processes one op at a time.
- Each op is keyed; only one pending op per key.
- New ops with the same key overwrite the payload but do not reset
queued_at(fairness).
Keys (include chat_id to avoid cross-chat collisions):
("edit", chat_id, message_id)for edits (coalesced).("delete", chat_id, message_id)for deletes.("send", chat_id, replace_message_id)when replacing a progress message.- Unique key for normal sends.
Scheduling:
- Ordered by
(priority, queued_at). - Priorities: send=0, delete=1, edit=2.
- Within a priority tier, the oldest pending op runs first.
updated_atis kept for debugging only.
Rate limiting + backoff
- Per-chat pacing is computed from
private_chat_rpsandgroup_chat_rps. Defaults: 1.0 msg/s for private, 20/60 msg/s for groups (≈1 message every 3s). - Pacing is currently enforced via a single global
next_at; per-chatnext_atis a future consideration if we ever run multiple chats in parallel. - The worker waits until
max(next_at, retry_at)before executing the next op. - On 429,
RetryAfteris raised usingparameters.retry_afterwhen present; if missing, we fall back to a 5s delay. The outbox setsretry_atand requeues the op if no newer op for the same key has arrived.
Error handling
- Non-429 errors are logged and dropped (no retry).
- On
RetryAfter, the op is retried unless a newer op superseded the same key.
Replace progress messages
send_message(replace_message_id=...):
- Drops any pending edit for that progress message.
- Enqueues the send at highest priority.
- If the send succeeds, enqueues a delete for the old progress message.
This keeps the final message first and avoids deleting progress if the send fails.
getUpdates
get_updates bypasses the outbox and retries on RetryAfter by sleeping
for the provided delay.
Close semantics
TelegramClient.close() shuts down the outbox and closes the HTTP client.
Pending ops are failed with None (best-effort).