Quellcode durchsuchen

Added 3 new buttons to telegram bot (#2965)

* Add a new button to but : Reset All Clients

* handel translation for `Reset All Clients` button

* refactoring

* add a new button to telegram bot >> `Sorted Traffic Usage Report`

* - refactoring

* add ip limit conifg on new client adding time
nistootsin vor 1 Tag
Ursprung
Commit
d39ccf4b8f

+ 35 - 0
web/service/inbound.go

@@ -3,6 +3,7 @@ package service
 import (
 	"encoding/json"
 	"fmt"
+	"sort"
 	"strconv"
 	"strings"
 	"time"
@@ -2025,3 +2026,37 @@ func (s *InboundService) MigrateDB() {
 func (s *InboundService) GetOnlineClients() []string {
 	return p.GetOnlineClients()
 }
+
+func (s *InboundService) FilterAndSortClientEmails(emails []string) ([]string, []string, error) {
+	db := database.GetDB()
+
+	// Step 1: Get ClientTraffic records for emails in the input list
+	var clients []xray.ClientTraffic
+	err := db.Where("email IN ?", emails).Find(&clients).Error
+	if err != nil && err != gorm.ErrRecordNotFound {
+		return nil, nil, err
+	}
+
+	// Step 2: Sort clients by (Up + Down) descending
+	sort.Slice(clients, func(i, j int) bool {
+		return (clients[i].Up + clients[i].Down) > (clients[j].Up + clients[j].Down)
+	})
+
+	// Step 3: Extract sorted valid emails and track found ones
+	validEmails := make([]string, 0, len(clients))
+	found := make(map[string]bool)
+	for _, client := range clients {
+		validEmails = append(validEmails, client.Email)
+		found[client.Email] = true
+	}
+
+	// Step 4: Identify emails that were not found in the database
+	extraEmails := make([]string, 0)
+	for _, email := range emails {
+		if !found[email] {
+			extraEmails = append(extraEmails, email)
+		}
+	}
+
+	return validEmails, extraEmails, nil
+}

+ 198 - 3
web/service/tgbot.go

@@ -1069,6 +1069,83 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool
 				}
 				t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
 				t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
+			case "add_client_ip_limit_c":
+				if len(dataArray) == 2 {
+					count, _ := strconv.Atoi(dataArray[1])
+					client_LimitIP = count
+				}
+
+				messageId := callbackQuery.Message.GetMessageID()
+				inbound, err := t.inboundService.GetInbound(receiver_inbound_ID)
+				if err != nil {
+					t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
+					return
+				}
+				message_text, err := t.BuildInboundClientDataMessage(inbound.Remark, inbound.Protocol)
+
+				t.addClient(chatId, message_text, messageId)
+				t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))
+			case "add_client_ip_limit_in":
+				if len(dataArray) >= 2 {
+					oldInputNumber, err := strconv.Atoi(dataArray[1])
+					inputNumber := oldInputNumber
+					if err == nil {
+						if len(dataArray) == 3 {
+							num, err := strconv.Atoi(dataArray[2])
+							if err == nil {
+								if num == -2 {
+									inputNumber = 0
+								} else if num == -1 {
+									if inputNumber > 0 {
+										inputNumber = (inputNumber / 10)
+									}
+								} else {
+									inputNumber = (inputNumber * 10) + num
+								}
+							}
+							if inputNumber == oldInputNumber {
+								t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))
+								return
+							}
+							if inputNumber >= 999999 {
+								t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
+								return
+							}
+						}
+						inlineKeyboard := tu.InlineKeyboard(
+							tu.InlineKeyboardRow(
+								tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancel")).WithCallbackData(t.encodeQuery("add_client_default_ip_limit")),
+							),
+							tu.InlineKeyboardRow(
+								tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmNumber", "Num=="+strconv.Itoa(inputNumber))).WithCallbackData(t.encodeQuery("add_client_ip_limit_c "+strconv.Itoa(inputNumber))),
+							),
+							tu.InlineKeyboardRow(
+								tu.InlineKeyboardButton("1").WithCallbackData(t.encodeQuery("add_client_ip_limit_in "+strconv.Itoa(inputNumber)+" 1")),
+								tu.InlineKeyboardButton("2").WithCallbackData(t.encodeQuery("add_client_ip_limit_in "+strconv.Itoa(inputNumber)+" 2")),
+								tu.InlineKeyboardButton("3").WithCallbackData(t.encodeQuery("add_client_ip_limit_in "+strconv.Itoa(inputNumber)+" 3")),
+							),
+							tu.InlineKeyboardRow(
+								tu.InlineKeyboardButton("4").WithCallbackData(t.encodeQuery("add_client_ip_limit_in "+strconv.Itoa(inputNumber)+" 4")),
+								tu.InlineKeyboardButton("5").WithCallbackData(t.encodeQuery("add_client_ip_limit_in "+strconv.Itoa(inputNumber)+" 5")),
+								tu.InlineKeyboardButton("6").WithCallbackData(t.encodeQuery("add_client_ip_limit_in "+strconv.Itoa(inputNumber)+" 6")),
+							),
+							tu.InlineKeyboardRow(
+								tu.InlineKeyboardButton("7").WithCallbackData(t.encodeQuery("add_client_ip_limit_in "+strconv.Itoa(inputNumber)+" 7")),
+								tu.InlineKeyboardButton("8").WithCallbackData(t.encodeQuery("add_client_ip_limit_in "+strconv.Itoa(inputNumber)+" 8")),
+								tu.InlineKeyboardButton("9").WithCallbackData(t.encodeQuery("add_client_ip_limit_in "+strconv.Itoa(inputNumber)+" 9")),
+							),
+							tu.InlineKeyboardRow(
+								tu.InlineKeyboardButton("🔄").WithCallbackData(t.encodeQuery("add_client_ip_limit_in "+strconv.Itoa(inputNumber)+" -2")),
+								tu.InlineKeyboardButton("0").WithCallbackData(t.encodeQuery("add_client_ip_limit_in "+strconv.Itoa(inputNumber)+" 0")),
+								tu.InlineKeyboardButton("⬅️").WithCallbackData(t.encodeQuery("add_client_ip_limit_in "+strconv.Itoa(inputNumber)+" -1")),
+							),
+						)
+						t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
+						return
+					}
+				}
+				t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
+				t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
 			case "clear_ips":
 				inlineKeyboard := tu.InlineKeyboard(
 					tu.InlineKeyboardRow(
@@ -1382,6 +1459,35 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool
 			),
 		)
 		t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
+	case "add_client_ch_default_ip_limit":
+		inlineKeyboard := tu.InlineKeyboard(
+			tu.InlineKeyboardRow(
+				tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancel")).WithCallbackData(t.encodeQuery("add_client_default_ip_limit")),
+			),
+			tu.InlineKeyboardRow(
+				tu.InlineKeyboardButton(t.I18nBot("tgbot.unlimited")).WithCallbackData(t.encodeQuery("add_client_ip_limit_c 0")),
+				tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.custom")).WithCallbackData(t.encodeQuery("add_client_ip_limit_in 0")),
+			),
+			tu.InlineKeyboardRow(
+				tu.InlineKeyboardButton("1").WithCallbackData(t.encodeQuery("add_client_ip_limit_c 1")),
+				tu.InlineKeyboardButton("2").WithCallbackData(t.encodeQuery("add_client_ip_limit_c 2")),
+			),
+			tu.InlineKeyboardRow(
+				tu.InlineKeyboardButton("3").WithCallbackData(t.encodeQuery("add_client_ip_limit_c 3")),
+				tu.InlineKeyboardButton("4").WithCallbackData(t.encodeQuery("add_client_ip_limit_c 4")),
+			),
+			tu.InlineKeyboardRow(
+				tu.InlineKeyboardButton("5").WithCallbackData(t.encodeQuery("add_client_ip_limit_c 5")),
+				tu.InlineKeyboardButton("6").WithCallbackData(t.encodeQuery("add_client_ip_limit_c 6")),
+				tu.InlineKeyboardButton("7").WithCallbackData(t.encodeQuery("add_client_ip_limit_c 7")),
+			),
+			tu.InlineKeyboardRow(
+				tu.InlineKeyboardButton("8").WithCallbackData(t.encodeQuery("add_client_ip_limit_c 8")),
+				tu.InlineKeyboardButton("9").WithCallbackData(t.encodeQuery("add_client_ip_limit_c 9")),
+				tu.InlineKeyboardButton("10").WithCallbackData(t.encodeQuery("add_client_ip_limit_c 10")),
+			),
+		)
+		t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
 	case "add_client_default_info":
 		t.deleteMessageTgBot(chatId, callbackQuery.Message.GetMessageID())
 		t.SendMsgToTgbotDeleteAfter(chatId, t.I18nBot("tgbot.messages.using_default_value"), 3, tu.ReplyKeyboardRemove())
