added avatar for verification bot

This commit is contained in:
onysd 2026-08-06 04:39:28 +03:00
parent a9586aec87
commit 4f0fa895c1
4 changed files with 87 additions and 1 deletions

View file

@ -838,6 +838,11 @@ func run(logger *zap.Logger) error {
} else if seeded {
logger.Info("@ChatBot avatar seed import complete", zap.Int64("photo_id", domain.ChatBotUserPhotoID))
}
if seeded, err := filesService.SeedVerifyBotAvatar(ctx); err != nil {
return fmt.Errorf("seed verifybot avatar: %w", err)
} else if seeded {
logger.Info("@verifybot avatar seed import complete", zap.Int64("photo_id", domain.VerifyBotUserPhotoID))
}
if stats, err := filesService.WarmCaches(ctx); err != nil {
logger.Warn("media resource cache warmup failed", zap.Error(err))
} else if stats.StickerSets > 0 || stats.Documents > 0 || stats.Blobs > 0 {

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 KiB

View file

@ -0,0 +1,54 @@
package files
import (
"context"
_ "embed"
"fmt"
"time"
"telesrv/internal/domain"
)
//go:embed seedassets/verifybot_avatar.png
var verifyBotAvatarPNG []byte
// SeedVerifyBotAvatar idempotently seeds the built-in @verifybot account's
// profile photo from the bundled avatar, mirroring SeedChatBotAvatar: writes
// it under the fixed domain.VerifyBotUserPhotoID so the photo/blob layer and
// the pure domain.VerifyBotUser() struct literal stay in sync across
// restarts, and registers it as the account's *current* profile photo so
// users.getFullUser resolves it too. Returns true if it actually wrote a new
// photo.
func (s *Service) SeedVerifyBotAvatar(ctx context.Context) (bool, error) {
photoID := domain.VerifyBotUserPhotoID
wrote := false
if _, found, err := s.media.GetPhoto(ctx, photoID); err != nil {
return false, err
} else if !found {
sizes, err := s.putPhotoStaticSizes(ctx, photoID, verifyBotAvatarPNG, photoSizeSpecsForAvatar(verifyBotAvatarPNG))
if err != nil {
return false, err
}
photo := domain.Photo{
ID: photoID,
AccessHash: domain.VerifyBotUserPhotoAccessHash,
FileReference: randomFileReference(),
Date: int(time.Now().Unix()),
DCID: s.dc,
Sizes: sizes,
}
if err := s.media.PutPhoto(ctx, photo); err != nil {
return false, err
}
wrote = true
}
photo, ok, err := s.SetCurrentProfilePhoto(ctx, domain.PeerTypeUser, domain.VerifyBotUserID, photoID, int(time.Now().Unix()))
if err != nil {
return false, err
}
if !ok {
return false, fmt.Errorf("verifybot avatar photo %d not found after seeding", photoID)
}
domain.SetVerifyBotAvatar(photo.DCID, domain.StrippedFromSizes(photo.Sizes))
return wrote, nil
}

View file

@ -47,6 +47,10 @@ const (
// VerifyBotAccessHash is fixed and double-written with the seed row in
// migration 0153; the two must never drift.
VerifyBotAccessHash int64 = 7802113947355620887
// VerifyBotUserPhotoID/AccessHash are the fixed id of @verifybot's avatar
// photo, matching the row files.Service.SeedVerifyBotAvatar seeds.
VerifyBotUserPhotoID int64 = 12500000110001
VerifyBotUserPhotoAccessHash int64 = 975869468725402752
// VerifierBotUserID is the built-in @marksbot: the first THIRD-PARTY
// verifier of a deployment (core.telegram.org/api/bots/verification). It
@ -130,6 +134,23 @@ func SetChatBotAvatar(dcID int, stripped []byte) {
chatBotPhotoStripped = stripped
}
// verifyBotPhotoDCID/Stripped are written once at startup by
// files.Service.SeedVerifyBotAvatar via SetVerifyBotAvatar; before that,
// VerifyBotUser() carries no photo (PhotoID==0), same as every other
// not-yet-seeded built-in account.
var (
verifyBotPhotoDCID int
verifyBotPhotoStripped []byte
)
// SetVerifyBotAvatar records the DC and inline thumbnail bytes for
// @verifybot's avatar. Should only be called once, at startup, after the
// avatar seed completes.
func SetVerifyBotAvatar(dcID int, stripped []byte) {
verifyBotPhotoDCID = dcID
verifyBotPhotoStripped = stripped
}
// OfficialSystemUser 返回第一阶段内置的官方系统账号。
func OfficialSystemUser() User {
u := User{
@ -209,7 +230,7 @@ func ChatBotUser() User {
// VerifyBotUser returns the built-in @verifybot account. It is verified itself,
// so the applicant sees the same badge on the account that grants it.
func VerifyBotUser() User {
return User{
u := User{
ID: VerifyBotUserID,
AccessHash: VerifyBotAccessHash,
FirstName: "Verify Bot",
@ -218,6 +239,12 @@ func VerifyBotUser() User {
Bot: true,
BotInfoVersion: 1,
}
if verifyBotPhotoDCID != 0 {
u.PhotoID = VerifyBotUserPhotoID
u.PhotoDCID = verifyBotPhotoDCID
u.PhotoStripped = verifyBotPhotoStripped
}
return u
}
// VerifierBotUser returns the built-in @marksbot account.