package tdesktop import ( "net/netip" "time" "github.com/iamxvbaba/td/tg" "telesrv/internal/links" ) // BuildConfig 构造 help.getConfig 返回的 tg.Config,含自建 DC 的 DCOptions。 // // 字段值取 Telegram 常见默认;TDesktop 联调阶段按客户端实际需要微调 // (记录于 docs/compatibility-matrix.md)。 func BuildConfig(dc int, ip string, port int, now time.Time, publicBaseURL string) *tg.Config { // TELESRV_ADVERTISE_IP is validated during config loading. Parse again here // only to derive the wire ipv6 flag and to render IPv4-mapped addresses in // their canonical form. Keeping the advertised route in help.getConfig is a // protocol invariant: clients replace or persist this list for reconnects. addr, err := netip.ParseAddr(ip) if err == nil { addr = addr.Unmap() ip = addr.String() } meURLPrefix := links.NormalizeBaseURL(publicBaseURL) + "/" config := &tg.Config{ Date: int(now.Unix()), Expires: int(now.Add(time.Hour).Unix()), TestMode: false, ThisDC: dc, DCOptions: []tg.DCOption{{ Ipv6: addr.Is6(), ID: dc, IPAddress: ip, Port: port, }}, ChatSizeMax: 200, MegagroupSizeMax: 200000, ForwardedCountMax: 100, OnlineUpdatePeriodMs: 120000, OfflineBlurTimeoutMs: 5000, OfflineIdleTimeoutMs: 30000, OnlineCloudTimeoutMs: 300000, NotifyCloudDelayMs: 30000, NotifyDefaultDelayMs: 1500, PushChatPeriodMs: 60000, PushChatLimit: 2, EditTimeLimit: 172800, // 官方现行 revoke 三元组:无时限 + 允许撤回对方发来的私聊消息。 // TDesktop 的私聊 "Also delete for X" 复选框要求 // revoke_pm_inbox=true 且 revoke_pm_time_limit=0x7FFFFFFF, // 否则双向删除 UI 永不出现。 RevokeTimeLimit: 2147483647, RevokePmTimeLimit: 2147483647, RevokePmInbox: true, RatingEDecay: 2419200, StickersRecentLimit: 200, CallReceiveTimeoutMs: 20000, CallRingTimeoutMs: 90000, CallConnectTimeoutMs: 30000, CallPacketTimeoutMs: 10000, MeURLPrefix: meURLPrefix, CaptionLengthMax: 1024, MessageLengthMax: 4096, WebfileDCID: dc, } config.SetReactionsDefault(&tg.ReactionEmoji{Emoticon: DefaultReactionEmoticon}) // The GIF picker's trending/search panel reads this from help.getConfig's // typed Config (gifs_list_widget.cpp: session().serverConfig().gifSearchUsername) // -- NOT from help.getAppConfig's loose JSON blob, which is a separate RPC/ // response entirely. Must match the built-in @gif system bot's username // (domain.GifBotUser().Username), whose inline results are served // synchronously in-process (see rpc.ServiceBotInlineResults). config.SetGifSearchUsername("gif") return config }