@@ -1403,6 +1509,16 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool
 		message_text, err := t.BuildInboundClientDataMessage(inbound.Remark, inbound.Protocol)
 		t.addClient(chatId, message_text, messageId)
 		t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.canceled", "Email=="+client_Email))
+	case "add_client_default_ip_limit":
+		messageId := callbackQuery.Message.GetMessageID()
+		inbound, err := t.inboundService.GetInbound(receiver_inbound_ID)
+		if err != nil {
+			t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
+			return
+		}
+		message_text, err := t.BuildInboundClientDataMessage(inbound.Remark, inbound.Protocol)
+		t.addClient(chatId, message_text, messageId)
+		t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.canceled", "Email=="+client_Email))
 	case "add_client_submit_disable":
 		client_Enable = false
 		_, err := t.SubmitAddClient()
@@ -1423,6 +1539,71 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool
 			t.deleteMessageTgBot(chatId, callbackQuery.Message.GetMessageID())
 			t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.successfulOperation"), tu.ReplyKeyboardRemove())
 		}
+	case "reset_all_traffics_cancel":
+		t.deleteMessageTgBot(chatId, callbackQuery.Message.GetMessageID())
+		t.SendMsgToTgbotDeleteAfter(chatId, t.I18nBot("tgbot.messages.cancel"), 1, tu.ReplyKeyboardRemove())
+	case "reset_all_traffics":
+		inlineKeyboard := tu.InlineKeyboard(
+			tu.InlineKeyboardRow(
+				tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancelReset")).WithCallbackData(t.encodeQuery("reset_all_traffics_cancel")),
+			),
+			tu.InlineKeyboardRow(
+				tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmResetTraffic")).WithCallbackData(t.encodeQuery("reset_all_traffics_c")),
+			),
+		)
+		t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.messages.AreYouSure"), inlineKeyboard)
+	case "reset_all_traffics_c":
+		t.deleteMessageTgBot(chatId, callbackQuery.Message.GetMessageID())
+		emails, err := t.inboundService.getAllEmails()
+		if err != nil {
+			t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.errorOperation"), tu.ReplyKeyboardRemove())
+			return
+		}
+
+		for _, email := range emails {
+			err := t.inboundService.ResetClientTrafficByEmail(email)
+			if err == nil {
+				msg := t.I18nBot("tgbot.messages.SuccessResetTraffic", "ClientEmail=="+email)
+				t.SendMsgToTgbot(chatId, msg, tu.ReplyKeyboardRemove())
+			} else {
+				msg := t.I18nBot("tgbot.messages.FailedResetTraffic", "ClientEmail=="+email, "ErrorMessage=="+err.Error())
+				t.SendMsgToTgbot(chatId, msg, tu.ReplyKeyboardRemove())
+			}
+		}
+
+		t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.messages.FinishProcess"), tu.ReplyKeyboardRemove())
+	case "get_sorted_traffic_usage_report":
+		t.deleteMessageTgBot(chatId, callbackQuery.Message.GetMessageID())
+		emails, err := t.inboundService.getAllEmails()
+
+		if err != nil {
+			t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.errorOperation"), tu.ReplyKeyboardRemove())
+			return
+		}
+		valid_emails, extra_emails, err := t.inboundService.FilterAndSortClientEmails(emails)
+
+		for _, valid_emails := range valid_emails {
+			traffic, err := t.inboundService.GetClientTrafficByEmail(valid_emails)
+			if err != nil {
+				logger.Warning(err)
+				msg := t.I18nBot("tgbot.wentWrong")
+				t.SendMsgToTgbot(chatId, msg)
+				continue
+			}
+			if traffic == nil {
+				msg := t.I18nBot("tgbot.noResult")
+				t.SendMsgToTgbot(chatId, msg)
+				continue
+			}
+
+			output := t.clientInfoMsg(traffic, false, false, false, false, true, false)
+			t.SendMsgToTgbot(chatId, output, tu.ReplyKeyboardRemove())
+		}
+		for _, extra_emails := range extra_emails {
+			msg := fmt.Sprintf("📧 %s\n%s", extra_emails, t.I18nBot("tgbot.noResult"))
+			t.SendMsgToTgbot(chatId, msg, tu.ReplyKeyboardRemove())
+
+		}
 	}
 }
 
@@ -1451,15 +1632,22 @@ func (t *Tgbot) BuildInboundClientDataMessage(inbound_remark string, protocol mo
 		traffic_value = common.FormatTraffic(client_TotalGB)
 	}
 
