Linked account contacts never reach the roster #2

Closed
opened 2026-10-07 17:59:32 +00:00 by asxpi · 1 comment

Linked account's contacts never reach the roster

What happens

After linking a real Telegram account (QR, updates running logged), the
user's roster gets only the gateway itself (telegram.<domain>, both).
None of the Telegram contacts appear, so there is nobody to write to without
knowing their numeric id.

Why

docs/DESIGN.md, Registration step 5: "Done: the gateway asks for a presence
subscription (XEP-0100), pushes the Telegram contacts into the roster
(XEP-0356, else XEP-0144), and says so", and the layout lists
roster.tcl XEP-0356 roster pushes, XEP-0144 fallback. There is no
component/roster.tcl, and nothing in component/ sends a roster push. The
Milestones section puts "roster sync" in M1, so DESIGN.md contradicts
itself about what M0 delivers.

anotherim-server already grants the gateway what it needs: ejabberd logs
Granting permissions to external component 'telegram.<domain>': roster = both, presence = roster, message = outgoing.

Expected

Either push the contacts on link (and on restart, as a diff) through
XEP-0356, or move step 5 to M1 in DESIGN.md so the M0 docs match the code.

Environment

feat/telegram-connect at cb68dd9, in anotherim-server's compose
deployment (ejabberd 26.09).

## Linked account's contacts never reach the roster ### What happens After linking a real Telegram account (QR, `updates running` logged), the user's roster gets only the gateway itself (`telegram.<domain>`, both). None of the Telegram contacts appear, so there is nobody to write to without knowing their numeric id. ### Why `docs/DESIGN.md`, Registration step 5: "Done: the gateway asks for a presence subscription (XEP-0100), pushes the Telegram contacts into the roster (XEP-0356, else XEP-0144), and says so", and the layout lists `roster.tcl XEP-0356 roster pushes, XEP-0144 fallback`. There is no `component/roster.tcl`, and nothing in `component/` sends a roster push. The Milestones section puts "roster sync" in M1, so DESIGN.md contradicts itself about what M0 delivers. anotherim-server already grants the gateway what it needs: ejabberd logs `Granting permissions to external component 'telegram.<domain>': roster = both, presence = roster, message = outgoing`. ### Expected Either push the contacts on link (and on restart, as a diff) through XEP-0356, or move step 5 to M1 in DESIGN.md so the M0 docs match the code. ### Environment `feat/telegram-connect` at `cb68dd9`, in anotherim-server's compose deployment (ejabberd 26.09).
ann referenced this issue from a commit 2026-10-12 23:13:07 +00:00
The three open issues: a message to a non-numeric address is bounced instead of dropped (#1), a linked account's contacts reach the roster (#2), and the gateway's presence survives a reconnect (#3). gateway.tcl bounces a chat message to a JID on our domain that names no peer with item-not-found, saying how to address a Telegram user; when the localpart is a Telegram username the linked account resolves it and the error names the JID to write to, or says no such user; a presence subscription to such a JID is answered unsubscribed. The engine gains `contacts` (account.Contacts over contacts.getContacts, the users' access hashes kept through peers.Apply, deleted accounts left out; the fake answers Alice and Bob; docs/frames.md), and the new component/roster.tcl puts them in the user's roster when the account turns ready and every time the component's stream comes up: with the roster privilege the server states in its XEP-0356 <privilege> message, a roster get and the pushes that make it match (adds, renames, contacts gone from Telegram removed, one item per iq); without one, an XEP-0144 roster item exchange. The grant may arrive before or after the stream's ready event, so it is kept until the stream drops and the sync waits two seconds for it. On every ready main.tcl sends each linked user the gateway's presence again and a probe, and the engine's account list sends it too when the stream was up first. DESIGN.md's registration step 5 and the milestones now say what M0 does. The libtacky submodule moves to the rig that grants the privilege under XMPP_COMPONENT_PRIVILEGE=1; make e2e runs the end-to-end test in both modes, with the gateway restarted in the middle to see its presence come back and the roster left alone. make test passes (coverage 92.5 %); e2e 44 of 44 with the privilege and 44 of 44 without.
Owner

Fixed in 58b32c7 (main): the engine answers contacts (contacts.getContacts, the users' access hashes kept, deleted accounts left out; docs/frames.md), and the new component/roster.tcl puts them in the user's roster when the account turns ready and on every component connect — XEP-0356 pushes with a diff against the roster (adds, renames, contacts gone from Telegram removed, one item per iq) where the server grants the roster privilege, an XEP-0144 roster item exchange otherwise.

Two things worth knowing: ejabberd runs a privileged roster set as the user's own, so the items land with subscription none whatever the push says; and mod_privilege wants an access rule name — with an ACL name ejabberd logs "Granting no permissions" and carries on (anotherim-server's ejabberd.yml already defines the access rule). DESIGN.md's step 5 and the milestones now say what M0 does. make e2e runs both modes (44/44 each); it needs libtacky ≥ v1.0.0-rc2 for the rig's XMPP_COMPONENT_PRIVILEGE knob.

Fixed in 58b32c7 (main): the engine answers `contacts` (contacts.getContacts, the users' access hashes kept, deleted accounts left out; docs/frames.md), and the new `component/roster.tcl` puts them in the user's roster when the account turns ready and on every component connect — XEP-0356 pushes with a diff against the roster (adds, renames, contacts gone from Telegram removed, one item per iq) where the server grants the roster privilege, an XEP-0144 roster item exchange otherwise. Two things worth knowing: ejabberd runs a privileged roster set as the user's own, so the items land with subscription `none` whatever the push says; and `mod_privilege` wants an *access rule* name — with an ACL name ejabberd logs "Granting no permissions" and carries on (anotherim-server's ejabberd.yml already defines the access rule). DESIGN.md's step 5 and the milestones now say what M0 does. `make e2e` runs both modes (44/44 each); it needs libtacky ≥ v1.0.0-rc2 for the rig's `XMPP_COMPONENT_PRIVILEGE` knob.
ann closed this issue 2026-10-12 23:17:57 +00:00
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
another-im/tackygram#2
No description provided.