# Slidgram (XMPP↔TG bridge): registration flow & avatar HTTP gap Companion to `slidge-telegram-bridge-nixg.md` (full bridge setup + SOCKS5). These are the two remaining user-facing/known-weak items, validated against slidgram 0.4.2.dev0 code inside the `icq-slidgram` container (2026-08-29) and the offline docs copy at `/opt/icq/docs/slidgram/`. ## 1. Registration of a Telegram account through the bridge Two ways (per slidgram docs `user/registration.rst`); both target the component JID `telegram.nixg.ru` (no @, no local part): - **Method A — adhoc "Register" command** (Gajim / Movim / Cheogram / Converse info card → Commands): opens a form. - **Method B — text message**: send `register` to `telegram.nixg.ru`; bridge replies with the same form. Form fields (from `slidgram/gateway.py:validate`): - `phone` — international format, e.g. `+7...` (validated by `is_valid_phone_number`). - `api_id`, `api_hash` — user-provided from https://my.telegram.org/apps (my.telegram.org is plain HTTP, reachable from RF in a normal browser — only MTProto/telegram-asset traffic needs the tunnel). If the server env has `API_ID`/`API_HASH` preset (slidgram/config.py), the form omits these fields. Flow under the hood: 1. `Client.connect()` — if the session is already logged in, aborts early. 2. `send_code(phone)` → stores `phone_code_hash`; user gets an SMS/code on other TG clients. Timeout to enter it: `REGISTRATION_AUTH_CODE_TIMEOUT` (default 60 s, config.py). 3. `sign_in(phone, code_hash, code)`; if the account has 2FA, catches `SessionPasswordNeeded` and asks for the password (`check_password`). After success: contacts appear in the XMPP roster as puppet JIDs `123456789@telegram.nixg.ru`; Telegram messages mirror into the XMPP dialog. All registration traffic runs over Pyrogram MTProto → `SLIDGRAM_PROXY` (SOCKS5) → works from RF. Check `docker logs icq-slidgram` for register/login/avatar/error. Constraints / gotchas: - **One phone number per server**: re-registering the same number → "Someone is already using this phone number on this server". - 2FA password required if enabled; code entry is time-limited. - Converse web: adhoc command lives in the contact's info card; if the roster isn't visible yet, the gateway JID can be added as a manual contact. ## 2. Avatar download timeout — root cause (confirmed in code) Symptom: avatars/logo (e.g. `https://web.telegram.org/img/logo_share.png`) time out from RF; messaging is unaffected. - `slidge/core/gateway.py:399` creates `self.http = aiohttp.ClientSession()` with **no proxy**; `slidge/db/avatar.py:112` (`self.http.get(url)`) downloads URL-based avatars directly → blocked in RF. - MTProto side IS proxied: `slidgram/gateway.py:validate()` passes `proxy=_proxy` (built from `SLIDGRAM_PROXY`) to the Pyrogram `Client`. - Contact photo avatars use Pyrogram `download_media()` via `slidgram/telegram.py:download_avatar` (`AVATAR_DOWNLOAD_SLEEP=15` between downloads) — proxied and working. The HTTP gap only hits URL-based avatars and the component logo. Fix options (pick one when implementing): 1. `aiohttp.ClientSession(trust_env=True)` + env `HTTP_PROXY/HTTPS_PROXY/ALL_PROXY`. ⚠️ aiohttp supports SOCKS5 only through the extra `aiohttp-socks` package; a plain HTTP proxy env var works if that proxy is RF-reachable (or points at the tunnel's HTTP side). 2. nginx reverse-proxy on bigbox rewriting `web.telegram.org` asset URLs through the tunnel — no code changes in the container. 3. Where the avatar is a Telegram file_id, rely on Pyrogram `download_media()` (already proxied) and only proxy the remaining external URLs. ## 3. Useful container paths (diagnostics) - `slidgram/telegram.py` — `Client(TelegramClient)` subclass, `download_avatar`, `handle_flood` decorator around MTProto calls. - `slidgram/gateway.py` — `validate()` / `validate_two_factor_code()` registration. - `slidgram/config.py` — `API_ID`, `API_HASH`, `REGISTRATION_AUTH_CODE_TIMEOUT`, `GROUP_HISTORY_MAXIMUM_MESSAGES`, `BIG_AVATARS`. - `slidge/core/gateway.py` — `__set_http()` at :399 (unproxied aiohttp session). - `slidge/db/avatar.py` — `CachedAvatar.__download` / `url_modified` (HTTP HEAD/GET).