+	ip_limit := ""
+	if client_LimitIP == 0 {
+		ip_limit = "♾️ Unlimited(Reset)"
+	} else {
+		ip_limit = fmt.Sprint(client_LimitIP)
+	}
+
 	switch protocol {
 	case model.VMESS, model.VLESS:
-		message = t.I18nBot("tgbot.messages.inbound_client_data_id", "InboundRemark=="+inbound_remark, "ClientId=="+client_Id, "ClientEmail=="+client_Email, "ClientTraffic=="+traffic_value, "ClientExp=="+expiryTime, "ClientComment=="+client_Comment)
+		message = t.I18nBot("tgbot.messages.inbound_client_data_id", "InboundRemark=="+inbound_remark, "ClientId=="+client_Id, "ClientEmail=="+client_Email, "ClientTraffic=="+traffic_value, "ClientExp=="+expiryTime, "IpLimit=="+ip_limit, "ClientComment=="+client_Comment)
 
 	case model.Trojan:
-		message = t.I18nBot("tgbot.messages.inbound_client_data_pass", "InboundRemark=="+inbound_remark, "ClientPass=="+client_TrPassword, "ClientEmail=="+client_Email, "ClientTraffic=="+traffic_value, "ClientExp=="+expiryTime, "ClientComment=="+client_Comment)
+		message = t.I18nBot("tgbot.messages.inbound_client_data_pass", "InboundRemark=="+inbound_remark, "ClientPass=="+client_TrPassword, "ClientEmail=="+client_Email, "ClientTraffic=="+traffic_value, "ClientExp=="+expiryTime, "IpLimit=="+ip_limit, "ClientComment=="+client_Comment)
 
 	case model.Shadowsocks:
-		message = t.I18nBot("tgbot.messages.inbound_client_data_pass", "InboundRemark=="+inbound_remark, "ClientPass=="+client_ShPassword, "ClientEmail=="+client_Email, "ClientTraffic=="+traffic_value, "ClientExp=="+expiryTime, "ClientComment=="+client_Comment)
+		message = t.I18nBot("tgbot.messages.inbound_client_data_pass", "InboundRemark=="+inbound_remark, "ClientPass=="+client_ShPassword, "ClientEmail=="+client_Email, "ClientTraffic=="+traffic_value, "ClientExp=="+expiryTime, "IpLimit=="+ip_limit, "ClientComment=="+client_Comment)
 
 	default:
 		return "", errors.New("unknown protocol")
@@ -1575,8 +1763,12 @@ func checkAdmin(tgId int64) bool {
 
 func (t *Tgbot) SendAnswer(chatId int64, msg string, isAdmin bool) {
 	numericKeyboard := tu.InlineKeyboard(
+		tu.InlineKeyboardRow(
+			tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.SortedTrafficUsageReport")).WithCallbackData(t.encodeQuery("get_sorted_traffic_usage_report")),
+		),
 		tu.InlineKeyboardRow(
 			tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.serverUsage")).WithCallbackData(t.encodeQuery("get_usage")),
+			tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.ResetAllTraffics")).WithCallbackData(t.encodeQuery("reset_all_traffics")),
 		),
 		tu.InlineKeyboardRow(
 			tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.dbBackup")).WithCallbackData(t.encodeQuery("get_backup")),
@@ -2223,6 +2415,7 @@ func (t *Tgbot) addClient(chatId int64, msg string, messageID ...int) {
 			),
 			tu.InlineKeyboardRow(
 				tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.change_comment")).WithCallbackData("add_client_ch_default_comment"),
+				tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.ipLimit")).WithCallbackData("add_client_ch_default_ip_limit"),
 			),
 			tu.InlineKeyboardRow(
 				tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.submitDisable")).WithCallbackData("add_client_submit_disable"),
@@ -2249,6 +2442,7 @@ func (t *Tgbot) addClient(chatId int64, msg string, messageID ...int) {
 			),
 			tu.InlineKeyboardRow(
 				tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.change_comment")).WithCallbackData("add_client_ch_default_comment"),
+				tu.InlineKeyboardButton("ip limit").WithCallbackData("add_client_ch_default_ip_limit"),
 			),
 			tu.InlineKeyboardRow(
 				tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.submitDisable")).WithCallbackData("add_client_submit_disable"),
@@ -2275,6 +2469,7 @@ func (t *Tgbot) addClient(chatId int64, msg string, messageID ...int) {
 			),
 			tu.InlineKeyboardRow(
 				tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.change_comment")).WithCallbackData("add_client_ch_default_comment"),
+				tu.InlineKeyboardButton("ip limit").WithCallbackData("add_client_ch_default_ip_limit"),
 			),
 			tu.InlineKeyboardRow(
 				tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.submitDisable")).WithCallbackData("add_client_submit_disable"),

+ 10 - 2
web/translation/translate.ar_EG.toml

@@ -605,12 +605,17 @@
 "pass_prompt" = "🔑 الباسورد الافتراضي: {{ .ClientPassword }}\n\nادخل الباسورد بتاعك."
 "email_prompt" = "📧 الإيميل الافتراضي: {{ .ClientEmail }}\n\nادخل الإيميل بتاعك."
 "comment_prompt" = "💬 التعليق الافتراضي: {{ .ClientComment }}\n\nادخل تعليقك."
-"inbound_client_data_id" = "🔄 للإدخال: {{ .InboundRemark }}\n\n🔑 الـ ID: {{ .ClientId }}\n📧 الإيميل: {{ .ClientEmail }}\n📊 الترافيك: {{ .ClientTraffic }}\n📅 تاريخ الانتهاء: {{ .ClientExp }}\n💬 التعليق: {{ .ClientComment }}\n\nممكن تضيف العميل للإدخال دلوقتي!"
-"inbound_client_data_pass" = "🔄 للإدخال: {{ .InboundRemark }}\n\n🔑 الباسورد: {{ .ClientPass }}\n📧 الإيميل: {{ .ClientEmail }}\n📊 الترافيك: {{ .ClientTraffic }}\n📅 تاريخ الانتهاء: {{ .ClientExp }}\n💬 التعليق: {{ .ClientComment }}\n\nممكن تضيف العميل للإدخال دلوقتي!"
+"inbound_client_data_id" = "🔄 الدخول: {{ .InboundRemark }}\n\n🔑 المعرف: {{ .ClientId }}\n📧 البريد الإلكتروني: {{ .ClientEmail }}\n📊 الترافيك: {{ .ClientTraffic }}\n📅 تاريخ الانتهاء: {{ .ClientExp }}\n🌐 حدّ IP: {{ .IpLimit }}\n💬 تعليق: {{ .ClientComment }}\n\nدلوقتي تقدر تضيف العميل على الدخول!"
+"inbound_client_data_pass" = "🔄 الدخول: {{ .InboundRemark }}\n\n🔑 كلمة المرور: {{ .ClientPass }}\n📧 البريد الإلكتروني: {{ .ClientEmail }}\n📊 الترافيك: {{ .ClientTraffic }}\n📅 تاريخ الانتهاء: {{ .ClientExp }}\n🌐 حدّ IP: {{ .IpLimit }}\n💬 تعليق: {{ .ClientComment }}\n\nدلوقتي تقدر تضيف العميل على الدخول!"
 "cancel" = "❌ العملية اتلغت! \n\nممكن تبدأ من /start في أي وقت. 🔄"
 "error_add_client" = "⚠️ حصل خطأ:\n\n {{ .error }}"
 "using_default_value" = "تمام، هشيل على القيمة الافتراضية. 😊"
 "incorrect_input" = "المدخلات مش صحيحة.\nالكلمات لازم تكون متصلة من غير فراغات.\nمثال صحيح: aaaaaa\nمثال غلط: aaa aaa 🚫"
+"AreYouSure" = "إنت متأكد؟ 🤔"
+"SuccessResetTraffic" = "📧 البريد الإلكتروني: {{ .ClientEmail }}\n🏁 النتيجة: ✅ تم بنجاح"
+"FailedResetTraffic" = "📧 البريد الإلكتروني: {{ .ClientEmail }}\n🏁 النتيجة: ❌ فشل \n\n🛠️ الخطأ: [ {{ .ErrorMessage }} ]"
+"FinishProcess" = "🔚 عملية إعادة ضبط الترافيك خلصت لكل العملاء."
+
 
 [tgbot.buttons]
 "closeKeyboard" = "❌ اقفل الكيبورد"
@@ -654,6 +659,9 @@
 "change_password" = "⚙️🔑 كلمة السر"
 "change_email" = "⚙️📧 البريد الإلكتروني"
 "change_comment" = "⚙️💬 تعليق"
+"ResetAllTraffics" = "إعادة ضبط جميع الترافيك"
+"SortedTrafficUsageReport" = "تقرير استخدام الترافيك المرتب"
+
 
 [tgbot.answers]
 "successfulOperation" = "✅ العملية نجحت!"

+ 9 - 2
web/translation/translate.en_US.toml

@@ -605,12 +605,17 @@
 "pass_prompt" = "🔑 Default Password: {{ .ClientPassword }}\n\nEnter your password."
 "email_prompt" = "📧 Default Email: {{ .ClientEmail }}\n\nEnter your email."
 "comment_prompt" = "💬 Default Comment: {{ .ClientComment }}\n\nEnter your Comment."
-"inbound_client_data_id" = "🔄 Inbound: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 Email: {{ .ClientEmail }}\n📊 Traffic: {{ .ClientTraffic }}\n📅 Expire Date: {{ .ClientExp }}\n💬 Comment: {{ .ClientComment }}\n\nYou can add the client to inbound now!"
-"inbound_client_data_pass" = "🔄 Inbound: {{ .InboundRemark }}\n\n🔑 Password: {{ .ClientPass }}\n📧 Email: {{ .ClientEmail }}\n📊 Traffic: {{ .ClientTraffic }}\n📅 Expire Date: {{ .ClientExp }}\n💬 Comment: {{ .ClientComment }}\n\nYou can add the client to inbound now!"
+"inbound_client_data_id" = "🔄 Inbound: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 Email: {{ .ClientEmail }}\n📊 Traffic: {{ .ClientTraffic }}\n📅 Expire Date: {{ .ClientExp }}\n🌐 IP Limit: {{ .IpLimit }}\n💬 Comment: {{ .ClientComment }}\n\nYou can add the client to inbound now!"
+"inbound_client_data_pass" = "🔄 Inbound: {{ .InboundRemark }}\n\n🔑 Password: {{ .ClientPass }}\n📧 Email: {{ .ClientEmail }}\n📊 Traffic: {{ .ClientTraffic }}\n📅 Expire Date: {{ .ClientExp }}\n🌐 IP Limit: {{ .IpLimit }}\n💬 Comment: {{ .ClientComment }}\n\nYou can add the client to inbound now!"
 "cancel" = "❌ Process Canceled! \n\nYou can /start again anytime. 🔄"
 "error_add_client"  = "⚠️ Error:\n\n {{ .error }}"
 "using_default_value"  = "Okay, I'll stick with the default value. 😊"
 "incorrect_input" ="Your input is not valid.\nThe phrases should be continuous without spaces.\nCorrect example: aaaaaa\nIncorrect example: aaa aaa 🚫"
+"AreYouSure" = "Are you sure? 🤔"
+"SuccessResetTraffic" = "📧 Email: {{ .ClientEmail }}\n🏁 Result: ✅ Success"
+"FailedResetTraffic" = "📧 Email: {{ .ClientEmail }}\n🏁 Result: ❌ Failed \n\n🛠️ Error: [ {{ .ErrorMessage }} ]"
+"FinishProcess" = "🔚 Traffic reset process finished for all clients."
+
 
 [tgbot.buttons]
 "closeKeyboard" = "❌ Close Keyboard"
@@ -654,6 +659,8 @@
 "change_password" = "⚙️🔑 Password"
 "change_email" = "⚙️📧 Email"
 "change_comment" = "⚙️💬 Comment"
+"ResetAllTraffics" = "Reset All Traffics"
+"SortedTrafficUsageReport" = "Sorted Traffic Usage Report"
 
 [tgbot.answers]
 "successfulOperation" = "✅ Operation successful!"

+ 8 - 3
web/translation/translate.es_ES.toml

@@ -607,12 +607,16 @@
 "pass_prompt" = "🔑 Contraseña predeterminada: {{ .ClientPassword }}\n\nIntroduce tu contraseña."
 "email_prompt" = "📧 Correo electrónico predeterminado: {{ .ClientEmail }}\n\nIntroduce tu correo electrónico."
 "comment_prompt" = "💬 Comentario predeterminado: {{ .ClientComment }}\n\nIntroduce tu comentario."
-"inbound_client_data_id" = "🔄 Entrada: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 Email: {{ .ClientEmail }}\n📊 Tráfico: {{ .ClientTraffic }}\n📅 Fecha de vencimiento: {{ .ClientExp }}\n💬 Comentario: {{ .ClientComment }}\n\n¡Ahora puedes agregar al cliente a la entrada!"
-"inbound_client_data_pass" = "🔄 Entrada: {{ .InboundRemark }}\n\n🔑 Contraseña: {{ .ClientPass }}\n📧 Email: {{ .ClientEmail }}\n📊 Tráfico: {{ .ClientTraffic }}\n📅 Fecha de vencimiento: {{ .ClientExp }}\n💬 Comentario: {{ .ClientComment }}\n\n¡Ahora puedes agregar al cliente a la entrada!"
+"inbound_client_data_id" = "🔄 Entrada: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 Correo: {{ .ClientEmail }}\n📊 Tráfico: {{ .ClientTraffic }}\n📅 Fecha de expiración: {{ .ClientExp }}\n🌐 Límite de IP: {{ .IpLimit }}\n💬 Comentario: {{ .ClientComment }}\n\n¡Ahora puedes agregar al cliente a la entrada!"
+"inbound_client_data_pass" = "🔄 Entrada: {{ .InboundRemark }}\n\n🔑 Contraseña: {{ .ClientPass }}\n📧 Correo: {{ .ClientEmail }}\n📊 Tráfico: {{ .ClientTraffic }}\n📅 Fecha de expiración: {{ .ClientExp }}\n🌐 Límite de IP: {{ .IpLimit }}\n💬 Comentario: {{ .ClientComment }}\n\n¡Ahora puedes agregar al cliente a la entrada!"
 "cancel" = "❌ ¡Proceso cancelado! \n\nPuedes /start de nuevo en cualquier momento. 🔄"
 "error_add_client"  = "⚠️ Error:\n\n {{ .error }}"
 "using_default_value"  = "Está bien, me quedaré con el valor predeterminado. 😊"
 "incorrect_input" ="Tu entrada no es válida.\nLas frases deben ser continuas sin espacios.\nEjemplo correcto: aaaaaa\nEjemplo incorrecto: aaa aaa 🚫"
+"AreYouSure" = "¿Estás seguro? 🤔"
+"SuccessResetTraffic" = "📧 Correo: {{ .ClientEmail }}\n🏁 Resultado: ✅ Éxito"
+"FailedResetTraffic" = "📧 Correo: {{ .ClientEmail }}\n🏁 Resultado: ❌ Fallido \n\n🛠️ Error: [ {{ .ErrorMessage }} ]"
+"FinishProcess" = "🔚 Proceso de reinicio de tráfico finalizado para todos los clientes."
 
 
 [tgbot.buttons]
@@ -657,7 +661,8 @@
 "change_password" = "⚙️🔑 Contraseña"
 "change_email" = "⚙️📧 Correo electrónico"
 "change_comment" = "⚙️💬 Comentario"
-
+"ResetAllTraffics" = "Reiniciar todo el tráfico"
+"SortedTrafficUsageReport" = "Informe de uso de tráfico ordenado"
 
 
 [tgbot.answers]

+ 9 - 2
web/translation/translate.fa_IR.toml

@@ -607,12 +607,16 @@
 "pass_prompt" = "🔑 رمز عبور پیش‌فرض: {{ .ClientPassword }}\n\nرمز عبور خود را وارد کنید."
 "email_prompt" = "📧 ایمیل پیش‌فرض: {{ .ClientEmail }}\n\nایمیل خود را وارد کنید."
 "comment_prompt" = "💬 نظر پیش‌فرض: {{ .ClientComment }}\n\nنظر خود را وارد کنید."
-"inbound_client_data_id" = "🔄 ورودی: {{ .InboundRemark }}\n\n🔑 شناسه: {{ .ClientId }}\n📧 ایمیل: {{ .ClientEmail }}\n📊 ترافیک: {{ .ClientTraffic }}\n📅 تاریخ انقضا: {{ .ClientExp }}\n💬 نظر: {{ .ClientComment }}\n\nحالا می‌توانید مشتری را به ورودی اضافه کنید!"
-"inbound_client_data_pass" = "🔄 ورودی: {{ .InboundRemark }}\n\n🔑 رمز عبور: {{ .ClientPass }}\n📧 ایمیل: {{ .ClientEmail }}\n📊 ترافیک: {{ .ClientTraffic }}\n📅 تاریخ انقضا: {{ .ClientExp }}\n💬 نظر: {{ .ClientComment }}\n\nحالا می‌توانید مشتری را به ورودی اضافه کنید!"
+"inbound_client_data_id" = "🔄 ورودی: {{ .InboundRemark }}\n\n🔑 شناسه: {{ .ClientId }}\n📧 ایمیل: {{ .ClientEmail }}\n📊 ترافیک: {{ .ClientTraffic }}\n📅 تاریخ انقضا: {{ .ClientExp }}\n🌐 محدودیت IP: {{ .IpLimit }}\n💬 توضیح: {{ .ClientComment }}\n\nاکنون می‌تونی مشتری را به ورودی اضافه کنی!"
+"inbound_client_data_pass" = "🔄 ورودی: {{ .InboundRemark }}\n\n🔑 رمز عبور: {{ .ClientPass }}\n📧 ایمیل: {{ .ClientEmail }}\n📊 ترافیک: {{ .ClientTraffic }}\n📅 تاریخ انقضا: {{ .ClientExp }}\n🌐 محدودیت IP: {{ .IpLimit }}\n💬 توضیح: {{ .ClientComment }}\n\nاکنون می‌تونی مشتری را به ورودی اضافه کنی!"
 "cancel" = "❌ فرآیند لغو شد! \n\nمی‌توانید هر زمان که خواستید /start را دوباره اجرا کنید. 🔄"
 "error_add_client"  = "⚠️ خطا:\n\n {{ .error }}"
 "using_default_value"  = "باشه، از مقدار پیش‌فرض استفاده می‌کنم. 😊"
 "incorrect_input" ="ورودی شما معتبر نیست.\nعبارت‌ها باید بدون فاصله باشند.\nمثال صحیح: aaaaaa\nمثال نادرست: aaa aaa 🚫"
+"AreYouSure" = "مطمئنی؟ 🤔"
+"SuccessResetTraffic" = "📧 ایمیل: {{ .ClientEmail }}\n🏁 نتیجه: ✅ موفقیت‌آمیز"
+"FailedResetTraffic" = "📧 ایمیل: {{ .ClientEmail }}\n🏁 نتیجه: ❌ ناموفق \n\n🛠️ خطا: [ {{ .ErrorMessage }} ]"
+"FinishProcess" = "🔚 فرآیند بازنشانی ترافیک برای همه مشتریان به پایان رسید."
 
 
 [tgbot.buttons]
@@ -657,6 +661,9 @@
 "change_password" = "⚙️🔑 گذرواژه"
 "change_email" = "⚙️📧 ایمیل"
 "change_comment" = "⚙️💬 نظر"
+"ResetAllTraffics" = "بازنشانی همه ترافیک‌ها"
+"SortedTrafficUsageReport" = "گزارش استفاده از ترافیک مرتب‌شده"
+
 
 [tgbot.answers]
 "successfulOperation" = "✅ انجام شد!"

+ 8 - 3
web/translation/translate.id_ID.toml

@@ -607,12 +607,16 @@
 "pass_prompt" = "🔑 Kata Sandi Default: {{ .ClientPassword }}\n\nMasukkan kata sandi Anda."
 "email_prompt" = "📧 Email Default: {{ .ClientEmail }}\n\nMasukkan email Anda."
 "comment_prompt" = "💬 Komentar Default: {{ .ClientComment }}\n\nMasukkan komentar Anda."
-"inbound_client_data_id" = "🔄 Masuk: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 Email: {{ .ClientEmail }}\n📊 Lalu Lintas: {{ .ClientTraffic }}\n📅 Tanggal Kedaluwarsa: {{ .ClientExp }}\n💬 Komentar: {{ .ClientComment }}\n\nSekarang Anda bisa menambahkan klien ke masuk!"
-"inbound_client_data_pass" = "🔄 Masuk: {{ .InboundRemark }}\n\n🔑 Kata Sandi: {{ .ClientPass }}\n📧 Email: {{ .ClientEmail }}\n📊 Lalu Lintas: {{ .ClientTraffic }}\n📅 Tanggal Kedaluwarsa: {{ .ClientExp }}\n💬 Komentar: {{ .ClientComment }}\n\nSekarang Anda bisa menambahkan klien ke masuk!"
+"inbound_client_data_id" = "🔄 Masuk: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 Email: {{ .ClientEmail }}\n📊 Lalu lintas: {{ .ClientTraffic }}\n📅 Tanggal Kedaluwarsa: {{ .ClientExp }}\n🌐 Batas IP: {{ .IpLimit }}\n💬 Komentar: {{ .ClientComment }}\n\nSekarang kamu bisa menambahkan klien ke inbound!"
+"inbound_client_data_pass" = "🔄 Masuk: {{ .InboundRemark }}\n\n🔑 Kata sandi: {{ .ClientPass }}\n📧 Email: {{ .ClientEmail }}\n📊 Lalu lintas: {{ .ClientTraffic }}\n📅 Tanggal Kedaluwarsa: {{ .ClientExp }}\n🌐 Batas IP: {{ .IpLimit }}\n💬 Komentar: {{ .ClientComment }}\n\nSekarang kamu bisa menambahkan klien ke inbound!"
 "cancel" = "❌ Proses Dibatalkan! \n\nAnda dapat /start lagi kapan saja. 🔄"
 "error_add_client"  = "⚠️ Kesalahan:\n\n {{ .error }}"
 "using_default_value"  = "Oke, saya akan tetap menggunakan nilai default. 😊"
 "incorrect_input" ="Masukan Anda tidak valid.\nFrasa harus berlanjut tanpa spasi.\nContoh benar: aaaaaa\nContoh salah: aaa aaa 🚫"
+"AreYouSure" = "Apakah kamu yakin? 🤔"
+"SuccessResetTraffic" = "📧 Email: {{ .ClientEmail }}\n🏁 Hasil: ✅ Berhasil"
+"FailedResetTraffic" = "📧 Email: {{ .ClientEmail }}\n🏁 Hasil: ❌ Gagal \n\n🛠️ Kesalahan: [ {{ .ErrorMessage }} ]"
+"FinishProcess" = "🔚 Proses reset traffic selesai untuk semua klien."
 
 
 [tgbot.buttons]
@@ -657,7 +661,8 @@
 "change_password" = "⚙️🔑 Kata Sandi"
 "change_email" = "⚙️📧 Email"
 "change_comment" = "⚙️💬 Komentar"
-
+"ResetAllTraffics" = "Reset Semua Lalu Lintas"
+"SortedTrafficUsageReport" = "Laporan Penggunaan Lalu Lintas yang Terurut"
 
 
 [tgbot.answers]

+ 9 - 2
web/translation/translate.ja_JP.toml

@@ -607,12 +607,16 @@
 "pass_prompt" = "🔑 デフォルトパスワード: {{ .ClientPassword }}\n\nパスワードを入力してください。"
 "email_prompt" = "📧 デフォルトメール: {{ .ClientEmail }}\n\nメールを入力してください。"
 "comment_prompt" = "💬 デフォルトコメント: {{ .ClientComment }}\n\nコメントを入力してください。"
-"inbound_client_data_id" = "🔄 入力: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 メール: {{ .ClientEmail }}\n📊 トラフィック: {{ .ClientTraffic }}\n📅 期限: {{ .ClientExp }}\n💬 コメント: {{ .ClientComment }}\n\n今すぐクライアントをインバウンドに追加できます!"
-"inbound_client_data_pass" = "🔄 入力: {{ .InboundRemark }}\n\n🔑 パスワード: {{ .ClientPass }}\n📧 メール: {{ .ClientEmail }}\n📊 トラフィック: {{ .ClientTraffic }}\n📅 期限: {{ .ClientExp }}\n💬 コメント: {{ .ClientComment }}\n\n今すぐクライアントをインバウンドに追加できます!"
+"inbound_client_data_id" = "🔄 インバウンド: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 メール: {{ .ClientEmail }}\n📊 トラフィック: {{ .ClientTraffic }}\n📅 有効期限: {{ .ClientExp }}\n🌐 IP制限: {{ .IpLimit }}\n💬 コメント: {{ .ClientComment }}\n\n今すぐこのクライアントをインバウンドに追加できます!"
+"inbound_client_data_pass" = "🔄 インバウンド: {{ .InboundRemark }}\n\n🔑 パスワード: {{ .ClientPass }}\n📧 メール: {{ .ClientEmail }}\n📊 トラフィック: {{ .ClientTraffic }}\n📅 有効期限: {{ .ClientExp }}\n🌐 IP制限: {{ .IpLimit }}\n💬 コメント: {{ .ClientComment }}\n\n今すぐこのクライアントをインバウンドに追加できます!"
 "cancel" = "❌ プロセスがキャンセルされました!\n\nいつでも /start で再開できます。 🔄"
 "error_add_client"  = "⚠️ エラー:\n\n {{ .error }}"
 "using_default_value"  = "わかりました、デフォルト値を使用します。 😊"
 "incorrect_input" ="入力が無効です。\nフレーズはスペースなしで続けて入力してください。\n正しい例: aaaaaa\n間違った例: aaa aaa 🚫"
+"AreYouSure" = "本当にいいですか?🤔"
+"SuccessResetTraffic" = "📧 メール: {{ .ClientEmail }}\n🏁 結果: ✅ 成功"
+"FailedResetTraffic" = "📧 メール: {{ .ClientEmail }}\n🏁 結果: ❌ 失敗 \n\n🛠️ エラー: [ {{ .ErrorMessage }} ]"
+"FinishProcess" = "🔚 すべてのクライアントのトラフィックリセットが完了しました。"
 
 
 [tgbot.buttons]
@@ -657,6 +661,9 @@
 "change_password" = "⚙️🔑 パスワード"
 "change_email" = "⚙️📧 メールアドレス"
 "change_comment" = "⚙️💬 コメント"
+"ResetAllTraffics" = "すべてのトラフィックをリセット"
+"SortedTrafficUsageReport" = "ソートされたトラフィック使用レポート"
+
 
 [tgbot.answers]
 "successfulOperation" = "✅ 成功!"

+ 8 - 2
web/translation/translate.pt_BR.toml

@@ -607,12 +607,16 @@
 "pass_prompt" = "🔑 Senha Padrão: {{ .ClientPassword }}\n\nDigite sua senha."
 "email_prompt" = "📧 E-mail Padrão: {{ .ClientEmail }}\n\nDigite seu e-mail."
 "comment_prompt" = "💬 Comentário Padrão: {{ .ClientComment }}\n\nDigite seu comentário."
-"inbound_client_data_id" = "🔄 Entrada: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 Email: {{ .ClientEmail }}\n📊 Tráfego: {{ .ClientTraffic }}\n📅 Data de expiração: {{ .ClientExp }}\n💬 Comentário: {{ .ClientComment }}\n\nAgora você pode adicionar o cliente à entrada!"
-"inbound_client_data_pass" = "🔄 Entrada: {{ .InboundRemark }}\n\n🔑 Senha: {{ .ClientPass }}\n📧 Email: {{ .ClientEmail }}\n📊 Tráfego: {{ .ClientTraffic }}\n📅 Data de expiração: {{ .ClientExp }}\n💬 Comentário: {{ .ClientComment }}\n\nAgora você pode adicionar o cliente à entrada!"
+"inbound_client_data_id" = "🔄 Entrada: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 Email: {{ .ClientEmail }}\n📊 Tráfego: {{ .ClientTraffic }}\n📅 Data de expiração: {{ .ClientExp }}\n🌐 Limite de IP: {{ .IpLimit }}\n💬 Comentário: {{ .ClientComment }}\n\nAgora você pode adicionar o cliente à entrada!"
+"inbound_client_data_pass" = "🔄 Entrada: {{ .InboundRemark }}\n\n🔑 Senha: {{ .ClientPass }}\n📧 Email: {{ .ClientEmail }}\n📊 Tráfego: {{ .ClientTraffic }}\n📅 Data de expiração: {{ .ClientExp }}\n🌐 Limite de IP: {{ .IpLimit }}\n💬 Comentário: {{ .ClientComment }}\n\nAgora você pode adicionar o cliente à entrada!"
 "cancel" = "❌ Processo Cancelado! \n\nVocê pode iniciar novamente a qualquer momento com /start. 🔄"
 "error_add_client"  = "⚠️ Erro:\n\n {{ .error }}"
 "using_default_value"  = "Tudo bem, vou manter o valor padrão. 😊"
 "incorrect_input" ="Sua entrada não é válida.\nAs frases devem ser contínuas, sem espaços.\nExemplo correto: aaaaaa\nExemplo incorreto: aaa aaa 🚫"
+"AreYouSure" = "Você tem certeza? 🤔"
+"SuccessResetTraffic" = "📧 Email: {{ .ClientEmail }}\n🏁 Resultado: ✅ Sucesso"
+"FailedResetTraffic" = "📧 Email: {{ .ClientEmail }}\n🏁 Resultado: ❌ Falhou \n\n🛠️ Erro: [ {{ .ErrorMessage }} ]"
+"FinishProcess" = "🔚 Processo de redefinição de tráfego concluído para todos os clientes."
 
 
 [tgbot.buttons]
@@ -657,6 +661,8 @@
 "change_password" = "⚙️🔑 Senha"
 "change_email" = "⚙️📧 E-mail"
 "change_comment" = "⚙️💬 Comentário"
+"ResetAllTraffics" = "Redefinir Todo o Tráfego"
+"SortedTrafficUsageReport" = "Relatório de Uso de Tráfego Ordenado"
 
 
 [tgbot.answers]

+ 8 - 2
web/translation/translate.ru_RU.toml

@@ -607,12 +607,16 @@
 "pass_prompt" = "🔑 Стандартный пароль: {{ .ClientPassword }}\n\nВведите ваш пароль."
 "email_prompt" = "📧 Стандартный email: {{ .ClientEmail }}\n\nВведите ваш email."
 "comment_prompt" = "💬 Стандартный комментарий: {{ .ClientComment }}\n\nВведите ваш комментарий."
-"inbound_client_data_id" = "🔄 Входящие: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 Email: {{ .ClientEmail }}\n📊 Трафик: {{ .ClientTraffic }}\n📅 Дата истечения: {{ .ClientExp }}\n💬 Комментарий: {{ .ClientComment }}\n\nТеперь вы можете добавить клиента во входящие!"
-"inbound_client_data_pass" = "🔄 Входящие: {{ .InboundRemark }}\n\n🔑 Пароль: {{ .ClientPass }}\n📧 Email: {{ .ClientEmail }}\n📊 Трафик: {{ .ClientTraffic }}\n📅 Дата истечения: {{ .ClientExp }}\n💬 Комментарий: {{ .ClientComment }}\n\nТеперь вы можете добавить клиента во входящие!"
+"inbound_client_data_id" = "🔄 Вход: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 Почта: {{ .ClientEmail }}\n📊 Трафик: {{ .ClientTraffic }}\n📅 Дата окончания: {{ .ClientExp }}\n🌐 Лимит IP: {{ .IpLimit }}\n💬 Комментарий: {{ .ClientComment }}\n\nТеперь вы можете добавить клиента во входящий поток!"
+"inbound_client_data_pass" = "🔄 Вход: {{ .InboundRemark }}\n\n🔑 Пароль: {{ .ClientPass }}\n📧 Почта: {{ .ClientEmail }}\n📊 Трафик: {{ .ClientTraffic }}\n📅 Дата окончания: {{ .ClientExp }}\n🌐 Лимит IP: {{ .IpLimit }}\n💬 Комментарий: {{ .ClientComment }}\n\nТеперь вы можете добавить клиента во входящий поток!"
 "cancel" = "❌ Процесс отменён! \n\nВы можете снова начать с /start в любое время. 🔄"
 "error_add_client"  = "⚠️ Ошибка:\n\n {{ .error }}"
 "using_default_value"  = "Хорошо, оставлю значение по умолчанию. 😊"
 "incorrect_input" ="Ваш ввод недействителен.\nФразы должны быть непрерывными без пробелов.\nПравильный пример: aaaaaa\nНеправильный пример: aaa aaa 🚫"
+"AreYouSure" = "Вы уверены? 🤔"
+"SuccessResetTraffic" = "📧 Почта: {{ .ClientEmail }}\n🏁 Результат: ✅ Успешно"
+"FailedResetTraffic" = "📧 Почта: {{ .ClientEmail }}\n🏁 Результат: ❌ Неудача \n\n🛠️ Ошибка: [ {{ .ErrorMessage }} ]"
+"FinishProcess" = "🔚 Сброс трафика завершён для всех клиентов."
 
 
 [tgbot.buttons]
@@ -657,6 +661,8 @@
 "change_password" = "⚙️🔑 Пароль"
 "change_email" = "⚙️📧 Электронная почта"
 "change_comment" = "⚙️💬 Комментарий"
+"ResetAllTraffics" = "Сбросить весь трафик"
+"SortedTrafficUsageReport" = "Отсортированный отчет об использовании трафика"
 
 
 [tgbot.answers]

+ 8 - 2
web/translation/translate.tr_TR.toml

@@ -607,12 +607,16 @@
 "pass_prompt" = "🔑 Varsayılan Şifre: {{ .ClientPassword }}\n\nŞifrenizi girin."
 "email_prompt" = "📧 Varsayılan E-posta: {{ .ClientEmail }}\n\nE-postanızı girin."
 "comment_prompt" = "💬 Varsayılan Yorum: {{ .ClientComment }}\n\nYorumunuzu girin."
-"inbound_client_data_id" = "🔄 Giriş: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 E-posta: {{ .ClientEmail }}\n📊 Trafik: {{ .ClientTraffic }}\n📅 Son Kullanım Tarihi: {{ .ClientExp }}\n💬 Yorum: {{ .ClientComment }}\n\nŞimdi müşteriyi girişe ekleyebilirsiniz!"
-"inbound_client_data_pass" = "🔄 Giriş: {{ .InboundRemark }}\n\n🔑 Şifre: {{ .ClientPass }}\n📧 E-posta: {{ .ClientEmail }}\n📊 Trafik: {{ .ClientTraffic }}\n📅 Son Kullanım Tarihi: {{ .ClientExp }}\n💬 Yorum: {{ .ClientComment }}\n\nŞimdi müşteriyi girişe ekleyebilirsiniz!"
+"inbound_client_data_id" = "🔄 Giriş: {{ .InboundRemark }}\n\n🔑 Kimlik: {{ .ClientId }}\n📧 E-posta: {{ .ClientEmail }}\n📊 Trafik: {{ .ClientTraffic }}\n📅 Bitiş Tarihi: {{ .ClientExp }}\n🌐 IP Sınırı: {{ .IpLimit }}\n💬 Yorum: {{ .ClientComment }}\n\nArtık bu müşteriyi girişe ekleyebilirsin!"
+"inbound_client_data_pass" = "🔄 Giriş: {{ .InboundRemark }}\n\n🔑 Şifre: {{ .ClientPass }}\n📧 E-posta: {{ .ClientEmail }}\n📊 Trafik: {{ .ClientTraffic }}\n📅 Bitiş Tarihi: {{ .ClientExp }}\n🌐 IP Sınırı: {{ .IpLimit }}\n💬 Yorum: {{ .ClientComment }}\n\nArtık bu müşteriyi girişe ekleyebilirsin!"
 "cancel" = "❌ İşlem iptal edildi! \n\nİstediğiniz zaman /start ile yeniden başlayabilirsiniz. 🔄"
 "error_add_client"  = "⚠️ Hata:\n\n {{ .error }}"
 "using_default_value"  = "Tamam, varsayılan değeri kullanacağım. 😊"
 "incorrect_input" ="Girdiğiniz değer geçerli değil.\nKelime öbekleri boşluk olmadan devam etmelidir.\nDoğru örnek: aaaaaa\nYanlış örnek: aaa aaa 🚫"
+"AreYouSure" = "Emin misin? 🤔"
+"SuccessResetTraffic" = "📧 E-posta: {{ .ClientEmail }}\n🏁 Sonuç: ✅ Başarılı"
+"FailedResetTraffic" = "📧 E-posta: {{ .ClientEmail }}\n🏁 Sonuç: ❌ Başarısız \n\n🛠️ Hata: [ {{ .ErrorMessage }} ]"
+"FinishProcess" = "🔚 Tüm müşteriler için trafik sıfırlama işlemi tamamlandı."
 
 
 [tgbot.buttons]
@@ -657,6 +661,8 @@
 "change_password" = "⚙️🔑 Şifre"
 "change_email" = "⚙️📧 E-posta"
 "change_comment" = "⚙️💬 Yorum"
+"ResetAllTraffics" = "Tüm Trafikleri Sıfırla"
+"SortedTrafficUsageReport" = "Sıralı Trafik Kullanım Raporu"
 
 
 [tgbot.answers]

+ 8 - 2
web/translation/translate.uk_UA.toml

@@ -607,12 +607,16 @@
 "pass_prompt" = "🔑 Стандартний пароль: {{ .ClientPassword }}\n\nВведіть ваш пароль."
 "email_prompt" = "📧 Стандартний email: {{ .ClientEmail }}\n\nВведіть ваш email."
 "comment_prompt" = "💬 Стандартний коментар: {{ .ClientComment }}\n\nВведіть ваш коментар."
-"inbound_client_data_id" = "🔄 Вхідні: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 Email: {{ .ClientEmail }}\n📊 Трафік: {{ .ClientTraffic }}\n📅 Термін придатності: {{ .ClientExp }}\n💬 Коментар: {{ .ClientComment }}\n\nТепер ви можете додати клієнта до вхідних!"
-"inbound_client_data_pass" = "🔄 Вхідні: {{ .InboundRemark }}\n\n🔑 Пароль: {{ .ClientPass }}\n📧 Email: {{ .ClientEmail }}\n📊 Трафік: {{ .ClientTraffic }}\n📅 Термін придатності: {{ .ClientExp }}\n💬 Коментар: {{ .ClientComment }}\n\nТепер ви можете додати клієнта до вхідних!"
+"inbound_client_data_id" = "🔄 Вхід: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 Електронна пошта: {{ .ClientEmail }}\n📊 Трафік: {{ .ClientTraffic }}\n📅 Дата завершення: {{ .ClientExp }}\n🌐 Обмеження IP: {{ .IpLimit }}\n💬 Коментар: {{ .ClientComment }}\n\nТепер ви можете додати клієнта до вхідного з'єднання!"
+"inbound_client_data_pass" = "🔄 Вхід: {{ .InboundRemark }}\n\n🔑 Пароль: {{ .ClientPass }}\n📧 Електронна пошта: {{ .ClientEmail }}\n📊 Трафік: {{ .ClientTraffic }}\n📅 Дата завершення: {{ .ClientExp }}\n🌐 Обмеження IP: {{ .IpLimit }}\n💬 Коментар: {{ .ClientComment }}\n\nТепер ви можете додати клієнта до вхідного з'єднання!"
 "cancel" = "❌ Процес скасовано! \n\nВи можете знову розпочати, використовуючи /start у будь-який час. 🔄"
 "error_add_client"  = "⚠️ Помилка:\n\n {{ .error }}"
 "using_default_value"  = "Гаразд, залишу значення за замовчуванням. 😊"
 "incorrect_input" ="Ваш ввід невірний.\nФрази повинні бути без пробілів.\nПравильний приклад: aaaaaa\nНеправильний приклад: aaa aaa 🚫"
+"AreYouSure" = "Ви впевнені? 🤔"
+"SuccessResetTraffic" = "📧 Електронна пошта: {{ .ClientEmail }}\n🏁 Результат: ✅ Успішно"
+"FailedResetTraffic" = "📧 Електронна пошта: {{ .ClientEmail }}\n🏁 Результат: ❌ Невдача \n\n🛠️ Помилка: [ {{ .ErrorMessage }} ]"
+"FinishProcess" = "🔚 Процес скидання трафіку завершено для всіх клієнтів."
 
 
 [tgbot.buttons]
@@ -657,6 +661,8 @@
 "change_password" = "⚙️🔑 Пароль"
 "change_email" = "⚙️📧 Електронна пошта"
 "change_comment" = "⚙️💬 Коментар"
+"ResetAllTraffics" = "Скинути весь трафік"
+"SortedTrafficUsageReport" = "Відсортований звіт про використання трафіку"
 
 
 [tgbot.answers]

+ 8 - 2
web/translation/translate.vi_VN.toml

@@ -607,12 +607,16 @@
 "pass_prompt" = "🔑 Mật khẩu mặc định: {{ .ClientPassword }}\n\nVui lòng nhập mật khẩu của bạn."
 "email_prompt" = "📧 Email mặc định: {{ .ClientEmail }}\n\nVui lòng nhập email của bạn."
 "comment_prompt" = "💬 Bình luận mặc định: {{ .ClientComment }}\n\nVui lòng nhập bình luận của bạn."
-"inbound_client_data_id" = "🔄 Vào: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 Email: {{ .ClientEmail }}\n📊 Lưu lượng: {{ .ClientTraffic }}\n📅 Ngày hết hạn: {{ .ClientExp }}\n💬 Bình luận: {{ .ClientComment }}\n\nBạn có thể thêm khách hàng vào vào ngay bây giờ!"
-"inbound_client_data_pass" = "🔄 Vào: {{ .InboundRemark }}\n\n🔑 Mật khẩu: {{ .ClientPass }}\n📧 Email: {{ .ClientEmail }}\n📊 Lưu lượng: {{ .ClientTraffic }}\n📅 Ngày hết hạn: {{ .ClientExp }}\n💬 Bình luận: {{ .ClientComment }}\n\nBạn có thể thêm khách hàng vào vào ngay bây giờ!"
+"inbound_client_data_id" = "🔄 Kết nối vào: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 Email: {{ .ClientEmail }}\n📊 Dung lượng: {{ .ClientTraffic }}\n📅 Ngày hết hạn: {{ .ClientExp }}\n🌐 Giới hạn IP: {{ .IpLimit }}\n💬 Ghi chú: {{ .ClientComment }}\n\nBây giờ bạn có thể thêm khách hàng vào inbound!"
+"inbound_client_data_pass" = "🔄 Kết nối vào: {{ .InboundRemark }}\n\n🔑 Mật khẩu: {{ .ClientPass }}\n📧 Email: {{ .ClientEmail }}\n📊 Dung lượng: {{ .ClientTraffic }}\n📅 Ngày hết hạn: {{ .ClientExp }}\n🌐 Giới hạn IP: {{ .IpLimit }}\n💬 Ghi chú: {{ .ClientComment }}\n\nBây giờ bạn có thể thêm khách hàng vào inbound!"
 "cancel" = "❌ Quá trình đã bị hủy! \n\nBạn có thể bắt đầu lại bất cứ lúc nào bằng cách nhập /start. 🔄"
 "error_add_client"  = "⚠️ Lỗi:\n\n {{ .error }}"
 "using_default_value"  = "Được rồi, tôi sẽ sử dụng giá trị mặc định. 😊"
 "incorrect_input" ="Dữ liệu bạn nhập không hợp lệ.\nCác chuỗi phải liền mạch và không có dấu cách.\nVí dụ đúng: aaaaaa\nVí dụ sai: aaa aaa 🚫"
+"AreYouSure" = "Bạn có chắc không? 🤔"
+"SuccessResetTraffic" = "📧 Email: {{ .ClientEmail }}\n🏁 Kết quả: ✅ Thành công"
+"FailedResetTraffic" = "📧 Email: {{ .ClientEmail }}\n🏁 Kết quả: ❌ Thất bại \n\n🛠️ Lỗi: [ {{ .ErrorMessage }} ]"
+"FinishProcess" = "🔚 Quá trình đặt lại lưu lượng đã hoàn tất cho tất cả khách hàng."
 
 
 [tgbot.buttons]
@@ -657,6 +661,8 @@
 "change_password" = "⚙️🔑 Mật Khẩu"
 "change_email" = "⚙️📧 Email"
 "change_comment" = "⚙️💬 Bình Luận"
+"ResetAllTraffics" = "Đặt lại tất cả lưu lượng"
+"SortedTrafficUsageReport" = "Báo cáo sử dụng lưu lượng đã sắp xếp"
 
 
 [tgbot.answers]

+ 8 - 2
web/translation/translate.zh_CN.toml

@@ -607,12 +607,16 @@
 "pass_prompt" = "🔑 默认密码: {{ .ClientPassword }}\n\n请输入您的密码。"
 "email_prompt" = "📧 默认邮箱: {{ .ClientEmail }}\n\n请输入您的邮箱。"
 "comment_prompt" = "💬 默认评论: {{ .ClientComment }}\n\n请输入您的评论。"
-"inbound_client_data_id" = "🔄 入站: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 邮箱: {{ .ClientEmail }}\n📊 流量: {{ .ClientTraffic }}\n📅 过期日期: {{ .ClientExp }}\n💬 评论: {{ .ClientComment }}\n\n您现在可以将客户添加到入站!"
-"inbound_client_data_pass" = "🔄 入站: {{ .InboundRemark }}\n\n🔑 密码: {{ .ClientPass }}\n📧 邮箱: {{ .ClientEmail }}\n📊 流量: {{ .ClientTraffic }}\n📅 过期日期: {{ .ClientExp }}\n💬 评论: {{ .ClientComment }}\n\n您现在可以将客户添加到入站!"
+"inbound_client_data_id" = "🔄 入站: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 邮箱: {{ .ClientEmail }}\n📊 流量: {{ .ClientTraffic }}\n📅 到期日期: {{ .ClientExp }}\n🌐 IP 限制: {{ .IpLimit }}\n💬 备注: {{ .ClientComment }}\n\n你现在可以将客户添加到入站了!"
+"inbound_client_data_pass" = "🔄 入站: {{ .InboundRemark }}\n\n🔑 密码: {{ .ClientPass }}\n📧 邮箱: {{ .ClientEmail }}\n📊 流量: {{ .ClientTraffic }}\n📅 到期日期: {{ .ClientExp }}\n🌐 IP 限制: {{ .IpLimit }}\n💬 备注: {{ .ClientComment }}\n\n你现在可以将客户添加到入站了!"
 "cancel" = "❌ 进程已取消!\n\n您可以随时使用 /start 重新开始。 🔄"
 "error_add_client"  = "⚠️ 错误:\n\n {{ .error }}"
 "using_default_value"  = "好的,我会使用默认值。 😊"
 "incorrect_input" ="您的输入无效。\n短语应连续输入,不能有空格。\n正确示例: aaaaaa\n错误示例: aaa aaa 🚫"
+"AreYouSure" = "你确定吗?🤔"
+"SuccessResetTraffic" = "📧 邮箱: {{ .ClientEmail }}\n🏁 结果: ✅ 成功"
+"FailedResetTraffic" = "📧 邮箱: {{ .ClientEmail }}\n🏁 结果: ❌ 失败 \n\n🛠️ 错误: [ {{ .ErrorMessage }} ]"
+"FinishProcess" = "🔚 所有客户的流量重置已完成。"
 
 
 [tgbot.buttons]
@@ -657,6 +661,8 @@
 "change_password" = "⚙️🔑 密码"
 "change_email" = "⚙️📧 邮箱"
 "change_comment" = "⚙️💬 评论"
+"ResetAllTraffics" = "重置所有流量"
+"SortedTrafficUsageReport" = "排序的流量使用报告"
 
 
 [tgbot.answers]

+ 8 - 2
web/translation/translate.zh_TW.toml

@@ -607,12 +607,16 @@
 "pass_prompt" = "🔑 預設密碼: {{ .ClientPassword }}\n\n請輸入您的密碼。"
 "email_prompt" = "📧 預設電子郵件: {{ .ClientEmail }}\n\n請輸入您的電子郵件。"
 "comment_prompt" = "💬 預設評論: {{ .ClientComment }}\n\n請輸入您的評論。"
-"inbound_client_data_id" = "🔄 入站: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 電子郵件: {{ .ClientEmail }}\n📊 流量: {{ .ClientTraffic }}\n📅 到期日: {{ .ClientExp }}\n💬 評論: {{ .ClientComment }}\n\n您現在可以將客戶新增至入站!"
-"inbound_client_data_pass" = "🔄 入站: {{ .InboundRemark }}\n\n🔑 密碼: {{ .ClientPass }}\n📧 電子郵件: {{ .ClientEmail }}\n📊 流量: {{ .ClientTraffic }}\n📅 到期日: {{ .ClientExp }}\n💬 評論: {{ .ClientComment }}\n\n您現在可以將客戶新增至入站!"
+"inbound_client_data_id" = "🔄 入站: {{ .InboundRemark }}\n\n🔑 ID: {{ .ClientId }}\n📧 電子郵件: {{ .ClientEmail }}\n📊 流量: {{ .ClientTraffic }}\n📅 到期日: {{ .ClientExp }}\n🌐 IP 限制: {{ .IpLimit }}\n💬 備註: {{ .ClientComment }}\n\n你現在可以將客戶加入入站了!"
+"inbound_client_data_pass" = "🔄 入站: {{ .InboundRemark }}\n\n🔑 密碼: {{ .ClientPass }}\n📧 電子郵件: {{ .ClientEmail }}\n📊 流量: {{ .ClientTraffic }}\n📅 到期日: {{ .ClientExp }}\n🌐 IP 限制: {{ .IpLimit }}\n💬 備註: {{ .ClientComment }}\n\n你現在可以將客戶加入入站了!"
 "cancel" = "❌ 程序已取消!\n\n您可以隨時使用 /start 重新開始。 🔄"
 "error_add_client"  = "⚠️ 錯誤:\n\n {{ .error }}"
 "using_default_value"  = "好的,我會使用預設值。 😊"
 "incorrect_input" ="您的輸入無效。\n短語應連續輸入,不能有空格。\n正確示例: aaaaaa\n錯誤示例: aaa aaa 🚫"
+"AreYouSure" = "你確定嗎?🤔"
+"SuccessResetTraffic" = "📧 電子郵件: {{ .ClientEmail }}\n🏁 結果: ✅ 成功"
+"FailedResetTraffic" = "📧 電子郵件: {{ .ClientEmail }}\n🏁 結果: ❌ 失敗 \n\n🛠️ 錯誤: [ {{ .ErrorMessage }} ]"
+"FinishProcess" = "🔚 所有客戶的流量重置已完成。"
 
 
 [tgbot.buttons]
@@ -657,6 +661,8 @@
 "change_password" = "⚙️🔑 密碼"
 "change_email" = "⚙️📧 電子郵件"
 "change_comment" = "⚙️💬 評論"
+"ResetAllTraffics" = "重設所有流量"
+"SortedTrafficUsageReport" = "排序過的流量使用報告"
 
 
 [tgbot.answers]