feat: sync host-based public app links

This commit is contained in:
A 2026-07-22 21:43:56 +08:00
parent 10de462191
commit 8cfb6f74c1
19 changed files with 375 additions and 26 deletions

View file

@ -20,6 +20,7 @@ import (
"github.com/iamxvbaba/td/tlprofile"
compatandroid "telesrv/internal/compat/android"
"telesrv/internal/domain"
"telesrv/internal/links"
"telesrv/internal/observability/dbtrace"
)
@ -83,6 +84,10 @@ type Config struct {
RtmpIngestURL string
// PublicBaseURL 是所有客户端可见 telesrv 链接的公开根 URL。
PublicBaseURL string
// PublicAppScheme/PublicAppLinkBase 控制客户端 deep linkbase 为空时
// 保持 <scheme>://<route>,非空时生成 <base>/<route>。
PublicAppScheme string
PublicAppLinkBase string
// TempKeyResolveCacheTTL 是 PFS temp→perm auth key 解析的进程内缓存有效期。>0 时同一 temp key
// 在 TTL 内复用上次解析、跳过每帧 ResolveAuthKey 的 PG 查询0默认/测试)关闭=每帧重校验。
// 显式撤销会删除协议 auth key、清缓存并断开活跃连接TTL 只影响自然过期或异常路径下的
@ -99,6 +104,7 @@ type Config struct {
// 剥离 invokeWithLayer / initConnection / invokeWithoutUpdates / invokeAfter*,并兜底未注册 RPC。
type Router struct {
cfg Config
appLinks links.AppLinkBuilder
log *zap.Logger
clock clock.Clock
deps Deps
@ -236,11 +242,15 @@ type authUserCacheEntry struct {
// New 创建 Router由各业务域自行注册其 RPC handlerregisterHelp/Auth/Users/Updates
func New(cfg Config, deps Deps, log *zap.Logger, clk clock.Clock) *Router {
assertNoTypedNilDeps(deps)
appLinks, err := links.NewAppLinkBuilder(cfg.PublicAppScheme, cfg.PublicAppLinkBase)
if err != nil {
panic(fmt.Sprintf("initialize public app links: %v", err))
}
instanceID := cfg.InstanceID
if instanceID == "" {
instanceID = fmt.Sprintf("%016x", randomNonZeroInt64())
}
r := &Router{cfg: cfg, log: log, clock: clk, deps: deps, exactProfiles: make(map[clientInfoSessionKey]exactSessionProfileEntry), authLayerEvidence: make(map[[8]byte]authLayerDefaultEvidence), presence: newPresenceTracker(), callbacks: newCallbackRegistry(deps.BotCallbacks), inlines: newInlineRegistry(botInlineQueryTTL, deps.Inline), webviews: newWebViewRegistry(webViewSessionTTL, deps.Inline), loginTokens: newLoginTokenRegistry(), botAPIUpdates: newBotAPIUpdateNotifier(), tempKeyResolveCache: newTempKeyResolveCache(cfg.TempKeyResolveCacheMaxEntries), storyProjectionCache: newStoryProjectionCache(clk.Now), storyPinnedCache: newStoryPinnedAvailableCache(clk.Now), storyPinnedListCache: newStoryPinnedStoriesCache(clk.Now), channelFullBotCache: newChannelFullBotInfoCache(clk.Now), userFullProjectionCache: newUserFullProjectionCache(clk.Now), peerSettingsProjectionCache: newPeerSettingsProjectionCache(clk.Now), channelFullProjectionCache: newChannelFullProjectionCache(clk.Now), emojiStickers: newEmojiStickerIndex(clk.Now), notifySettings: newNotifySettingsCache(clk.Now), stickerCatalog: newStickerCatalogCache(clk.Now), accountSettings: newAccountSettingsCache(clk.Now), accountFreezeWake: make(chan struct{}, 1), instanceID: instanceID}
r := &Router{cfg: cfg, appLinks: appLinks, log: log, clock: clk, deps: deps, exactProfiles: make(map[clientInfoSessionKey]exactSessionProfileEntry), authLayerEvidence: make(map[[8]byte]authLayerDefaultEvidence), presence: newPresenceTracker(), callbacks: newCallbackRegistry(deps.BotCallbacks), inlines: newInlineRegistry(botInlineQueryTTL, deps.Inline), webviews: newWebViewRegistry(webViewSessionTTL, deps.Inline), loginTokens: newLoginTokenRegistry(), botAPIUpdates: newBotAPIUpdateNotifier(), tempKeyResolveCache: newTempKeyResolveCache(cfg.TempKeyResolveCacheMaxEntries), storyProjectionCache: newStoryProjectionCache(clk.Now), storyPinnedCache: newStoryPinnedAvailableCache(clk.Now), storyPinnedListCache: newStoryPinnedStoriesCache(clk.Now), channelFullBotCache: newChannelFullBotInfoCache(clk.Now), userFullProjectionCache: newUserFullProjectionCache(clk.Now), peerSettingsProjectionCache: newPeerSettingsProjectionCache(clk.Now), channelFullProjectionCache: newChannelFullProjectionCache(clk.Now), emojiStickers: newEmojiStickerIndex(clk.Now), notifySettings: newNotifySettingsCache(clk.Now), stickerCatalog: newStickerCatalogCache(clk.Now), accountSettings: newAccountSettingsCache(clk.Now), accountFreezeWake: make(chan struct{}, 1), instanceID: instanceID}
r.channelFanout = newChannelFanoutDispatcher(r, defaultChannelFanoutShards, defaultChannelFanoutBuffer)
r.botAPIEnqueueQueue = newBotAPIEnqueueDispatcher(log, defaultBotAPIEnqueueBuffer)
r.webPageResolveSem = make(chan struct{}, webPageResolveConcurrency)