Files
xmpp-server-prosody/references/slidge-registration-and-avatar-gap.md
2026-09-06 13:51:11 +00:00

78 lines
4.2 KiB
Markdown

# 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).