From a336c99d6d224bcfb98a6b53ee6d35bb709c9de9 Mon Sep 17 00:00:00 2001 From: onysd Date: Mon, 13 Jul 2026 10:30:24 +0300 Subject: [PATCH] branding for server --- cmd/telesrv/main.go | 5 ++ ...86_owpengram_system_account_brand.down.sql | 3 ++ ...0086_owpengram_system_account_brand.up.sql | 8 ++++ .../seedassets/owpengram_system_avatar.png | Bin 0 -> 20880 bytes internal/app/files/system_avatar_seed.go | 44 ++++++++++++++++++ internal/domain/system.go | 32 +++++++++++-- 6 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 deploy/migrations/0086_owpengram_system_account_brand.down.sql create mode 100644 deploy/migrations/0086_owpengram_system_account_brand.up.sql create mode 100644 internal/app/files/seedassets/owpengram_system_avatar.png create mode 100644 internal/app/files/system_avatar_seed.go diff --git a/cmd/telesrv/main.go b/cmd/telesrv/main.go index 6632746d..720fabf4 100644 --- a/cmd/telesrv/main.go +++ b/cmd/telesrv/main.go @@ -443,6 +443,11 @@ func run(logger *zap.Logger) error { zap.Int("blobs", stats.Blobs), ) } + if seeded, err := filesService.SeedOfficialSystemAvatar(ctx); err != nil { + return fmt.Errorf("seed official system avatar: %w", err) + } else if seeded { + logger.Info("官方系统账号头像种子导入完成", zap.Int64("photo_id", domain.OfficialSystemUserPhotoID)) + } if stats, err := filesService.WarmCaches(ctx); err != nil { logger.Warn("媒体资源缓存预热失败", zap.Error(err)) } else if stats.StickerSets > 0 || stats.Documents > 0 || stats.Blobs > 0 { diff --git a/deploy/migrations/0086_owpengram_system_account_brand.down.sql b/deploy/migrations/0086_owpengram_system_account_brand.down.sql new file mode 100644 index 00000000..482a63b0 --- /dev/null +++ b/deploy/migrations/0086_owpengram_system_account_brand.down.sql @@ -0,0 +1,3 @@ +UPDATE public.users +SET first_name = 'Telegram', username = 'telegram', updated_at = now() +WHERE id = 777000; diff --git a/deploy/migrations/0086_owpengram_system_account_brand.up.sql b/deploy/migrations/0086_owpengram_system_account_brand.up.sql new file mode 100644 index 00000000..23f650f6 --- /dev/null +++ b/deploy/migrations/0086_owpengram_system_account_brand.up.sql @@ -0,0 +1,8 @@ +-- Rebrand the built-in official system account (777000) from the upstream +-- gramsrv default "Telegram"/@telegram to this fork's own identity. Existing +-- databases already seeded by migration 0001 need this as a follow-up +-- UPDATE; migration 0001 itself is never replayed on an already-migrated +-- database. +UPDATE public.users +SET first_name = 'OwpenGram', username = 'owpengram', updated_at = now() +WHERE id = 777000; diff --git a/internal/app/files/seedassets/owpengram_system_avatar.png b/internal/app/files/seedassets/owpengram_system_avatar.png new file mode 100644 index 0000000000000000000000000000000000000000..323390560e6571c39606033315d089d00e089b9b GIT binary patch literal 20880 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 }(?; zU%kHP(ay0vr$V{=dS&!SF^F+`HGxfhGRY)J3ZhMM=d5q2hP(7EOfhZViCUA-#`iDH z;8ys~a!jn--@K9&n0F_9k1 zz-JRXXQy9APu7d%{@}y}-sn+LNJhaY;y9V!I(Yr4gEenvkT}+(q4SE~Z@R>(H5E0` z-+fAzA~I`@CfPgDzuC|0b@Gq79SUc?$SI>Dp}hp^5)*PLdDy;{OY{kQUjHzE1LBps z+Vb=nK7qV(9~>|)dvGqi*Tc383^A;J1S?HQOuCAQY8I#73RI#w1X}FVC)S^*lTbPj zeNT04K${;vhp(n|{xBHBzUf{4{0Fv0N#w(&iVMt~N%EMLg%o0Ko%w`SO30#z6>_R5^G{5005A zJ+0HbX};iVmZL2j?~k*e;}^%m^vf#?i@94C&K3+yq+(NHwrJ-4QI{kB6Xi}soz7*% z^HI>Qbr-#8s59i15G%42$U56sT*R32=jD$Cj)WjsR7?y9qj6XCjfJ<@@n@C7mjRR0 zNs7X4?)Zd9oOF~81?B3jg#~5$QQ(xJ=}Y~0@#PHcZ$;uX@qWmwOOqfJFvNG49LF_?H(`VVuU3WzkLP6LUO$i}$_C@$2h(wO_$6$8`E;7IrFt(93 z*d|g6*X4V(5b?;D`Y}gsVcBnr-`A%7L<#D5(SYgvifBxvD)26L3!um8A=!3HTf#`RToF#bMDk59XbAJ8uq zL8=oMV>s57M?$(5Wt6IEltLG%X(z{N4e;^fSGUzHf|W2~eTC{=bt{$;EuhHny4=T# zP#v&0P}^#V;{o!6e!ZY#=e4{FPmP5;B-wJk@)8C4zBf#@@_-W_a1{V;AJk zJpG$1Xodf-Z&1CY^~08MH+4l++K3GdroQP0?6QZ?d^_DIwrIEEB86ytql{I|^t&vF z>NUWl&aaS=S6Tn&G#`NDnXzJ2<%1nSvGI)%>$hZ+K)uEbo=68fgZswl30<+xP=&&9 z@T|U)%2ZS#N2Epys`1q@3KbA+?g(!8yu}|c`t{s7yNKr%GQw`uEThz@J-+v_hgQwwMpR*!A@5tc z&TJ0+l+dF#x%n>blIoqF-@bTKEM+gh!0)Z^Z9QVAJKHD1J{QK`q5nYGcpUz^+%Ep= zjxy_@1^a83^$`6ns2zvl<}LKOdA>br>vo-2#^xm$pd`Je$VjSqk;yoITSbwUlnXi! zEF#DDp~yz5I5iQc38^GSwdvIciuYfQcm}2c=6@FS7 zaSXzj1QD3Ud5(OED9xlE3AE|EPbo+UUv6cIDZcO3c;J|?9Z5tJ2C+@y(S7W&s`a3G zs@Lz_S!ew=ArZ|Vunnf{gmdNOTp=YmFoZXGMnu@Y=iVD4!bKd{#rlvzRtBn%rLMW< zJ0~f=GWV_L`)b@98HNOERgE)U^x@ejcO{)m)u503@@HbXf0>9WqKaQV>7gY1t4`!u zCD85@%w*O^@r%6FHR!^=0D9W_bh>2=_4`Jf4hZFtm(Lrm$&@N@V*hTof*SPfP73Q= zHab2KFd4iPH71;)dVQBP`$kruUIM-f6_$={j?n5Hrz1J*DE*i(TE-RAFu3IQMmuaDB&(Q0tgfSp@H zT_u0b><9w9w++FRX_Gx8xD)kVzUzvO^$eQ#r~B_%GZ9}Q(heL}4fJQ2+L^fN>wcn_ z*J>}lY#=~^;ku=LppR0)!^K^Ha`L`E1AnhLd>=TsaNxbhRN4#Yn1SKoZdcK6lsE#h zxlZHVg6TT5fehPh3qr2GD)m)75t>@7Ml;sV|Q^ zm=aw^>GR!GbU5dJYF)4;O`};s45o0974E?~v8Y;>mABy20Rs|-LWu-vp&%KVQv2E0 z7t_Z9seynsg?!G3Ws9PbjcexL>_io!o8JpFoII_b=Y8Lf913)6djNF|`-+L9{% zH;|qxfr!iw@_$X7XIK+k*M>t8q99FFnj)f71(71s2`Cbp21Gh25@`YHNDD=eGzlt5 z7hC8gv;+ZZD&LJuMD;P>a7U$f@gd#)*K*4}%~dhSn8$yiA+54iC? zYSHOzewq5$&9Cx@ffwU+qW9vvC0ERR5Tq;i<@ks5%utm@=I0Y2!^a~SHzn2kO_hXY z$MiljZz#tz<8L&s?bU>Z3JW+0euptRbv*YP?G$vke?v@=1=kW? zrv4Jg=%4Q-(-yYsA6S^B`#LndYx}(TOS^<^eshSBQ ziR6LA@VrTdTyVLK9sZtFgvuAY5rYi<&Tg$P5D*hnnc|CJvVmTRiLIlI^MAU2JpL8l zlYPN|KPi|}g6M=-TdW3-X$WA&xwr&MamLTJ4j)QiGv4M+!bH zPd97Ji-zF)*gi6?dB|H$bs+RHOY#>U7wN6mSdO7Eb`}!vlzSZEtl(s$e4Lb9!Fb_k}wO9j(~nqA8geTwJEUWb6ow7$-F;0>$&LEjF&3b#^mw zuEe^Of%C7E?ot1j<889J|33y2bA8lpKWKkjMgeRW`}W=RCX6Ep(T@Y}j}yD^^=s~v zH%^1;RBVMw+&|p+;{t)6_TD64Q%#cs#MK0=Yp%5gmcI9U$6pQx$Yvcu&H_? zPff>$|Lg1*<8OY?ghd|eI*&y);S5^#O$vt|MK!J8mA!umQceo!y}9d6|3K{u=+h=R zJZ(K@C7V89@5t$tq25!>vn)BKFUjudUA?#-L)t)rva7J%Xn4ccs( zisJ3-(+DMOu=W;xnXX1G+iJ=eHaiy!0`jX;q^`2^y5)ROqPyAC&NCBYvX3BX_txHP z(=r5;UXUM@4(owGz8ec$OBUGO!-#ltfAcQ^>+4BQ*+_I};|y$fIOqIrhdsBtu1F;z z1xF?Om!7Nx^s{K|ds>%tz%112XqD|&q?Pc?Lv`|x(< zXK(c?^1fuxS2xvg3nSJCc^>H;vwN1fUQIjJIhbD$a8bmndhzDya{`vgkB01?d9DYT z+E z#$&Vd^BF_Kr4Muir8A>YCdVs;9Cv5m0%niugIpzD(joNY-Mc9>{jeX$%51|`wwh+t zt)vC-myaAQsS+Ig+Fj=kP>aF&mtyMzo@|{gPNTP3$y$~Smt;e#y=}c*Z&BRf3hB_Q zamw#{;^FAf&>R-E|Le_h(4Ev5@pq_WxMf2^Poz?wIn%FpTpvr|;#)me;TD6tTt35l zgmZuu3u@%8qUenIQKdnow6Ttn;qhxFvSK0Nf`Woone^+52td%yvc{GUH9jtZuysKg z7t$ejO01wKra0}&x1H0VSsCVLX2esH3>2ECi{a9dRN@C-c8!PS&5Y6rJ?Q#spvK!` zg4dPbgJ<#b6?k^@NLLV~(gqNUHS~BN`b9;p26UVc_f}ox49(q@M}otJ@b4`EJq~7v6|e$Fz(M{GpEpIi~l(`+Y*9&aoeMT)C2{`|2FC60?N@b5Fgl zV1b|MmOnb!NPe%G52%$%ZOM6a{>CgH{3di=C<{X?YBKw1@{=7r(Le7k+JX9B3X@83^W`VcivCyarazwnwHdCgmc@cVRq5Dt5e?W&hh83~?qF87Vuwu7E6Y#d&>gIOhwNBi$nT)yp96L2 zFGG7oPK;n2_ z1b_Z7afK2*-o2ksCYK_c!?u=g!V9<*qSXNchKc@|kBp;A*1{PrTj(>)Owj`t09!$6 zS!@9Dv9}`e<9Pw^6!ZUkS~Id|f?*GR9O06eo!Lopl67+;dIlY;gJVVI(yO=$nf8tl zFZ#$#fY?h}z>b}2cf!&-+5nIe5OKV1YJG_J?8zuIjtVS(`k#}c6Rs&Yw-JVaBu0dwh=B7%Ml8KC#r@P-9gNGI>o}w%nae2xOn(Rkp)Q8A-()X6+wU2)`l$UT8a5wpbSjbn2fcJ(`D*nG>AO5a&j%vmekR{1Cxr~RKnc%s3HQ z>!8pT)r<_n5+Z#*rbZEuT7AxH@=}ieK~PKf1(yJnii@9stWDPN*1lHqKz8RJHY1aI z#pkJL7)uX4Tv-`e<HIYjIq&SR!4?ti($m_AQBY;unVulS#nOn^&Ia_@ghdTdYK@c9!))F|r)E#K=brko$94pFfug(R!W$<|a6CSV9&N!1$5S$iVG@xKNE6FAXKTR8 zY>TaYT;U!^2_qi=l~6Oj+63A32^6*|i~-1Tw?{z~jMcB}ANgDQ9~`fMc`hG{MU8u&cyzRr{14vw9pU^Op@rn-~7nb`?8}+-u8WPp#0#B_h{7< zw~wiNqVPkLK9hvot{wx4uKPYZ&Z&(~1ipa>Wb$~v9nN#qI%jp9+hxV0t;6QD78>a}CA5zvccU@{^`6Rpk z)8ErOUA)BX&`u#sE)(SLHW+|aA#$JHRpchRyLY}o^3_e_Sh@mM={Gfmf#q8 z^>J5IzK7sVAqUHp*c5(9k%I!KD>v|-aCSK~fHZXW(o#felNXQ|H7K{{25p7W+S;eC zb{`n+Mf5K3MAnQW443<4__=wuMFPGrX2n}wc^k8=;jWUceR1Cx&Pa!%ci*;w%#LVo znx?d4po;Ji22e|nRr|-ewY&Mg{QSQ{AI2%4NL0x|$*G^Xf}-vZ1FqWBYwJ(`A2<(t zL#V|JmdMS?(m?Tva_S!3^4NWpO?=agqtuW0+97=W}0GQMSQh=I7o{tpDtH2?qr literal 0 HcmV?d00001 diff --git a/internal/app/files/system_avatar_seed.go b/internal/app/files/system_avatar_seed.go new file mode 100644 index 00000000..2b77f908 --- /dev/null +++ b/internal/app/files/system_avatar_seed.go @@ -0,0 +1,44 @@ +package files + +import ( + "context" + _ "embed" + "time" + + "telesrv/internal/domain" +) + +//go:embed seedassets/owpengram_system_avatar.png +var officialSystemAvatarPNG []byte + +// SeedOfficialSystemAvatar idempotently seeds the built-in official system +// account's (777000) profile photo from the bundled brand logo, writing it +// under the fixed domain.OfficialSystemUserPhotoID so the photo/blob layer +// and the pure domain.OfficialSystemUser() struct literal stay in sync +// across restarts. Returns true if it actually wrote a new photo. +func (s *Service) SeedOfficialSystemAvatar(ctx context.Context) (bool, error) { + photoID := domain.OfficialSystemUserPhotoID + if existing, found, err := s.media.GetPhoto(ctx, photoID); err != nil { + return false, err + } else if found { + domain.SetOfficialSystemUserAvatar(existing.DCID, domain.StrippedFromSizes(existing.Sizes)) + return false, nil + } + sizes, err := s.putPhotoStaticSizes(ctx, photoID, officialSystemAvatarPNG, photoSizeSpecsForAvatar(officialSystemAvatarPNG)) + if err != nil { + return false, err + } + photo := domain.Photo{ + ID: photoID, + AccessHash: domain.OfficialSystemUserPhotoAccessHash, + FileReference: randomFileReference(), + Date: int(time.Now().Unix()), + DCID: s.dc, + Sizes: sizes, + } + if err := s.media.PutPhoto(ctx, photo); err != nil { + return false, err + } + domain.SetOfficialSystemUserAvatar(photo.DCID, domain.StrippedFromSizes(photo.Sizes)) + return true, nil +} diff --git a/internal/domain/system.go b/internal/domain/system.go index b1f6a399..dfc65911 100644 --- a/internal/domain/system.go +++ b/internal/domain/system.go @@ -3,6 +3,11 @@ package domain const ( // OfficialSystemUserID 是 Telegram 兼容客户端识别的官方系统账号。 OfficialSystemUserID int64 = 777000 + // OfficialSystemUserPhotoID/AccessHash 是该账号头像 photo 的固定 id, + // 与 files.Service.SeedOfficialSystemAvatar 种子写入的行保持一致, + // 确保跨重启后 OfficialSystemUser() 引用的 photo id 稳定不变。 + OfficialSystemUserPhotoID int64 = 7770000001 + OfficialSystemUserPhotoAccessHash int64 = 5837219004471160321 // BotFatherUserID 是内置 BotFather 账号,与官方 @BotFather 同 ID。 BotFatherUserID int64 = 93372553 @@ -21,17 +26,38 @@ const ( ChatBotAccessHash int64 = 6332902371644871201 ) +// officialSystemUserPhotoDCID/Stripped 由 files.Service.SeedOfficialSystemAvatar +// 在启动时通过 SetOfficialSystemUserAvatar 写入一次;写入前 OfficialSystemUser() +// 不带头像(PhotoID==0),与其它未设置头像的账号行为一致。 +var ( + officialSystemUserPhotoDCID int + officialSystemUserPhotoStripped []byte +) + +// SetOfficialSystemUserAvatar 记录官方系统账号头像所在的 DC 与内联缩略图字节。 +// 只应在启动阶段、头像 seed 完成后调用一次。 +func SetOfficialSystemUserAvatar(dcID int, stripped []byte) { + officialSystemUserPhotoDCID = dcID + officialSystemUserPhotoStripped = stripped +} + // OfficialSystemUser 返回第一阶段内置的官方系统账号。 func OfficialSystemUser() User { - return User{ + u := User{ ID: OfficialSystemUserID, AccessHash: 6599886787491911851, Phone: "42777", - FirstName: "Telegram", - Username: "telegram", + FirstName: "OwpenGram", + Username: "owpengram", Verified: true, Support: true, } + if officialSystemUserPhotoDCID != 0 { + u.PhotoID = OfficialSystemUserPhotoID + u.PhotoDCID = officialSystemUserPhotoDCID + u.PhotoStripped = officialSystemUserPhotoStripped + } + return u } // BotFatherUser 返回内置 BotFather 账号。username 不以 bot 结尾属种子例外(与官方一致)。