From d99ed95cd56c2e79401ce53e20a0ba6da7dacc34 Mon Sep 17 00:00:00 2001 From: "dmitrii.pichenikin" Date: Tue, 10 Mar 2026 15:56:02 +0300 Subject: [PATCH] added fallback display for the removed achievement emoji --- server/api.go | 13 +++++++++++-- server/utils.go | 21 +++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/server/api.go b/server/api.go index 66b1793..ed8de30 100644 --- a/server/api.go +++ b/server/api.go @@ -1536,6 +1536,10 @@ func (p *Plugin) getUserBadges(w http.ResponseWriter, r *http.Request, actingUse p.mm.Log.Debug("Error getting the badges for user", "error", err, "user", userID) } + for _, ub := range badges { + p.sanitizeBadgeEmoji(&ub.Badge) + } + b, _ := json.Marshal(badges) _, _ = w.Write(b) } @@ -1564,6 +1568,7 @@ func (p *Plugin) getBadgeDetails(w http.ResponseWriter, r *http.Request, actingU resp := BadgeDetailsResponse{BadgeDetails: badge} if badge != nil { + p.sanitizeBadgeEmoji(&badge.Badge) actingUser, userErr := p.mm.User.Get(actingUserID) if userErr == nil { bt, typeErr := p.store.GetType(badge.Type) @@ -1578,12 +1583,16 @@ func (p *Plugin) getBadgeDetails(w http.ResponseWriter, r *http.Request, actingU } func (p *Plugin) getAllBadges(w http.ResponseWriter, r *http.Request, actingUserID string) { - badge, err := p.store.GetAllBadges() + badges, err := p.store.GetAllBadges() if err != nil { p.mm.Log.Debug("Cannot get all badges", "error", err) } - b, _ := json.Marshal(badge) + for _, ab := range badges { + p.sanitizeBadgeEmoji(&ab.Badge) + } + + b, _ := json.Marshal(badges) _, _ = w.Write(b) } diff --git a/server/utils.go b/server/utils.go index 56b284d..6f5dd4f 100644 --- a/server/utils.go +++ b/server/utils.go @@ -140,6 +140,27 @@ func dumpObject(o interface{}) { fmt.Println(string(b)) } +const fallbackEmoji = "question" + +// sanitizeBadgeEmoji checks if a badge's custom emoji still exists. +// If the emoji was deleted, it replaces it with a fallback and persists the change. +func (p *Plugin) sanitizeBadgeEmoji(badge *badgesmodel.Badge) { + if badge.ImageType != badgesmodel.ImageTypeEmoji { + return + } + if _, ok := model.SystemEmojis[badge.Image]; ok { + return + } + _, appErr := p.API.GetEmojiByName(badge.Image) + if appErr == nil { + return + } + badge.Image = fallbackEmoji + if err := p.store.UpdateBadge(badge); err != nil { + p.mm.Log.Warn("Failed to replace deleted emoji on badge", "badge_id", badge.ID, "error", err.Error()) + } +} + func (p *Plugin) notifyGrant(badgeID badgesmodel.BadgeID, granter string, granted *model.User, inChannel bool, channelID string, reason string) { b, errBadge := p.store.GetBadgeDetails(badgeID) granterUser, errUser := p.mm.User.Get(granter)