owpengram-server/internal/compat/tdesktop/defaults.go

181 lines
8.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package tdesktop
import (
"github.com/gotd/td/tg"
"telesrv/internal/seed/catalog"
)
const (
appConfigHash = 16 // app config 内容变更时必须递增,否则缓存端只会收到 notModified。
countriesListHash = 1
timezonesListHash = 1
)
// AppConfig returns the fallback TDesktop startup app config used when HelpService is absent.
func AppConfig(hash int) tg.HelpAppConfigClass {
if hash == appConfigHash {
return &tg.HelpAppConfigNotModified{}
}
return &tg.HelpAppConfig{
Hash: appConfigHash,
Config: readMarkAppConfig(""),
}
}
func readMarkAppConfig(mapboxToken string) *tg.JSONObject {
values := []tg.JSONObjectValue{
{Key: "chat_read_mark_size_threshold", Value: &tg.JSONNumber{Value: 50}},
{Key: "chat_read_mark_expire_period", Value: &tg.JSONNumber{Value: 604800}},
{Key: "pm_read_date_expire_period", Value: &tg.JSONNumber{Value: 604800}},
{Key: "quote_length_max", Value: &tg.JSONNumber{Value: 1024}},
{Key: "telegram_antispam_group_size_min", Value: &tg.JSONNumber{Value: 200}},
{Key: "telegram_antispam_user_id", Value: &tg.JSONString{Value: "5434988373"}},
// premium_purchase_blocked=false客户端把 star gift「Send a Gift」入口与
// premiumCanBuy()=!premium_purchase_blocked 耦合,置 true 会同时隐藏送礼入口
// (详见 app/help/service.go 主配置注释)。这里是无 HelpService 时的最小回退。
{Key: "premium_purchase_blocked", Value: &tg.JSONBool{Value: false}},
// stargifts_blocked=falseDrKLO 缺省 stargiftsBlocked=true 会隐藏 star gift 送礼网格。
{Key: "stargifts_blocked", Value: &tg.JSONBool{Value: false}},
{Key: "reactions_user_max_premium", Value: &tg.JSONNumber{Value: 3}},
// DrKLO 频道自定义 reaction 编辑页用它作为可选 reaction 数量上限。
{Key: "boosts_channel_level_max", Value: &tg.JSONNumber{Value: 100}},
// TDesktop 富文本编辑入口:官方默认缺省 disabled显式 enabled 才显示/允许进入编辑器。
{Key: "rich_message_posting", Value: &tg.JSONString{Value: "enabled"}},
// dialog_filters_enabled=trueTDesktop 据此(或已有文件夹)才显示 Settings→Folders 入口。
{Key: "dialog_filters_enabled", Value: &tg.JSONBool{Value: true}},
{Key: "chatlist_update_period", Value: &tg.JSONNumber{Value: 3600}},
{Key: "chatlist_invites_limit_default", Value: &tg.JSONNumber{Value: 3}},
{Key: "chatlist_invites_limit_premium", Value: &tg.JSONNumber{Value: 20}},
{Key: "chatlists_joined_limit_default", Value: &tg.JSONNumber{Value: 2}},
{Key: "chatlists_joined_limit_premium", Value: &tg.JSONNumber{Value: 20}},
{Key: "stories_stealth_future_period", Value: &tg.JSONNumber{Value: 1500}},
{Key: "stories_stealth_past_period", Value: &tg.JSONNumber{Value: 300}},
{Key: "stories_stealth_cooldown_period", Value: &tg.JSONNumber{Value: 10800}},
{Key: "aicompose_tone_examples_num", Value: &tg.JSONNumber{Value: 3}},
{Key: "aicompose_tone_title_length_max", Value: &tg.JSONNumber{Value: 12}},
{Key: "aicompose_tone_prompt_length_max", Value: &tg.JSONNumber{Value: 1024}},
{Key: "aicompose_tone_saved_limit_default", Value: &tg.JSONNumber{Value: 5}},
{Key: "aicompose_tone_saved_limit_premium", Value: &tg.JSONNumber{Value: 20}},
// upload_markup_video=true 即官方默认emoji/sticker 头像由客户端本地渲染 mp4 后随
// markup 一起上传)。显式下发是为了把曾收到过 false 的客户端持久化配置洗回默认——
// 客户端对缺失的 key 会保留本地旧值,仅删除 key 无法恢复。
{Key: "upload_markup_video", Value: &tg.JSONBool{Value: true}},
// 单 emoji 消息转 InputMediaDice 的白名单;须与 rpc 层 dice 取值表同步。
{Key: "emojies_send_dice", Value: &tg.JSONArray{Value: []tg.JSONValueClass{
&tg.JSONString{Value: "\U0001F3B2"}, // 🎲
&tg.JSONString{Value: "\U0001F3AF"}, // 🎯
&tg.JSONString{Value: "\U0001F3C0"}, // 🏀
&tg.JSONString{Value: "⚽"},
&tg.JSONString{Value: "⚽️"},
&tg.JSONString{Value: "\U0001F3B3"}, // 🎳
&tg.JSONString{Value: "\U0001F3B0"}, // 🎰
}}},
}
if mapboxToken != "" {
// TDesktop 位置选点器WebView+Mapbox GL与 business 位置设置的地图 token
// 缺失时选点器地图空白(瓦片直连 api.mapbox.com不经服务端
values = append(values, tg.JSONObjectValue{Key: "tdesktop_config_map", Value: &tg.JSONObject{Value: []tg.JSONObjectValue{
{Key: "maps", Value: &tg.JSONString{Value: mapboxToken}},
{Key: "geo", Value: &tg.JSONString{Value: mapboxToken}},
{Key: "bmaps", Value: &tg.JSONString{Value: mapboxToken}},
{Key: "bgeo", Value: &tg.JSONString{Value: mapboxToken}},
}}})
}
return &tg.JSONObject{Value: values}
}
// fallbackTimezones 是 catalog 未 seed 时的内置最小时区集。
var fallbackTimezones = []tg.Timezone{
{ID: "Etc/UTC", Name: "UTC", UtcOffset: 0},
{ID: "America/New_York", Name: "Eastern Time", UtcOffset: -5 * 60 * 60},
{ID: "America/Chicago", Name: "Central Time", UtcOffset: -6 * 60 * 60},
{ID: "America/Denver", Name: "Mountain Time", UtcOffset: -7 * 60 * 60},
{ID: "America/Los_Angeles", Name: "Pacific Time", UtcOffset: -8 * 60 * 60},
{ID: "Asia/Shanghai", Name: "China Standard Time", UtcOffset: 8 * 60 * 60},
}
// TimezonesList 返回时区目录:优先用 catalog 固化的官方全量(~419 个),未 seed 时回退内置最小集。
func TimezonesList(hash int) tg.HelpTimezonesListClass {
seeded, h := catalog.Timezones()
src := seeded
if len(src) == 0 {
src, h = nil, timezonesListHash
}
if hash == h {
return &tg.HelpTimezonesListNotModified{}
}
items := fallbackTimezones
if len(src) > 0 {
items = make([]tg.Timezone, 0, len(src))
for _, t := range src {
items = append(items, tg.Timezone{ID: t.ID, Name: t.Name, UtcOffset: t.UTCOffset})
}
}
return &tg.HelpTimezonesList{Hash: h, Timezones: items}
}
// SuggestedDialogFilters 返回新建对话文件夹时的「推荐文件夹」模板(官方固定语义:
// Unread/Personal/Unmuted/Groups/Channels/Bots)。客户端据此一键创建对应规则的文件夹;
// 模板 id 仅占位,用户采纳时客户端会以新 id 调 updateDialogFilter 真正创建。
func SuggestedDialogFilters() []tg.DialogFilterSuggested {
mk := func(id int, title, desc string, set func(*tg.DialogFilter)) tg.DialogFilterSuggested {
df := &tg.DialogFilter{
ID: id,
Title: tg.TextWithEntities{Text: title, Entities: []tg.MessageEntityClass{}},
PinnedPeers: []tg.InputPeerClass{},
IncludePeers: []tg.InputPeerClass{},
ExcludePeers: []tg.InputPeerClass{},
}
set(df)
return tg.DialogFilterSuggested{Filter: df, Description: desc}
}
allTypes := func(d *tg.DialogFilter) {
d.Contacts, d.NonContacts, d.Groups, d.Broadcasts, d.Bots = true, true, true, true, true
}
return []tg.DialogFilterSuggested{
mk(2, "Unread", "New messages", func(d *tg.DialogFilter) { allTypes(d); d.ExcludeRead = true }),
mk(3, "Personal", "Personal chats", func(d *tg.DialogFilter) { d.Contacts, d.NonContacts = true, true }),
mk(4, "Unmuted", "Unmuted chats", func(d *tg.DialogFilter) { allTypes(d); d.ExcludeMuted = true }),
mk(5, "Groups", "Group chats", func(d *tg.DialogFilter) { d.Groups = true }),
mk(6, "Channels", "Channels only", func(d *tg.DialogFilter) { d.Broadcasts = true }),
mk(7, "Bots", "Bot chats", func(d *tg.DialogFilter) { d.Bots = true }),
}
}
// CountriesList 返回登录页国家区号目录:优先用 catalog 固化的官方全量(~235 国),未 seed
// 时回退内置最小集(US/CN)。生产路径通常经 HelpService.GetCountries → defaultCountries
// 走 catalog;此函数是 HelpService 缺省时的兜底。
func CountriesList(hash int) tg.HelpCountriesListClass {
list := catalog.Countries()
if len(list.Countries) == 0 {
if hash == countriesListHash {
return &tg.HelpCountriesListNotModified{}
}
return &tg.HelpCountriesList{
Hash: countriesListHash,
Countries: []tg.HelpCountry{
{ISO2: "US", DefaultName: "United States", CountryCodes: []tg.HelpCountryCode{{CountryCode: "1", Prefixes: []string{""}, Patterns: []string{"XXX XXX XXXX"}}}},
{ISO2: "CN", DefaultName: "China", CountryCodes: []tg.HelpCountryCode{{CountryCode: "86", Prefixes: []string{""}, Patterns: []string{"XXX XXXX XXXX"}}}},
},
}
}
if hash == list.Hash {
return &tg.HelpCountriesListNotModified{}
}
out := &tg.HelpCountriesList{Hash: list.Hash, Countries: make([]tg.HelpCountry, 0, len(list.Countries))}
for _, c := range list.Countries {
item := tg.HelpCountry{
Hidden: c.Hidden,
ISO2: c.ISO2,
DefaultName: c.DefaultName,
Name: c.Name,
CountryCodes: make([]tg.HelpCountryCode, 0, len(c.CountryCodes)),
}
for _, cc := range c.CountryCodes {
item.CountryCodes = append(item.CountryCodes, tg.HelpCountryCode{CountryCode: cc.CountryCode, Prefixes: cc.Prefixes, Patterns: cc.Patterns})
}
out.Countries = append(out.Countries, item)
}
return out
}