From 1259c20e5f11706cc3a03f439488b84f5f38bc17 Mon Sep 17 00:00:00 2001 From: MHSanaei Date: Sat, 20 Jun 2026 21:39:55 +0200 Subject: [PATCH] fix(tgbot): dedupe exhausted-client report by email (#5453) A client linked to N inbounds has one ClientStats row per inbound, all sharing the same email. getExhausted appended every row, so the admin expiration/traffic report listed the same user once per inbound (N info blocks and N buttons), which Telegram split into multiple messages. Track seen emails and report each client once. --- internal/web/service/tgbot/tgbot_report.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internal/web/service/tgbot/tgbot_report.go b/internal/web/service/tgbot/tgbot_report.go index d0fecd622..819209fe2 100644 --- a/internal/web/service/tgbot/tgbot_report.go +++ b/internal/web/service/tgbot/tgbot_report.go @@ -206,6 +206,7 @@ func (t *Tgbot) getExhausted(chatId int64) { logger.Warning("Unable to load Inbounds", err) } + seenClients := make(map[string]bool) for _, inbound := range inbounds { if inbound.Enable { if (inbound.ExpiryTime > 0 && (inbound.ExpiryTime-now < exDiff)) || @@ -214,6 +215,10 @@ func (t *Tgbot) getExhausted(chatId int64) { } if len(inbound.ClientStats) > 0 { for _, client := range inbound.ClientStats { + if seenClients[client.Email] { + continue + } + seenClients[client.Email] = true if client.Enable { if (client.ExpiryTime > 0 && (client.ExpiryTime-now < exDiff)) || (client.Total > 0 && (client.Total-(client.Up+client.Down) < trDiff)) {