A subId is the only selector of a subscription's inbounds and external
links, so a blank one matched every client stored without a subId, as
clients embedded through inbounds/add or inbounds/import are. The
Telegram bot authorised a client by email and then looked its links up
by that blank subId, handing a bound user the working links of every
other subId-less client.
A blank subId now resolves to nothing in the subscription service, and
the bot builds a subId-less client's own links by email, as the panel's
client page does.
The bot answered every action with a new message, so a chat filled with stale
menus whose buttons still acted, and long client or inbound lists were paged
through dozens of buttons. Each chat now has one live screen that is edited in
place: the menu is grouped into Server, Clients, Traffic and Maintenance, lists
open through inline search, the add-client flow starts from a draft card, QR
codes arrive as one labelled sheet, and repeated notices collapse into one with
a counter. A client's /start and /usage show only that client's own links and
usage, groups are refused, and the settings page warns when the bot's inline
mode is off. Admin topics, the indexed Telegram lookup and every locale,
Slovak included, carry over.
The bot's "individual links" and QR actions fetched the client's own
subscription over HTTP from the public URL it builds for display. With no
sub or web domain set that URL falls back to the machine's hostname, which
usually does not resolve (`lookup exhausted-reply: no such host`), and even
a resolvable name fails behind NAT, a firewall or a disabled sub server.
Both actions now ask InboundService.GetSubLinks, the in-process provider the
panel's links API already uses, with the host taken from that same URL so the
link addresses are unchanged. The now-unused pooled HTTP client goes too.
Closes#6597