| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502 |
- package tgbot
- import (
- "context"
- "fmt"
- "html"
- "slices"
- "strconv"
- "strings"
- "time"
- "github.com/mhsanaei/3x-ui/v3/internal/logger"
- "github.com/mymmrac/telego"
- th "github.com/mymmrac/telego/telegohandler"
- tu "github.com/mymmrac/telego/telegoutil"
- )
- // recoverBotPanic must be deferred by every bot handler entry point: telego's
- // dispatch has no recovery of its own, so one bad update would kill the panel.
- func recoverBotPanic() {
- if r := recover(); r != nil {
- logger.Error("Recovered panic in Telegram bot handler:", r)
- }
- }
- // runBotHandler runs a bot handler on a worker slot and recovers panics: a bad
- // callback must not take down the whole panel, the way a cron panic would not.
- func runBotHandler(fn func()) {
- messageWorkerPool <- struct{}{}
- defer func() { <-messageWorkerPool }()
- defer recoverBotPanic()
- fn()
- }
- // chooseInboundClient fetches the inbound once and reuses the row: the inline
- // keyboard outlives the inbound, so a stale tap must answer an error, not panic.
- func (t *Tgbot) chooseInboundClient(callbackQuery *telego.CallbackQuery, chatId int64, inboundID int, action string) {
- inbound, err := t.inboundService.GetInbound(inboundID)
- if err != nil {
- logger.Warning("chooseInboundClient GetInbound failed:", err)
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.getInboundsFailed"))
- return
- }
- clientsKB, err := t.getInboundClientsFor(inbound, action)
- if err != nil {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
- return
- }
- t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.chooseClient", "Inbound=="+inbound.Remark), clientsKB)
- }
- // OnReceive starts the message receiving loop for the Telegram bot.
- func (t *Tgbot) OnReceive() {
- params := telego.GetUpdatesParams{
- Timeout: 20, // Reduced timeout to detect connection issues faster
- }
- // Strict singleton: never start a second long-polling loop.
- tgBotMutex.Lock()
- if botCancel != nil || isRunning {
- tgBotMutex.Unlock()
- logger.Warning("TgBot OnReceive called while already running; ignoring.")
- return
- }
- ctx, cancel := context.WithCancel(context.Background())
- botCancel = cancel
- isRunning = true
- // Add to WaitGroup before releasing the lock so StopBot() can't return
- // before this receiver goroutine is accounted for.
- botWG.Add(1)
- tgBotMutex.Unlock()
- // Get updates channel using the context with shorter timeout for better error recovery
- updates, _ := bot.UpdatesViaLongPolling(ctx, ¶ms)
- go func() {
- defer botWG.Done()
- h, _ := th.NewBotHandler(bot, updates)
- tgBotMutex.Lock()
- botHandler = h
- tgBotMutex.Unlock()
- h.HandleMessage(func(ctx *th.Context, message telego.Message) error {
- defer recoverBotPanic()
- userStateMgr.clear(message.Chat.ID)
- t.SendMsgToTgbot(message.Chat.ID, t.I18nBot("tgbot.keyboardClosed"), tu.ReplyKeyboardRemove())
- return nil
- }, th.TextEqual(t.I18nBot("tgbot.buttons.closeKeyboard")))
- h.HandleMessage(func(ctx *th.Context, message telego.Message) error {
- defer recoverBotPanic()
- if !t.isCommandForCurrentBot(&message) {
- return nil
- }
- // Use goroutine with worker pool for concurrent command processing
- go runBotHandler(func() {
- userStateMgr.clear(message.Chat.ID)
- t.answerCommand(&message, message.Chat.ID, checkAdmin(message.From.ID))
- })
- return nil
- }, th.AnyCommand())
- h.HandleCallbackQuery(func(ctx *th.Context, query telego.CallbackQuery) error {
- // Use goroutine with worker pool for concurrent callback processing
- go runBotHandler(func() {
- userStateMgr.clear(query.Message.GetChat().ID)
- t.answerCallback(&query, checkAdmin(query.From.ID))
- })
- return nil
- }, th.AnyCallbackQueryWithMessage())
- h.HandleMessage(func(ctx *th.Context, message telego.Message) error {
- defer recoverBotPanic()
- userStateMgr.maybePrune(time.Hour)
- if userState, exists := userStateMgr.get(message.Chat.ID); exists {
- switch userState {
- case "awaiting_email":
- if client_Email == strings.TrimSpace(message.Text) {
- t.SendMsgToTgbotDeleteAfter(message.Chat.ID, t.I18nBot("tgbot.messages.using_default_value"), 3, tu.ReplyKeyboardRemove())
- userStateMgr.clear(message.Chat.ID)
- return nil
- }
- client_Email = strings.TrimSpace(message.Text)
- if t.isSingleWord(client_Email) {
- userStateMgr.set(message.Chat.ID, "awaiting_email")
- cancel_btn_markup := tu.InlineKeyboard(
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.use_default")).WithCallbackData("add_client_default_info"),
- ),
- )
- t.SendMsgToTgbot(message.Chat.ID, t.I18nBot("tgbot.messages.incorrect_input"), cancel_btn_markup)
- } else {
- t.SendMsgToTgbotDeleteAfter(message.Chat.ID, t.I18nBot("tgbot.messages.received_email"), 3, tu.ReplyKeyboardRemove())
- userStateMgr.clear(message.Chat.ID)
- t.addClient(message.Chat.ID, t.BuildClientDraftMessage())
- }
- case "awaiting_comment":
- if client_Comment == strings.TrimSpace(message.Text) {
- t.SendMsgToTgbotDeleteAfter(message.Chat.ID, t.I18nBot("tgbot.messages.using_default_value"), 3, tu.ReplyKeyboardRemove())
- userStateMgr.clear(message.Chat.ID)
- return nil
- }
- client_Comment = strings.TrimSpace(message.Text)
- t.SendMsgToTgbotDeleteAfter(message.Chat.ID, t.I18nBot("tgbot.messages.received_comment"), 3, tu.ReplyKeyboardRemove())
- userStateMgr.clear(message.Chat.ID)
- t.addClient(message.Chat.ID, t.BuildClientDraftMessage())
- case "awaiting_tg_id":
- input := strings.TrimSpace(message.Text)
- if input == "" || input == "-" || strings.EqualFold(input, "none") {
- client_TgID = ""
- t.SendMsgToTgbotDeleteAfter(message.Chat.ID, t.I18nBot("tgbot.messages.using_default_value"), 3, tu.ReplyKeyboardRemove())
- userStateMgr.clear(message.Chat.ID)
- t.addClient(message.Chat.ID, t.BuildClientDraftMessage())
- return nil
- }
- if _, err := strconv.ParseInt(input, 10, 64); err != nil {
- cancel_btn_markup := tu.InlineKeyboard(
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.use_default")).WithCallbackData("add_client_default_info"),
- ),
- )
- t.SendMsgToTgbot(message.Chat.ID, t.I18nBot("tgbot.messages.incorrect_input"), cancel_btn_markup)
- return nil
- }
- client_TgID = input
- t.SendMsgToTgbotDeleteAfter(message.Chat.ID, t.I18nBot("tgbot.messages.userSaved"), 3, tu.ReplyKeyboardRemove())
- userStateMgr.clear(message.Chat.ID)
- t.addClient(message.Chat.ID, t.BuildClientDraftMessage())
- }
- } else {
- if message.UsersShared != nil {
- if checkAdmin(message.From.ID) {
- for _, sharedUser := range message.UsersShared.Users {
- userID := sharedUser.UserID
- needRestart, err := t.clientService.SetClientTelegramUserID(&t.inboundService, message.UsersShared.RequestID, userID)
- if needRestart {
- t.xrayService.SetToNeedRestart()
- }
- output := ""
- if err != nil {
- output += t.I18nBot("tgbot.messages.selectUserFailed")
- } else {
- output += t.I18nBot("tgbot.messages.userSaved")
- }
- t.SendMsgToTgbot(message.Chat.ID, output, tu.ReplyKeyboardRemove())
- }
- } else {
- t.SendMsgToTgbot(message.Chat.ID, t.I18nBot("tgbot.noResult"), tu.ReplyKeyboardRemove())
- }
- }
- }
- return nil
- }, th.AnyMessage())
- _ = h.Start()
- }()
- }
- // answerCommand processes incoming command messages from Telegram users.
- func (t *Tgbot) answerCommand(message *telego.Message, chatId int64, isAdmin bool) {
- msg, onlyMessage := "", false
- command, _, commandArgs := tu.ParseCommand(message.Text)
- // Helper function to handle unknown commands.
- handleUnknownCommand := func() {
- msg += t.I18nBot("tgbot.commands.unknown")
- }
- // Handle the command.
- switch command {
- case "help":
- msg += t.I18nBot("tgbot.commands.help")
- msg += t.I18nBot("tgbot.commands.pleaseChoose")
- case "start":
- msg += t.I18nBot("tgbot.commands.start", "Firstname=="+html.EscapeString(message.From.FirstName))
- if isAdmin {
- msg += t.I18nBot("tgbot.commands.welcome", "Hostname=="+hostname)
- }
- msg += "\n\n" + t.I18nBot("tgbot.commands.pleaseChoose")
- case "status":
- onlyMessage = true
- msg += t.I18nBot("tgbot.commands.status")
- case "id":
- onlyMessage = true
- msg += t.I18nBot("tgbot.commands.getID", "ID=="+strconv.FormatInt(message.From.ID, 10))
- case "usage":
- onlyMessage = true
- if len(commandArgs) > 0 {
- if isAdmin {
- t.searchClient(chatId, commandArgs[0])
- } else {
- t.getClientUsage(chatId, message.From.ID, commandArgs[0])
- }
- } else {
- msg += t.I18nBot("tgbot.commands.usage")
- }
- case "inbound":
- onlyMessage = true
- if isAdmin && len(commandArgs) > 0 {
- t.searchInbound(chatId, commandArgs[0])
- } else {
- handleUnknownCommand()
- }
- case "restart":
- onlyMessage = true
- if isAdmin {
- if len(commandArgs) == 0 {
- if t.xrayService.IsXrayRunning() {
- err := t.xrayService.RestartXray(true)
- if err != nil {
- msg += t.I18nBot("tgbot.commands.restartFailed", "Error=="+err.Error())
- } else {
- msg += t.I18nBot("tgbot.commands.restartSuccess")
- }
- } else {
- msg += t.I18nBot("tgbot.commands.xrayNotRunning")
- }
- } else {
- handleUnknownCommand()
- msg += t.I18nBot("tgbot.commands.restartUsage")
- }
- } else {
- handleUnknownCommand()
- }
- case "clearall":
- onlyMessage = true
- if isAdmin {
- 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)
- } else {
- handleUnknownCommand()
- }
- default:
- handleUnknownCommand()
- }
- if msg != "" {
- t.sendResponse(chatId, msg, onlyMessage, isAdmin)
- }
- }
- func (t *Tgbot) isCommandForCurrentBot(message *telego.Message) bool {
- return isCommandForBot(message.Text, botUsername())
- }
- func botUsername() string {
- if bot == nil {
- return ""
- }
- return bot.Username()
- }
- func isCommandForBot(text string, username string) bool {
- _, commandUsername, _ := tu.ParseCommand(text)
- return commandUsername == "" || username == "" || strings.EqualFold(commandUsername, username)
- }
- // answerCallback processes callback queries from inline keyboards.
- func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool) {
- chatId := callbackQuery.Message.GetChat().ID
- if isAdmin {
- // get query from hash storage
- decodedQuery, err := t.decodeQuery(callbackQuery.Data)
- if err != nil {
- t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.noQuery"))
- return
- }
- dataArray := strings.Split(decodedQuery, " ")
- if len(dataArray) >= 2 && len(dataArray[1]) > 0 {
- email := dataArray[1]
- switch dataArray[0] {
- case "get_clients_for_sub":
- inboundIdInt, err := strconv.Atoi(dataArray[1])
- if err != nil {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
- return
- }
- t.chooseInboundClient(callbackQuery, chatId, inboundIdInt, "client_sub_links")
- case "get_clients_for_individual":
- inboundIdInt, err := strconv.Atoi(dataArray[1])
- if err != nil {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
- return
- }
- t.chooseInboundClient(callbackQuery, chatId, inboundIdInt, "client_individual_links")
- case "get_clients_for_qr":
- inboundIdInt, err := strconv.Atoi(dataArray[1])
- if err != nil {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
- return
- }
- t.chooseInboundClient(callbackQuery, chatId, inboundIdInt, "client_qr_links")
- case "client_sub_links":
- t.sendClientSubLinks(chatId, email)
- return
- case "client_individual_links":
- t.sendClientIndividualLinks(chatId, email)
- return
- case "client_qr_links":
- t.sendClientQRLinks(chatId, email)
- return
- case "client_get_usage":
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.messages.email", "Email=="+email))
- t.searchClient(chatId, email)
- case "client_refresh":
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.clientRefreshSuccess", "Email=="+email))
- t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
- case "client_cancel":
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.canceled", "Email=="+email))
- t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
- case "ips_refresh":
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.IpRefreshSuccess", "Email=="+email))
- t.searchClientIps(chatId, email, callbackQuery.Message.GetMessageID())
- case "ips_cancel":
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.canceled", "Email=="+email))
- t.searchClientIps(chatId, email, callbackQuery.Message.GetMessageID())
- case "tgid_refresh":
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.TGIdRefreshSuccess", "Email=="+email))
- t.clientTelegramUserInfo(chatId, email, callbackQuery.Message.GetMessageID())
- case "tgid_cancel":
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.canceled", "Email=="+email))
- t.clientTelegramUserInfo(chatId, email, callbackQuery.Message.GetMessageID())
- case "reset_traffic":
- inlineKeyboard := tu.InlineKeyboard(
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancelReset")).WithCallbackData(t.encodeQuery("client_cancel "+email)),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmResetTraffic")).WithCallbackData(t.encodeQuery("reset_traffic_c "+email)),
- ),
- )
- t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
- case "reset_traffic_c":
- err := t.inboundService.ResetClientTrafficByEmail(email)
- if err == nil {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.resetTrafficSuccess", "Email=="+email))
- t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
- } else {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
- }
- case "limit_traffic":
- inlineKeyboard := tu.InlineKeyboard(
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancel")).WithCallbackData(t.encodeQuery("client_cancel "+email)),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.unlimited")).WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 0")),
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.custom")).WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" 0")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("1 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 1")),
- tu.InlineKeyboardButton("5 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 5")),
- tu.InlineKeyboardButton("10 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 10")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("20 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 20")),
- tu.InlineKeyboardButton("30 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 30")),
- tu.InlineKeyboardButton("40 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 40")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("50 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 50")),
- tu.InlineKeyboardButton("60 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 60")),
- tu.InlineKeyboardButton("80 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 80")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("100 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 100")),
- tu.InlineKeyboardButton("150 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 150")),
- tu.InlineKeyboardButton("200 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 200")),
- ),
- )
- t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
- case "limit_traffic_c":
- if len(dataArray) == 3 {
- limitTraffic, err := strconv.Atoi(dataArray[2])
- if err == nil {
- needRestart, err := t.clientService.ResetClientTrafficLimitByEmail(&t.inboundService, email, limitTraffic)
- if needRestart {
- t.xrayService.SetToNeedRestart()
- }
- if err == nil {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.setTrafficLimitSuccess", "Email=="+email))
- t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
- return
- }
- }
- }
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
- t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
- case "limit_traffic_in":
- if len(dataArray) >= 3 {
- oldInputNumber, err := strconv.Atoi(dataArray[2])
- inputNumber := oldInputNumber
- if err == nil {
- if len(dataArray) == 4 {
- num, err := strconv.Atoi(dataArray[3])
- if err == nil {
- inputNumber = updateNumericInput(inputNumber, 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("client_cancel "+email)),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmNumberAdd", "Num=="+strconv.Itoa(inputNumber))).WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" "+strconv.Itoa(inputNumber))),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("1").WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" "+strconv.Itoa(inputNumber)+" 1")),
- tu.InlineKeyboardButton("2").WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" "+strconv.Itoa(inputNumber)+" 2")),
- tu.InlineKeyboardButton("3").WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" "+strconv.Itoa(inputNumber)+" 3")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("4").WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" "+strconv.Itoa(inputNumber)+" 4")),
- tu.InlineKeyboardButton("5").WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" "+strconv.Itoa(inputNumber)+" 5")),
- tu.InlineKeyboardButton("6").WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" "+strconv.Itoa(inputNumber)+" 6")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("7").WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" "+strconv.Itoa(inputNumber)+" 7")),
- tu.InlineKeyboardButton("8").WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" "+strconv.Itoa(inputNumber)+" 8")),
- tu.InlineKeyboardButton("9").WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" "+strconv.Itoa(inputNumber)+" 9")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("🔄").WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" "+strconv.Itoa(inputNumber)+" -2")),
- tu.InlineKeyboardButton("0").WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" "+strconv.Itoa(inputNumber)+" 0")),
- tu.InlineKeyboardButton("⬅️").WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" "+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 "add_client_limit_traffic_c":
- limitTraffic, _ := strconv.ParseInt(dataArray[1], 10, 64)
- client_TotalGB = limitTraffic * 1024 * 1024 * 1024
- messageId := callbackQuery.Message.GetMessageID()
- message_text := t.BuildClientDraftMessage()
- t.addClient(callbackQuery.Message.GetChat().ID, message_text, messageId)
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))
- case "add_client_limit_traffic_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 {
- inputNumber = updateNumericInput(inputNumber, 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_traffic_exp")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmNumberAdd", "Num=="+strconv.Itoa(inputNumber))).WithCallbackData(t.encodeQuery("add_client_limit_traffic_c "+strconv.Itoa(inputNumber))),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("1").WithCallbackData(t.encodeQuery("add_client_limit_traffic_in "+strconv.Itoa(inputNumber)+" 1")),
- tu.InlineKeyboardButton("2").WithCallbackData(t.encodeQuery("add_client_limit_traffic_in "+strconv.Itoa(inputNumber)+" 2")),
- tu.InlineKeyboardButton("3").WithCallbackData(t.encodeQuery("add_client_limit_traffic_in "+strconv.Itoa(inputNumber)+" 3")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("4").WithCallbackData(t.encodeQuery("add_client_limit_traffic_in "+strconv.Itoa(inputNumber)+" 4")),
- tu.InlineKeyboardButton("5").WithCallbackData(t.encodeQuery("add_client_limit_traffic_in "+strconv.Itoa(inputNumber)+" 5")),
- tu.InlineKeyboardButton("6").WithCallbackData(t.encodeQuery("add_client_limit_traffic_in "+strconv.Itoa(inputNumber)+" 6")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("7").WithCallbackData(t.encodeQuery("add_client_limit_traffic_in "+strconv.Itoa(inputNumber)+" 7")),
- tu.InlineKeyboardButton("8").WithCallbackData(t.encodeQuery("add_client_limit_traffic_in "+strconv.Itoa(inputNumber)+" 8")),
- tu.InlineKeyboardButton("9").WithCallbackData(t.encodeQuery("add_client_limit_traffic_in "+strconv.Itoa(inputNumber)+" 9")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("🔄").WithCallbackData(t.encodeQuery("add_client_limit_traffic_in "+strconv.Itoa(inputNumber)+" -2")),
- tu.InlineKeyboardButton("0").WithCallbackData(t.encodeQuery("add_client_limit_traffic_in "+strconv.Itoa(inputNumber)+" 0")),
- tu.InlineKeyboardButton("⬅️").WithCallbackData(t.encodeQuery("add_client_limit_traffic_in "+strconv.Itoa(inputNumber)+" -1")),
- ),
- )
- t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
- return
- }
- }
- case "reset_exp":
- inlineKeyboard := tu.InlineKeyboard(
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancelReset")).WithCallbackData(t.encodeQuery("client_cancel "+email)),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.unlimited")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 0")),
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.custom")).WithCallbackData(t.encodeQuery("reset_exp_in "+email+" 0")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 7 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 7")),
- tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 10 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 10")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 14 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 14")),
- tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 20 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 20")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 1 "+t.I18nBot("tgbot.month")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 30")),
- tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 3 "+t.I18nBot("tgbot.months")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 90")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 6 "+t.I18nBot("tgbot.months")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 180")),
- tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 12 "+t.I18nBot("tgbot.months")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 365")),
- ),
- )
- t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
- case "reset_exp_c":
- if len(dataArray) == 3 {
- days, err := strconv.ParseInt(dataArray[2], 10, 64)
- if err == nil {
- var date int64
- if days > 0 {
- traffic, err := t.inboundService.GetClientTrafficByEmail(email)
- if err != nil {
- logger.Warning(err)
- msg := t.I18nBot("tgbot.wentWrong")
- t.SendMsgToTgbot(chatId, msg)
- return
- }
- if traffic == nil {
- msg := t.I18nBot("tgbot.noResult")
- t.SendMsgToTgbot(chatId, msg)
- return
- }
- if traffic.ExpiryTime > 0 {
- if traffic.ExpiryTime-time.Now().Unix()*1000 < 0 {
- date = -(days * 24 * 60 * 60000)
- } else {
- date = traffic.ExpiryTime + days*24*60*60000
- }
- } else {
- date = traffic.ExpiryTime - days*24*60*60000
- }
- }
- needRestart, err := t.clientService.ResetClientExpiryTimeByEmail(&t.inboundService, email, date)
- if needRestart {
- t.xrayService.SetToNeedRestart()
- }
- if err == nil {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.expireResetSuccess", "Email=="+email))
- t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
- return
- }
- }
- }
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
- t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
- case "reset_exp_in":
- if len(dataArray) >= 3 {
- oldInputNumber, err := strconv.Atoi(dataArray[2])
- inputNumber := oldInputNumber
- if err == nil {
- if len(dataArray) == 4 {
- num, err := strconv.Atoi(dataArray[3])
- if err == nil {
- inputNumber = updateNumericInput(inputNumber, 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("client_cancel "+email)),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmNumber", "Num=="+strconv.Itoa(inputNumber))).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" "+strconv.Itoa(inputNumber))),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("1").WithCallbackData(t.encodeQuery("reset_exp_in "+email+" "+strconv.Itoa(inputNumber)+" 1")),
- tu.InlineKeyboardButton("2").WithCallbackData(t.encodeQuery("reset_exp_in "+email+" "+strconv.Itoa(inputNumber)+" 2")),
- tu.InlineKeyboardButton("3").WithCallbackData(t.encodeQuery("reset_exp_in "+email+" "+strconv.Itoa(inputNumber)+" 3")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("4").WithCallbackData(t.encodeQuery("reset_exp_in "+email+" "+strconv.Itoa(inputNumber)+" 4")),
- tu.InlineKeyboardButton("5").WithCallbackData(t.encodeQuery("reset_exp_in "+email+" "+strconv.Itoa(inputNumber)+" 5")),
- tu.InlineKeyboardButton("6").WithCallbackData(t.encodeQuery("reset_exp_in "+email+" "+strconv.Itoa(inputNumber)+" 6")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("7").WithCallbackData(t.encodeQuery("reset_exp_in "+email+" "+strconv.Itoa(inputNumber)+" 7")),
- tu.InlineKeyboardButton("8").WithCallbackData(t.encodeQuery("reset_exp_in "+email+" "+strconv.Itoa(inputNumber)+" 8")),
- tu.InlineKeyboardButton("9").WithCallbackData(t.encodeQuery("reset_exp_in "+email+" "+strconv.Itoa(inputNumber)+" 9")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("🔄").WithCallbackData(t.encodeQuery("reset_exp_in "+email+" "+strconv.Itoa(inputNumber)+" -2")),
- tu.InlineKeyboardButton("0").WithCallbackData(t.encodeQuery("reset_exp_in "+email+" "+strconv.Itoa(inputNumber)+" 0")),
- tu.InlineKeyboardButton("⬅️").WithCallbackData(t.encodeQuery("reset_exp_in "+email+" "+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 "add_client_reset_exp_c":
- client_ExpiryTime = 0
- days, _ := strconv.ParseInt(dataArray[1], 10, 64)
- var date int64
- if client_ExpiryTime > 0 {
- if client_ExpiryTime-time.Now().Unix()*1000 < 0 {
- date = -(days * 24 * 60 * 60000)
- } else {
- date = client_ExpiryTime + days*24*60*60000
- }
- } else {
- date = client_ExpiryTime - days*24*60*60000
- }
- client_ExpiryTime = date
- messageId := callbackQuery.Message.GetMessageID()
- message_text := t.BuildClientDraftMessage()
- t.addClient(callbackQuery.Message.GetChat().ID, message_text, messageId)
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))
- case "add_client_reset_exp_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 {
- inputNumber = updateNumericInput(inputNumber, 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_traffic_exp")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmNumberAdd", "Num=="+strconv.Itoa(inputNumber))).WithCallbackData(t.encodeQuery("add_client_reset_exp_c "+strconv.Itoa(inputNumber))),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("1").WithCallbackData(t.encodeQuery("add_client_reset_exp_in "+strconv.Itoa(inputNumber)+" 1")),
- tu.InlineKeyboardButton("2").WithCallbackData(t.encodeQuery("add_client_reset_exp_in "+strconv.Itoa(inputNumber)+" 2")),
- tu.InlineKeyboardButton("3").WithCallbackData(t.encodeQuery("add_client_reset_exp_in "+strconv.Itoa(inputNumber)+" 3")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("4").WithCallbackData(t.encodeQuery("add_client_reset_exp_in "+strconv.Itoa(inputNumber)+" 4")),
- tu.InlineKeyboardButton("5").WithCallbackData(t.encodeQuery("add_client_reset_exp_in "+strconv.Itoa(inputNumber)+" 5")),
- tu.InlineKeyboardButton("6").WithCallbackData(t.encodeQuery("add_client_reset_exp_in "+strconv.Itoa(inputNumber)+" 6")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("7").WithCallbackData(t.encodeQuery("add_client_reset_exp_in "+strconv.Itoa(inputNumber)+" 7")),
- tu.InlineKeyboardButton("8").WithCallbackData(t.encodeQuery("add_client_reset_exp_in "+strconv.Itoa(inputNumber)+" 8")),
- tu.InlineKeyboardButton("9").WithCallbackData(t.encodeQuery("add_client_reset_exp_in "+strconv.Itoa(inputNumber)+" 9")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("🔄").WithCallbackData(t.encodeQuery("add_client_reset_exp_in "+strconv.Itoa(inputNumber)+" -2")),
- tu.InlineKeyboardButton("0").WithCallbackData(t.encodeQuery("add_client_reset_exp_in "+strconv.Itoa(inputNumber)+" 0")),
- tu.InlineKeyboardButton("⬅️").WithCallbackData(t.encodeQuery("add_client_reset_exp_in "+strconv.Itoa(inputNumber)+" -1")),
- ),
- )
- t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
- return
- }
- }
- case "ip_limit":
- inlineKeyboard := tu.InlineKeyboard(
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancelIpLimit")).WithCallbackData(t.encodeQuery("client_cancel "+email)),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.unlimited")).WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 0")),
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.custom")).WithCallbackData(t.encodeQuery("ip_limit_in "+email+" 0")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("1").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 1")),
- tu.InlineKeyboardButton("2").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 2")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("3").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 3")),
- tu.InlineKeyboardButton("4").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 4")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("5").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 5")),
- tu.InlineKeyboardButton("6").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 6")),
- tu.InlineKeyboardButton("7").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 7")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("8").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 8")),
- tu.InlineKeyboardButton("9").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 9")),
- tu.InlineKeyboardButton("10").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 10")),
- ),
- )
- t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
- case "ip_limit_c":
- if len(dataArray) == 3 {
- count, err := strconv.Atoi(dataArray[2])
- if err == nil {
- needRestart, err := t.clientService.ResetClientIpLimitByEmail(&t.inboundService, email, count)
- if needRestart {
- t.xrayService.SetToNeedRestart()
- }
- if err == nil {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.resetIpSuccess", "Email=="+email, "Count=="+strconv.Itoa(count)))
- t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
- return
- }
- }
- }
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
- t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
- case "ip_limit_in":
- if len(dataArray) >= 3 {
- oldInputNumber, err := strconv.Atoi(dataArray[2])
- inputNumber := oldInputNumber
- if err == nil {
- if len(dataArray) == 4 {
- num, err := strconv.Atoi(dataArray[3])
- if err == nil {
- inputNumber = updateNumericInput(inputNumber, 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("client_cancel "+email)),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmNumber", "Num=="+strconv.Itoa(inputNumber))).WithCallbackData(t.encodeQuery("ip_limit_c "+email+" "+strconv.Itoa(inputNumber))),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("1").WithCallbackData(t.encodeQuery("ip_limit_in "+email+" "+strconv.Itoa(inputNumber)+" 1")),
- tu.InlineKeyboardButton("2").WithCallbackData(t.encodeQuery("ip_limit_in "+email+" "+strconv.Itoa(inputNumber)+" 2")),
- tu.InlineKeyboardButton("3").WithCallbackData(t.encodeQuery("ip_limit_in "+email+" "+strconv.Itoa(inputNumber)+" 3")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("4").WithCallbackData(t.encodeQuery("ip_limit_in "+email+" "+strconv.Itoa(inputNumber)+" 4")),
- tu.InlineKeyboardButton("5").WithCallbackData(t.encodeQuery("ip_limit_in "+email+" "+strconv.Itoa(inputNumber)+" 5")),
- tu.InlineKeyboardButton("6").WithCallbackData(t.encodeQuery("ip_limit_in "+email+" "+strconv.Itoa(inputNumber)+" 6")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("7").WithCallbackData(t.encodeQuery("ip_limit_in "+email+" "+strconv.Itoa(inputNumber)+" 7")),
- tu.InlineKeyboardButton("8").WithCallbackData(t.encodeQuery("ip_limit_in "+email+" "+strconv.Itoa(inputNumber)+" 8")),
- tu.InlineKeyboardButton("9").WithCallbackData(t.encodeQuery("ip_limit_in "+email+" "+strconv.Itoa(inputNumber)+" 9")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("🔄").WithCallbackData(t.encodeQuery("ip_limit_in "+email+" "+strconv.Itoa(inputNumber)+" -2")),
- tu.InlineKeyboardButton("0").WithCallbackData(t.encodeQuery("ip_limit_in "+email+" "+strconv.Itoa(inputNumber)+" 0")),
- tu.InlineKeyboardButton("⬅️").WithCallbackData(t.encodeQuery("ip_limit_in "+email+" "+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 "add_client_ip_limit_c":
- if len(dataArray) == 2 {
- count, _ := strconv.Atoi(dataArray[1])
- client_LimitIP = count
- }
- messageId := callbackQuery.Message.GetMessageID()
- message_text := t.BuildClientDraftMessage()
- t.addClient(callbackQuery.Message.GetChat().ID, 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 {
- inputNumber = updateNumericInput(inputNumber, 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
- }
- }
- case "clear_ips":
- inlineKeyboard := tu.InlineKeyboard(
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancel")).WithCallbackData(t.encodeQuery("ips_cancel "+email)),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmClearIps")).WithCallbackData(t.encodeQuery("clear_ips_c "+email)),
- ),
- )
- t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
- case "clear_ips_c":
- err := t.inboundService.ClearClientIps(email)
- if err == nil {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.clearIpSuccess", "Email=="+email))
- t.searchClientIps(chatId, email, callbackQuery.Message.GetMessageID())
- } else {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
- }
- case "ip_log":
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.getIpLog", "Email=="+email))
- t.searchClientIps(chatId, email)
- case "tg_user":
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.getUserInfo", "Email=="+email))
- t.clientTelegramUserInfo(chatId, email)
- case "tgid_remove":
- inlineKeyboard := tu.InlineKeyboard(
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancel")).WithCallbackData(t.encodeQuery("tgid_cancel "+email)),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmRemoveTGUser")).WithCallbackData(t.encodeQuery("tgid_remove_c "+email)),
- ),
- )
- t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
- case "tgid_remove_c":
- traffic, err := t.inboundService.GetClientTrafficByEmail(email)
- if err != nil || traffic == nil {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
- return
- }
- needRestart, err := t.clientService.SetClientTelegramUserID(&t.inboundService, traffic.Id, EmptyTelegramUserID)
- if needRestart {
- t.xrayService.SetToNeedRestart()
- }
- if err == nil {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.removedTGUserSuccess", "Email=="+email))
- t.clientTelegramUserInfo(chatId, email, callbackQuery.Message.GetMessageID())
- } else {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
- }
- case "toggle_enable":
- inlineKeyboard := tu.InlineKeyboard(
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancel")).WithCallbackData(t.encodeQuery("client_cancel "+email)),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmToggle")).WithCallbackData(t.encodeQuery("toggle_enable_c "+email)),
- ),
- )
- t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
- case "toggle_enable_c":
- enabled, needRestart, err := t.clientService.ToggleClientEnableByEmail(&t.inboundService, email)
- if needRestart {
- t.xrayService.SetToNeedRestart()
- }
- if err == nil {
- if enabled {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.enableSuccess", "Email=="+email))
- } else {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.disableSuccess", "Email=="+email))
- }
- t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
- } else {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
- }
- case "get_clients":
- inboundId := dataArray[1]
- inboundIdInt, err := strconv.Atoi(inboundId)
- if err != nil {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
- return
- }
- inbound, err := t.inboundService.GetInbound(inboundIdInt)
- if err != nil {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
- return
- }
- clients, err := t.getInboundClients(inboundIdInt)
- if err != nil {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
- return
- }
- t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.chooseClient", "Inbound=="+inbound.Remark), clients)
- case "add_client_to":
- client_Email = t.randomLowerAndNum(8)
- client_LimitIP = 0
- client_TotalGB = 0
- client_ExpiryTime = 0
- client_Enable = true
- client_TgID = ""
- client_SubID = t.randomLowerAndNum(16)
- client_Comment = ""
- client_Reset = 0
- inboundId := dataArray[1]
- inboundIdInt, err := strconv.Atoi(inboundId)
- if err != nil {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
- return
- }
- receiver_inbound_ID = inboundIdInt
- receiver_inbound_IDs = []int{inboundIdInt}
- t.addClient(callbackQuery.Message.GetChat().ID, t.BuildClientDraftMessage())
- case "add_client_toggle_attach":
- inboundIdStr := dataArray[1]
- inboundIdInt, err := strconv.Atoi(inboundIdStr)
- if err != nil {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
- return
- }
- found := -1
- for i, id := range receiver_inbound_IDs {
- if id == inboundIdInt {
- found = i
- break
- }
- }
- if found >= 0 {
- receiver_inbound_IDs = append(receiver_inbound_IDs[:found], receiver_inbound_IDs[found+1:]...)
- } else {
- receiver_inbound_IDs = append(receiver_inbound_IDs, inboundIdInt)
- }
- picker, err := t.getInboundsAttachPicker()
- if err != nil {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
- return
- }
- t.editMessageCallbackTgBot(callbackQuery.Message.GetChat().ID, callbackQuery.Message.GetMessageID(), picker)
- }
- return
- } else {
- switch callbackQuery.Data {
- case "get_inbounds":
- inbounds, err := t.getInbounds()
- if err != nil {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
- return
- }
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.allClients"))
- t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.chooseInbound"), inbounds)
- case "admin_client_sub_links":
- inbounds, err := t.getInboundsFor("get_clients_for_sub")
- if err != nil {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
- return
- }
- t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.chooseInbound"), inbounds)
- case "admin_client_individual_links":
- inbounds, err := t.getInboundsFor("get_clients_for_individual")
- if err != nil {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
- return
- }
- t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.chooseInbound"), inbounds)
- case "admin_client_qr_links":
- inbounds, err := t.getInboundsFor("get_clients_for_qr")
- if err != nil {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
- return
- }
- t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.chooseInbound"), inbounds)
- }
- }
- }
- if !isAdmin && !isClientSelfCallback(callbackQuery.Data) {
- return
- }
- switch callbackQuery.Data {
- case "get_usage":
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.serverUsage"))
- t.getServerUsage(chatId)
- case "usage_refresh":
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))
- t.getServerUsage(chatId, callbackQuery.Message.GetMessageID())
- case "inbounds":
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.getInbounds"))
- t.SendMsgToTgbot(chatId, t.getInboundUsages())
- case "deplete_soon":
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.depleteSoon"))
- t.getExhausted(chatId)
- case "get_backup":
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.dbBackup"))
- t.sendBackup(chatId)
- case "get_banlogs":
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.getBanLogs"))
- t.sendBanLogs(chatId, true)
- case "client_traffic":
- tgUserID := callbackQuery.From.ID
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.clientUsage"))
- t.getClientUsage(chatId, tgUserID)
- case "client_commands":
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.commands"))
- t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.commands.helpClientCommands"))
- case "client_sub_links":
- // show user's own clients to choose one for sub links
- tgUserID := callbackQuery.From.ID
- traffics, err := t.inboundService.GetClientTrafficTgBot(tgUserID)
- if err != nil {
- // fallback to message
- t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.errorOperation")+"\r\n"+err.Error())
- return
- }
- if len(traffics) == 0 {
- t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.askToAddUserId", "TgUserID=="+strconv.FormatInt(tgUserID, 10)))
- return
- }
- var buttons []telego.InlineKeyboardButton
- for _, tr := range traffics {
- buttons = append(buttons, tu.InlineKeyboardButton(tr.Email).WithCallbackData(t.encodeQuery("client_sub_links "+tr.Email)))
- }
- cols := 1
- if len(buttons) >= 6 {
- cols = 2
- }
- keyboard := tu.InlineKeyboardGrid(tu.InlineKeyboardCols(cols, buttons...))
- t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.commands.pleaseChoose"), keyboard)
- case "client_individual_links":
- // show user's clients to choose for individual links
- tgUserID := callbackQuery.From.ID
- traffics, err := t.inboundService.GetClientTrafficTgBot(tgUserID)
- if err != nil {
- t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.errorOperation")+"\r\n"+err.Error())
- return
- }
- if len(traffics) == 0 {
- t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.askToAddUserId", "TgUserID=="+strconv.FormatInt(tgUserID, 10)))
- return
- }
- var buttons2 []telego.InlineKeyboardButton
- for _, tr := range traffics {
- buttons2 = append(buttons2, tu.InlineKeyboardButton(tr.Email).WithCallbackData(t.encodeQuery("client_individual_links "+tr.Email)))
- }
- cols2 := 1
- if len(buttons2) >= 6 {
- cols2 = 2
- }
- keyboard2 := tu.InlineKeyboardGrid(tu.InlineKeyboardCols(cols2, buttons2...))
- t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.commands.pleaseChoose"), keyboard2)
- case "client_qr_links":
- // show user's clients to choose for QR codes
- tgUserID := callbackQuery.From.ID
- traffics, err := t.inboundService.GetClientTrafficTgBot(tgUserID)
- if err != nil {
- t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.errorOccurred")+"\r\n"+err.Error())
- return
- }
- if len(traffics) == 0 {
- t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.askToAddUserId", "TgUserID=="+strconv.FormatInt(tgUserID, 10)))
- return
- }
- var buttons3 []telego.InlineKeyboardButton
- for _, tr := range traffics {
- buttons3 = append(buttons3, tu.InlineKeyboardButton(tr.Email).WithCallbackData(t.encodeQuery("client_qr_links "+tr.Email)))
- }
- cols3 := 1
- if len(buttons3) >= 6 {
- cols3 = 2
- }
- keyboard3 := tu.InlineKeyboardGrid(tu.InlineKeyboardCols(cols3, buttons3...))
- t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.commands.pleaseChoose"), keyboard3)
- case "onlines":
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.onlines"))
- t.onlineClients(chatId)
- case "onlines_refresh":
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))
- t.onlineClients(chatId, callbackQuery.Message.GetMessageID())
- case "commands":
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.commands"))
- t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.commands.helpAdminCommands"))
- case "add_client":
- client_Email = t.randomLowerAndNum(8)
- client_LimitIP = 0
- client_TotalGB = 0
- client_ExpiryTime = 0
- client_Enable = true
- client_TgID = ""
- client_SubID = t.randomLowerAndNum(16)
- client_Comment = ""
- client_Reset = 0
- inbounds, err := t.getInboundsAddClient()
- if err != nil {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
- return
- }
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.addClient"))
- t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.chooseInbound"), inbounds)
- case "add_client_ch_default_email":
- t.deleteMessageTgBot(chatId, callbackQuery.Message.GetMessageID())
- userStateMgr.set(chatId, "awaiting_email")
- cancel_btn_markup := tu.InlineKeyboard(
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.use_default")).WithCallbackData("add_client_default_info"),
- ),
- )
- prompt_message := t.I18nBot("tgbot.messages.email_prompt", "ClientEmail=="+client_Email)
- t.SendMsgToTgbot(chatId, prompt_message, cancel_btn_markup)
- case "add_client_ch_default_comment":
- t.deleteMessageTgBot(chatId, callbackQuery.Message.GetMessageID())
- userStateMgr.set(chatId, "awaiting_comment")
- cancel_btn_markup := tu.InlineKeyboard(
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.use_default")).WithCallbackData("add_client_default_info"),
- ),
- )
- prompt_message := t.I18nBot("tgbot.messages.comment_prompt", "ClientComment=="+client_Comment)
- t.SendMsgToTgbot(chatId, prompt_message, cancel_btn_markup)
- case "add_client_ch_default_tg_id":
- t.deleteMessageTgBot(chatId, callbackQuery.Message.GetMessageID())
- userStateMgr.set(chatId, "awaiting_tg_id")
- cancel_btn_markup := tu.InlineKeyboard(
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.use_default")).WithCallbackData("add_client_default_info"),
- ),
- )
- current := client_TgID
- if current == "" {
- current = "—"
- }
- t.SendMsgToTgbot(chatId, fmt.Sprintf("Send the Telegram user id (numeric) to attach to this client, or send `-` / `none` to clear.\nCurrent: `%s`", current), cancel_btn_markup)
- case "add_client_ch_default_traffic":
- inlineKeyboard := tu.InlineKeyboard(
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancel")).WithCallbackData(t.encodeQuery("add_client_default_traffic_exp")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.unlimited")).WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 0")),
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.custom")).WithCallbackData(t.encodeQuery("add_client_limit_traffic_in 0")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("1 GB").WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 1")),
- tu.InlineKeyboardButton("5 GB").WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 5")),
- tu.InlineKeyboardButton("10 GB").WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 10")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("20 GB").WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 20")),
- tu.InlineKeyboardButton("30 GB").WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 30")),
- tu.InlineKeyboardButton("40 GB").WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 40")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("50 GB").WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 50")),
- tu.InlineKeyboardButton("60 GB").WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 60")),
- tu.InlineKeyboardButton("80 GB").WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 80")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton("100 GB").WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 100")),
- tu.InlineKeyboardButton("150 GB").WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 150")),
- tu.InlineKeyboardButton("200 GB").WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 200")),
- ),
- )
- t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
- case "add_client_ch_default_exp":
- inlineKeyboard := tu.InlineKeyboard(
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancel")).WithCallbackData(t.encodeQuery("add_client_default_traffic_exp")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.unlimited")).WithCallbackData(t.encodeQuery("add_client_reset_exp_c 0")),
- tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.custom")).WithCallbackData(t.encodeQuery("add_client_reset_exp_in 0")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 7 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("add_client_reset_exp_c 7")),
- tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 10 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("add_client_reset_exp_c 10")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 14 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("add_client_reset_exp_c 14")),
- tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 20 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("add_client_reset_exp_c 20")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 1 "+t.I18nBot("tgbot.month")).WithCallbackData(t.encodeQuery("add_client_reset_exp_c 30")),
- tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 3 "+t.I18nBot("tgbot.months")).WithCallbackData(t.encodeQuery("add_client_reset_exp_c 90")),
- ),
- tu.InlineKeyboardRow(
- tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 6 "+t.I18nBot("tgbot.months")).WithCallbackData(t.encodeQuery("add_client_reset_exp_c 180")),
- tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 12 "+t.I18nBot("tgbot.months")).WithCallbackData(t.encodeQuery("add_client_reset_exp_c 365")),
- ),
- )
- 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())
- userStateMgr.clear(chatId)
- t.addClient(chatId, t.BuildClientDraftMessage())
- case "add_client_cancel":
- userStateMgr.clear(chatId)
- receiver_inbound_ID = 0
- receiver_inbound_IDs = nil
- t.deleteMessageTgBot(chatId, callbackQuery.Message.GetMessageID())
- t.SendMsgToTgbotDeleteAfter(chatId, t.I18nBot("tgbot.messages.cancel"), 3, tu.ReplyKeyboardRemove())
- case "add_client_default_traffic_exp":
- messageId := callbackQuery.Message.GetMessageID()
- message_text := t.BuildClientDraftMessage()
- 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()
- message_text := t.BuildClientDraftMessage()
- t.addClient(chatId, message_text, messageId)
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.canceled", "Email=="+client_Email))
- case "add_client_attach_more":
- picker, err := t.getInboundsAttachPicker()
- if err != nil {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
- return
- }
- t.SendMsgToTgbot(chatId, "Pick inbound(s) to attach:", picker)
- case "add_client_attach_done":
- if receiver_inbound_ID == 0 && len(receiver_inbound_IDs) > 0 {
- receiver_inbound_ID = receiver_inbound_IDs[0]
- }
- if receiver_inbound_ID == 0 {
- t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.getInboundsFailed"))
- return
- }
- message_text := t.BuildClientDraftMessage()
- t.deleteMessageTgBot(chatId, callbackQuery.Message.GetMessageID())
- t.addClient(chatId, message_text)
- case "add_client_submit_disable":
- client_Enable = false
- _, err := t.SubmitAddClient()
- if err != nil {
- errorMessage := fmt.Sprintf("%v", err)
- t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.messages.error_add_client", "error=="+errorMessage), tu.ReplyKeyboardRemove())
- } else {
- t.deleteMessageTgBot(chatId, callbackQuery.Message.GetMessageID())
- t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.successfulOperation"), tu.ReplyKeyboardRemove())
- t.sendClientIndividualLinks(chatId, client_Email)
- t.sendClientQRLinks(chatId, client_Email)
- receiver_inbound_ID = 0
- receiver_inbound_IDs = nil
- }
- case "add_client_submit_enable":
- client_Enable = true
- _, err := t.SubmitAddClient()
- if err != nil {
- errorMessage := fmt.Sprintf("%v", err)
- t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.messages.error_add_client", "error=="+errorMessage), tu.ReplyKeyboardRemove())
- } else {
- t.deleteMessageTgBot(chatId, callbackQuery.Message.GetMessageID())
- t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.successfulOperation"), tu.ReplyKeyboardRemove())
- t.sendClientIndividualLinks(chatId, client_Email)
- t.sendClientQRLinks(chatId, client_Email)
- receiver_inbound_ID = 0
- receiver_inbound_IDs = nil
- }
- 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)
- if err != nil {
- t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.errorOperation"), tu.ReplyKeyboardRemove())
- return
- }
- 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())
- }
- default:
- if after, ok := strings.CutPrefix(callbackQuery.Data, "client_sub_links "); ok {
- email := after
- t.sendClientSubLinks(chatId, email)
- return
- }
- if after, ok := strings.CutPrefix(callbackQuery.Data, "client_individual_links "); ok {
- email := after
- t.sendClientIndividualLinks(chatId, email)
- return
- }
- if after, ok := strings.CutPrefix(callbackQuery.Data, "client_qr_links "); ok {
- email := after
- t.sendClientQRLinks(chatId, email)
- return
- }
- }
- }
- // checkAdmin checks if the given Telegram ID is an admin.
- func checkAdmin(tgId int64) bool {
- return slices.Contains(adminIds, tgId)
- }
- // isClientSelfCallback reports whether a callback is one of the per-user client
- // actions that resolve their own data from the caller's Telegram id, and so are
- // safe to run for a non-admin. Every other callback is admin-only (default-deny).
- func isClientSelfCallback(data string) bool {
- switch data {
- case "client_traffic", "client_commands", "client_sub_links",
- "client_individual_links", "client_qr_links":
- return true
- }
- return strings.HasPrefix(data, "client_sub_links ") ||
- strings.HasPrefix(data, "client_individual_links ") ||
- strings.HasPrefix(data, "client_qr_links ")
- }
|