1
0

tgbot_router.go 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340
  1. package tgbot
  2. import (
  3. "context"
  4. "fmt"
  5. "html"
  6. "slices"
  7. "strconv"
  8. "strings"
  9. "time"
  10. "github.com/mhsanaei/3x-ui/v3/internal/logger"
  11. "github.com/mymmrac/telego"
  12. th "github.com/mymmrac/telego/telegohandler"
  13. tu "github.com/mymmrac/telego/telegoutil"
  14. )
  15. // recoverBotPanic must be deferred by every bot handler entry point: telego's
  16. // dispatch has no recovery of its own, so one bad update would kill the panel.
  17. func recoverBotPanic() {
  18. if r := recover(); r != nil {
  19. logger.Error("Recovered panic in Telegram bot handler:", r)
  20. }
  21. }
  22. // runBotHandler runs a bot handler on a worker slot and recovers panics: a bad
  23. // callback must not take down the whole panel, the way a cron panic would not.
  24. func runBotHandler(fn func()) {
  25. messageWorkerPool <- struct{}{}
  26. defer func() { <-messageWorkerPool }()
  27. defer recoverBotPanic()
  28. fn()
  29. }
  30. // chooseInboundClient fetches the inbound once and reuses the row: the inline
  31. // keyboard outlives the inbound, so a stale tap must answer an error, not panic.
  32. func (t *Tgbot) chooseInboundClient(callbackQuery *telego.CallbackQuery, chatId int64, inboundID int, action string) {
  33. inbound, err := t.inboundService.GetInbound(inboundID)
  34. if err != nil {
  35. logger.Warning("chooseInboundClient GetInbound failed:", err)
  36. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.getInboundsFailed"))
  37. return
  38. }
  39. clientsKB, err := t.getInboundClientsFor(inbound, action)
  40. if err != nil {
  41. t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
  42. return
  43. }
  44. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.chooseClient", "Inbound=="+inbound.Remark), clientsKB)
  45. }
  46. // OnReceive starts the message receiving loop for the Telegram bot.
  47. func (t *Tgbot) OnReceive() {
  48. params := telego.GetUpdatesParams{
  49. Timeout: 20, // Reduced timeout to detect connection issues faster
  50. }
  51. // Strict singleton: never start a second long-polling loop.
  52. tgBotMutex.Lock()
  53. if botCancel != nil || isRunning {
  54. tgBotMutex.Unlock()
  55. logger.Warning("TgBot OnReceive called while already running; ignoring.")
  56. return
  57. }
  58. ctx, cancel := context.WithCancel(context.Background())
  59. botCancel = cancel
  60. isRunning = true
  61. // Add to WaitGroup before releasing the lock so StopBot() can't return
  62. // before this receiver goroutine is accounted for.
  63. botWG.Add(1)
  64. tgBotMutex.Unlock()
  65. // Get updates channel using the context with shorter timeout for better error recovery
  66. updates, _ := bot.UpdatesViaLongPolling(ctx, &params)
  67. go func() {
  68. defer botWG.Done()
  69. h, _ := th.NewBotHandler(bot, updates)
  70. tgBotMutex.Lock()
  71. botHandler = h
  72. tgBotMutex.Unlock()
  73. h.HandleMessage(func(ctx *th.Context, message telego.Message) error {
  74. defer recoverBotPanic()
  75. userStateMgr.clear(message.Chat.ID)
  76. t.SendMsgToTgbot(message.Chat.ID, t.I18nBot("tgbot.keyboardClosed"), tu.ReplyKeyboardRemove())
  77. return nil
  78. }, th.TextEqual(t.I18nBot("tgbot.buttons.closeKeyboard")))
  79. h.HandleMessage(func(ctx *th.Context, message telego.Message) error {
  80. defer recoverBotPanic()
  81. if !t.isCommandForCurrentBot(&message) {
  82. return nil
  83. }
  84. // Use goroutine with worker pool for concurrent command processing
  85. go runBotHandler(func() {
  86. userStateMgr.clear(message.Chat.ID)
  87. t.answerCommand(&message, message.Chat.ID, checkAdmin(message.From.ID))
  88. })
  89. return nil
  90. }, th.AnyCommand())
  91. h.HandleCallbackQuery(func(ctx *th.Context, query telego.CallbackQuery) error {
  92. // Use goroutine with worker pool for concurrent callback processing
  93. go runBotHandler(func() {
  94. userStateMgr.clear(query.Message.GetChat().ID)
  95. t.answerCallback(&query, checkAdmin(query.From.ID))
  96. })
  97. return nil
  98. }, th.AnyCallbackQueryWithMessage())
  99. h.HandleMessage(func(ctx *th.Context, message telego.Message) error {
  100. defer recoverBotPanic()
  101. userStateMgr.maybePrune(time.Hour)
  102. if userState, exists := userStateMgr.get(message.Chat.ID); exists {
  103. switch userState {
  104. case "awaiting_email":
  105. if client_Email == strings.TrimSpace(message.Text) {
  106. t.SendMsgToTgbotDeleteAfter(message.Chat.ID, t.I18nBot("tgbot.messages.using_default_value"), 3, tu.ReplyKeyboardRemove())
  107. userStateMgr.clear(message.Chat.ID)
  108. return nil
  109. }
  110. client_Email = strings.TrimSpace(message.Text)
  111. if t.isSingleWord(client_Email) {
  112. userStateMgr.set(message.Chat.ID, "awaiting_email")
  113. cancel_btn_markup := tu.InlineKeyboard(
  114. tu.InlineKeyboardRow(
  115. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.use_default")).WithCallbackData("add_client_default_info"),
  116. ),
  117. )
  118. t.SendMsgToTgbot(message.Chat.ID, t.I18nBot("tgbot.messages.incorrect_input"), cancel_btn_markup)
  119. } else {
  120. t.SendMsgToTgbotDeleteAfter(message.Chat.ID, t.I18nBot("tgbot.messages.received_email"), 3, tu.ReplyKeyboardRemove())
  121. userStateMgr.clear(message.Chat.ID)
  122. t.addClient(message.Chat.ID, t.BuildClientDraftMessage())
  123. }
  124. case "awaiting_comment":
  125. if client_Comment == strings.TrimSpace(message.Text) {
  126. t.SendMsgToTgbotDeleteAfter(message.Chat.ID, t.I18nBot("tgbot.messages.using_default_value"), 3, tu.ReplyKeyboardRemove())
  127. userStateMgr.clear(message.Chat.ID)
  128. return nil
  129. }
  130. client_Comment = strings.TrimSpace(message.Text)
  131. t.SendMsgToTgbotDeleteAfter(message.Chat.ID, t.I18nBot("tgbot.messages.received_comment"), 3, tu.ReplyKeyboardRemove())
  132. userStateMgr.clear(message.Chat.ID)
  133. t.addClient(message.Chat.ID, t.BuildClientDraftMessage())
  134. case "awaiting_tg_id":
  135. input := strings.TrimSpace(message.Text)
  136. if input == "" || input == "-" || strings.EqualFold(input, "none") {
  137. client_TgID = ""
  138. t.SendMsgToTgbotDeleteAfter(message.Chat.ID, t.I18nBot("tgbot.messages.using_default_value"), 3, tu.ReplyKeyboardRemove())
  139. userStateMgr.clear(message.Chat.ID)
  140. t.addClient(message.Chat.ID, t.BuildClientDraftMessage())
  141. return nil
  142. }
  143. if _, err := strconv.ParseInt(input, 10, 64); err != nil {
  144. cancel_btn_markup := tu.InlineKeyboard(
  145. tu.InlineKeyboardRow(
  146. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.use_default")).WithCallbackData("add_client_default_info"),
  147. ),
  148. )
  149. t.SendMsgToTgbot(message.Chat.ID, t.I18nBot("tgbot.messages.incorrect_input"), cancel_btn_markup)
  150. return nil
  151. }
  152. client_TgID = input
  153. t.SendMsgToTgbotDeleteAfter(message.Chat.ID, t.I18nBot("tgbot.messages.userSaved"), 3, tu.ReplyKeyboardRemove())
  154. userStateMgr.clear(message.Chat.ID)
  155. t.addClient(message.Chat.ID, t.BuildClientDraftMessage())
  156. }
  157. } else {
  158. if message.UsersShared != nil {
  159. if checkAdmin(message.From.ID) {
  160. for _, sharedUser := range message.UsersShared.Users {
  161. userID := sharedUser.UserID
  162. needRestart, err := t.clientService.SetClientTelegramUserID(&t.inboundService, message.UsersShared.RequestID, userID)
  163. if needRestart {
  164. t.xrayService.SetToNeedRestart()
  165. }
  166. output := ""
  167. if err != nil {
  168. output += t.I18nBot("tgbot.messages.selectUserFailed")
  169. } else {
  170. output += t.I18nBot("tgbot.messages.userSaved")
  171. }
  172. t.SendMsgToTgbot(message.Chat.ID, output, tu.ReplyKeyboardRemove())
  173. }
  174. } else {
  175. t.SendMsgToTgbot(message.Chat.ID, t.I18nBot("tgbot.noResult"), tu.ReplyKeyboardRemove())
  176. }
  177. }
  178. }
  179. return nil
  180. }, th.AnyMessage())
  181. _ = h.Start()
  182. }()
  183. }
  184. // answerCommand processes incoming command messages from Telegram users.
  185. func (t *Tgbot) answerCommand(message *telego.Message, chatId int64, isAdmin bool) {
  186. msg, onlyMessage := "", false
  187. command, _, commandArgs := tu.ParseCommand(message.Text)
  188. // Helper function to handle unknown commands.
  189. handleUnknownCommand := func() {
  190. msg += t.I18nBot("tgbot.commands.unknown")
  191. }
  192. // Handle the command.
  193. switch command {
  194. case "help":
  195. msg += t.I18nBot("tgbot.commands.help")
  196. msg += t.I18nBot("tgbot.commands.pleaseChoose")
  197. case "start":
  198. msg += t.I18nBot("tgbot.commands.start", "Firstname=="+html.EscapeString(message.From.FirstName))
  199. if isAdmin {
  200. msg += t.I18nBot("tgbot.commands.welcome", "Hostname=="+hostname)
  201. }
  202. msg += "\n\n" + t.I18nBot("tgbot.commands.pleaseChoose")
  203. case "status":
  204. onlyMessage = true
  205. msg += t.I18nBot("tgbot.commands.status")
  206. case "id":
  207. onlyMessage = true
  208. msg += t.I18nBot("tgbot.commands.getID", "ID=="+strconv.FormatInt(message.From.ID, 10))
  209. case "usage":
  210. onlyMessage = true
  211. if len(commandArgs) > 0 {
  212. if isAdmin {
  213. t.searchClient(chatId, commandArgs[0])
  214. } else {
  215. t.getClientUsage(chatId, message.From.ID, commandArgs[0])
  216. }
  217. } else {
  218. msg += t.I18nBot("tgbot.commands.usage")
  219. }
  220. case "inbound":
  221. onlyMessage = true
  222. if isAdmin && len(commandArgs) > 0 {
  223. t.searchInbound(chatId, commandArgs[0])
  224. } else {
  225. handleUnknownCommand()
  226. }
  227. case "restart":
  228. onlyMessage = true
  229. if isAdmin {
  230. if len(commandArgs) == 0 {
  231. if t.xrayService.IsXrayRunning() {
  232. err := t.xrayService.RestartXray(true)
  233. if err != nil {
  234. msg += t.I18nBot("tgbot.commands.restartFailed", "Error=="+err.Error())
  235. } else {
  236. msg += t.I18nBot("tgbot.commands.restartSuccess")
  237. }
  238. } else {
  239. msg += t.I18nBot("tgbot.commands.xrayNotRunning")
  240. }
  241. } else {
  242. handleUnknownCommand()
  243. msg += t.I18nBot("tgbot.commands.restartUsage")
  244. }
  245. } else {
  246. handleUnknownCommand()
  247. }
  248. case "clearall":
  249. onlyMessage = true
  250. if isAdmin {
  251. inlineKeyboard := tu.InlineKeyboard(
  252. tu.InlineKeyboardRow(
  253. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancelReset")).WithCallbackData(t.encodeQuery("reset_all_traffics_cancel")),
  254. ),
  255. tu.InlineKeyboardRow(
  256. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmResetTraffic")).WithCallbackData(t.encodeQuery("reset_all_traffics_c")),
  257. ),
  258. )
  259. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.messages.AreYouSure"), inlineKeyboard)
  260. } else {
  261. handleUnknownCommand()
  262. }
  263. default:
  264. handleUnknownCommand()
  265. }
  266. if msg != "" {
  267. t.sendResponse(chatId, msg, onlyMessage, isAdmin)
  268. }
  269. }
  270. func (t *Tgbot) isCommandForCurrentBot(message *telego.Message) bool {
  271. return isCommandForBot(message.Text, botUsername())
  272. }
  273. func botUsername() string {
  274. if bot == nil {
  275. return ""
  276. }
  277. return bot.Username()
  278. }
  279. func isCommandForBot(text string, username string) bool {
  280. _, commandUsername, _ := tu.ParseCommand(text)
  281. return commandUsername == "" || username == "" || strings.EqualFold(commandUsername, username)
  282. }
  283. // answerCallback processes callback queries from inline keyboards.
  284. func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool) {
  285. chatId := callbackQuery.Message.GetChat().ID
  286. if isAdmin {
  287. // get query from hash storage
  288. decodedQuery, err := t.decodeQuery(callbackQuery.Data)
  289. if err != nil {
  290. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.noQuery"))
  291. return
  292. }
  293. dataArray := strings.Split(decodedQuery, " ")
  294. if len(dataArray) >= 2 && len(dataArray[1]) > 0 {
  295. email := dataArray[1]
  296. switch dataArray[0] {
  297. case "get_clients_for_sub":
  298. inboundIdInt, err := strconv.Atoi(dataArray[1])
  299. if err != nil {
  300. t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
  301. return
  302. }
  303. t.chooseInboundClient(callbackQuery, chatId, inboundIdInt, "client_sub_links")
  304. case "get_clients_for_individual":
  305. inboundIdInt, err := strconv.Atoi(dataArray[1])
  306. if err != nil {
  307. t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
  308. return
  309. }
  310. t.chooseInboundClient(callbackQuery, chatId, inboundIdInt, "client_individual_links")
  311. case "get_clients_for_qr":
  312. inboundIdInt, err := strconv.Atoi(dataArray[1])
  313. if err != nil {
  314. t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
  315. return
  316. }
  317. t.chooseInboundClient(callbackQuery, chatId, inboundIdInt, "client_qr_links")
  318. case "client_sub_links":
  319. t.sendClientSubLinks(chatId, email)
  320. return
  321. case "client_individual_links":
  322. t.sendClientIndividualLinks(chatId, email)
  323. return
  324. case "client_qr_links":
  325. t.sendClientQRLinks(chatId, email)
  326. return
  327. case "client_get_usage":
  328. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.messages.email", "Email=="+email))
  329. t.searchClient(chatId, email)
  330. case "client_refresh":
  331. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.clientRefreshSuccess", "Email=="+email))
  332. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  333. case "client_cancel":
  334. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.canceled", "Email=="+email))
  335. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  336. case "ips_refresh":
  337. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.IpRefreshSuccess", "Email=="+email))
  338. t.searchClientIps(chatId, email, callbackQuery.Message.GetMessageID())
  339. case "ips_cancel":
  340. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.canceled", "Email=="+email))
  341. t.searchClientIps(chatId, email, callbackQuery.Message.GetMessageID())
  342. case "tgid_refresh":
  343. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.TGIdRefreshSuccess", "Email=="+email))
  344. t.clientTelegramUserInfo(chatId, email, callbackQuery.Message.GetMessageID())
  345. case "tgid_cancel":
  346. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.canceled", "Email=="+email))
  347. t.clientTelegramUserInfo(chatId, email, callbackQuery.Message.GetMessageID())
  348. case "reset_traffic":
  349. inlineKeyboard := tu.InlineKeyboard(
  350. tu.InlineKeyboardRow(
  351. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancelReset")).WithCallbackData(t.encodeQuery("client_cancel "+email)),
  352. ),
  353. tu.InlineKeyboardRow(
  354. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmResetTraffic")).WithCallbackData(t.encodeQuery("reset_traffic_c "+email)),
  355. ),
  356. )
  357. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  358. case "reset_traffic_c":
  359. err := t.inboundService.ResetClientTrafficByEmail(email)
  360. if err == nil {
  361. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.resetTrafficSuccess", "Email=="+email))
  362. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  363. } else {
  364. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  365. }
  366. case "limit_traffic":
  367. inlineKeyboard := tu.InlineKeyboard(
  368. tu.InlineKeyboardRow(
  369. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancel")).WithCallbackData(t.encodeQuery("client_cancel "+email)),
  370. ),
  371. tu.InlineKeyboardRow(
  372. tu.InlineKeyboardButton(t.I18nBot("tgbot.unlimited")).WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 0")),
  373. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.custom")).WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" 0")),
  374. ),
  375. tu.InlineKeyboardRow(
  376. tu.InlineKeyboardButton("1 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 1")),
  377. tu.InlineKeyboardButton("5 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 5")),
  378. tu.InlineKeyboardButton("10 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 10")),
  379. ),
  380. tu.InlineKeyboardRow(
  381. tu.InlineKeyboardButton("20 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 20")),
  382. tu.InlineKeyboardButton("30 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 30")),
  383. tu.InlineKeyboardButton("40 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 40")),
  384. ),
  385. tu.InlineKeyboardRow(
  386. tu.InlineKeyboardButton("50 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 50")),
  387. tu.InlineKeyboardButton("60 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 60")),
  388. tu.InlineKeyboardButton("80 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 80")),
  389. ),
  390. tu.InlineKeyboardRow(
  391. tu.InlineKeyboardButton("100 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 100")),
  392. tu.InlineKeyboardButton("150 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 150")),
  393. tu.InlineKeyboardButton("200 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 200")),
  394. ),
  395. )
  396. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  397. case "limit_traffic_c":
  398. if len(dataArray) == 3 {
  399. limitTraffic, err := strconv.Atoi(dataArray[2])
  400. if err == nil {
  401. needRestart, err := t.clientService.ResetClientTrafficLimitByEmail(&t.inboundService, email, limitTraffic)
  402. if needRestart {
  403. t.xrayService.SetToNeedRestart()
  404. }
  405. if err == nil {
  406. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.setTrafficLimitSuccess", "Email=="+email))
  407. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  408. return
  409. }
  410. }
  411. }
  412. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  413. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  414. case "limit_traffic_in":
  415. if len(dataArray) >= 3 {
  416. oldInputNumber, err := strconv.Atoi(dataArray[2])
  417. inputNumber := oldInputNumber
  418. if err == nil {
  419. if len(dataArray) == 4 {
  420. num, err := strconv.Atoi(dataArray[3])
  421. if err == nil {
  422. inputNumber = updateNumericInput(inputNumber, num)
  423. }
  424. if inputNumber == oldInputNumber {
  425. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))
  426. return
  427. }
  428. if inputNumber >= 999999 {
  429. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  430. return
  431. }
  432. }
  433. inlineKeyboard := t.numericKeypad(numericKeypadSpec{dataBase: "limit_traffic", dataArgs: email + " ", cancelData: "client_cancel " + email, confirmLabelKey: "tgbot.buttons.confirmNumberAdd"}, inputNumber)
  434. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  435. return
  436. }
  437. }
  438. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  439. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  440. case "add_client_limit_traffic_c":
  441. limitTraffic, _ := strconv.ParseInt(dataArray[1], 10, 64)
  442. client_TotalGB = limitTraffic * 1024 * 1024 * 1024
  443. messageId := callbackQuery.Message.GetMessageID()
  444. message_text := t.BuildClientDraftMessage()
  445. t.addClient(callbackQuery.Message.GetChat().ID, message_text, messageId)
  446. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))
  447. case "add_client_limit_traffic_in":
  448. if len(dataArray) >= 2 {
  449. oldInputNumber, err := strconv.Atoi(dataArray[1])
  450. inputNumber := oldInputNumber
  451. if err == nil {
  452. if len(dataArray) == 3 {
  453. num, err := strconv.Atoi(dataArray[2])
  454. if err == nil {
  455. inputNumber = updateNumericInput(inputNumber, num)
  456. }
  457. if inputNumber == oldInputNumber {
  458. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))
  459. return
  460. }
  461. if inputNumber >= 999999 {
  462. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  463. return
  464. }
  465. }
  466. inlineKeyboard := t.numericKeypad(numericKeypadSpec{dataBase: "add_client_limit_traffic", cancelData: "add_client_default_traffic_exp", confirmLabelKey: "tgbot.buttons.confirmNumberAdd"}, inputNumber)
  467. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  468. return
  469. }
  470. }
  471. case "reset_exp":
  472. inlineKeyboard := tu.InlineKeyboard(
  473. tu.InlineKeyboardRow(
  474. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancelReset")).WithCallbackData(t.encodeQuery("client_cancel "+email)),
  475. ),
  476. tu.InlineKeyboardRow(
  477. tu.InlineKeyboardButton(t.I18nBot("tgbot.unlimited")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 0")),
  478. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.custom")).WithCallbackData(t.encodeQuery("reset_exp_in "+email+" 0")),
  479. ),
  480. tu.InlineKeyboardRow(
  481. tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 7 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 7")),
  482. tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 10 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 10")),
  483. ),
  484. tu.InlineKeyboardRow(
  485. tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 14 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 14")),
  486. tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 20 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 20")),
  487. ),
  488. tu.InlineKeyboardRow(
  489. tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 1 "+t.I18nBot("tgbot.month")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 30")),
  490. tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 3 "+t.I18nBot("tgbot.months")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 90")),
  491. ),
  492. tu.InlineKeyboardRow(
  493. tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 6 "+t.I18nBot("tgbot.months")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 180")),
  494. tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 12 "+t.I18nBot("tgbot.months")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 365")),
  495. ),
  496. )
  497. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  498. case "reset_exp_c":
  499. if len(dataArray) == 3 {
  500. days, err := strconv.ParseInt(dataArray[2], 10, 64)
  501. if err == nil {
  502. var date int64
  503. if days > 0 {
  504. traffic, err := t.inboundService.GetClientTrafficByEmail(email)
  505. if err != nil {
  506. logger.Warning(err)
  507. msg := t.I18nBot("tgbot.wentWrong")
  508. t.SendMsgToTgbot(chatId, msg)
  509. return
  510. }
  511. if traffic == nil {
  512. msg := t.I18nBot("tgbot.noResult")
  513. t.SendMsgToTgbot(chatId, msg)
  514. return
  515. }
  516. if traffic.ExpiryTime > 0 {
  517. if traffic.ExpiryTime-time.Now().Unix()*1000 < 0 {
  518. date = -(days * 24 * 60 * 60000)
  519. } else {
  520. date = traffic.ExpiryTime + days*24*60*60000
  521. }
  522. } else {
  523. date = traffic.ExpiryTime - days*24*60*60000
  524. }
  525. }
  526. needRestart, err := t.clientService.ResetClientExpiryTimeByEmail(&t.inboundService, email, date)
  527. if needRestart {
  528. t.xrayService.SetToNeedRestart()
  529. }
  530. if err == nil {
  531. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.expireResetSuccess", "Email=="+email))
  532. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  533. return
  534. }
  535. }
  536. }
  537. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  538. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  539. case "reset_exp_in":
  540. if len(dataArray) >= 3 {
  541. oldInputNumber, err := strconv.Atoi(dataArray[2])
  542. inputNumber := oldInputNumber
  543. if err == nil {
  544. if len(dataArray) == 4 {
  545. num, err := strconv.Atoi(dataArray[3])
  546. if err == nil {
  547. inputNumber = updateNumericInput(inputNumber, num)
  548. }
  549. if inputNumber == oldInputNumber {
  550. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))
  551. return
  552. }
  553. if inputNumber >= 999999 {
  554. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  555. return
  556. }
  557. }
  558. inlineKeyboard := t.numericKeypad(numericKeypadSpec{dataBase: "reset_exp", dataArgs: email + " ", cancelData: "client_cancel " + email, confirmLabelKey: "tgbot.buttons.confirmNumber"}, inputNumber)
  559. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  560. return
  561. }
  562. }
  563. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  564. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  565. case "add_client_reset_exp_c":
  566. client_ExpiryTime = 0
  567. days, _ := strconv.ParseInt(dataArray[1], 10, 64)
  568. var date int64
  569. if client_ExpiryTime > 0 {
  570. if client_ExpiryTime-time.Now().Unix()*1000 < 0 {
  571. date = -(days * 24 * 60 * 60000)
  572. } else {
  573. date = client_ExpiryTime + days*24*60*60000
  574. }
  575. } else {
  576. date = client_ExpiryTime - days*24*60*60000
  577. }
  578. client_ExpiryTime = date
  579. messageId := callbackQuery.Message.GetMessageID()
  580. message_text := t.BuildClientDraftMessage()
  581. t.addClient(callbackQuery.Message.GetChat().ID, message_text, messageId)
  582. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))
  583. case "add_client_reset_exp_in":
  584. if len(dataArray) >= 2 {
  585. oldInputNumber, err := strconv.Atoi(dataArray[1])
  586. inputNumber := oldInputNumber
  587. if err == nil {
  588. if len(dataArray) == 3 {
  589. num, err := strconv.Atoi(dataArray[2])
  590. if err == nil {
  591. inputNumber = updateNumericInput(inputNumber, num)
  592. }
  593. if inputNumber == oldInputNumber {
  594. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))
  595. return
  596. }
  597. if inputNumber >= 999999 {
  598. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  599. return
  600. }
  601. }
  602. inlineKeyboard := t.numericKeypad(numericKeypadSpec{dataBase: "add_client_reset_exp", cancelData: "add_client_default_traffic_exp", confirmLabelKey: "tgbot.buttons.confirmNumberAdd"}, inputNumber)
  603. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  604. return
  605. }
  606. }
  607. case "ip_limit":
  608. inlineKeyboard := tu.InlineKeyboard(
  609. tu.InlineKeyboardRow(
  610. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancelIpLimit")).WithCallbackData(t.encodeQuery("client_cancel "+email)),
  611. ),
  612. tu.InlineKeyboardRow(
  613. tu.InlineKeyboardButton(t.I18nBot("tgbot.unlimited")).WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 0")),
  614. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.custom")).WithCallbackData(t.encodeQuery("ip_limit_in "+email+" 0")),
  615. ),
  616. tu.InlineKeyboardRow(
  617. tu.InlineKeyboardButton("1").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 1")),
  618. tu.InlineKeyboardButton("2").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 2")),
  619. ),
  620. tu.InlineKeyboardRow(
  621. tu.InlineKeyboardButton("3").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 3")),
  622. tu.InlineKeyboardButton("4").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 4")),
  623. ),
  624. tu.InlineKeyboardRow(
  625. tu.InlineKeyboardButton("5").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 5")),
  626. tu.InlineKeyboardButton("6").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 6")),
  627. tu.InlineKeyboardButton("7").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 7")),
  628. ),
  629. tu.InlineKeyboardRow(
  630. tu.InlineKeyboardButton("8").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 8")),
  631. tu.InlineKeyboardButton("9").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 9")),
  632. tu.InlineKeyboardButton("10").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 10")),
  633. ),
  634. )
  635. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  636. case "ip_limit_c":
  637. if len(dataArray) == 3 {
  638. count, err := strconv.Atoi(dataArray[2])
  639. if err == nil {
  640. needRestart, err := t.clientService.ResetClientIpLimitByEmail(&t.inboundService, email, count)
  641. if needRestart {
  642. t.xrayService.SetToNeedRestart()
  643. }
  644. if err == nil {
  645. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.resetIpSuccess", "Email=="+email, "Count=="+strconv.Itoa(count)))
  646. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  647. return
  648. }
  649. }
  650. }
  651. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  652. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  653. case "ip_limit_in":
  654. if len(dataArray) >= 3 {
  655. oldInputNumber, err := strconv.Atoi(dataArray[2])
  656. inputNumber := oldInputNumber
  657. if err == nil {
  658. if len(dataArray) == 4 {
  659. num, err := strconv.Atoi(dataArray[3])
  660. if err == nil {
  661. inputNumber = updateNumericInput(inputNumber, num)
  662. }
  663. if inputNumber == oldInputNumber {
  664. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))
  665. return
  666. }
  667. if inputNumber >= 999999 {
  668. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  669. return
  670. }
  671. }
  672. inlineKeyboard := t.numericKeypad(numericKeypadSpec{dataBase: "ip_limit", dataArgs: email + " ", cancelData: "client_cancel " + email, confirmLabelKey: "tgbot.buttons.confirmNumber"}, inputNumber)
  673. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  674. return
  675. }
  676. }
  677. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  678. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  679. case "add_client_ip_limit_c":
  680. if len(dataArray) == 2 {
  681. count, _ := strconv.Atoi(dataArray[1])
  682. client_LimitIP = count
  683. }
  684. messageId := callbackQuery.Message.GetMessageID()
  685. message_text := t.BuildClientDraftMessage()
  686. t.addClient(callbackQuery.Message.GetChat().ID, message_text, messageId)
  687. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))
  688. case "add_client_ip_limit_in":
  689. if len(dataArray) >= 2 {
  690. oldInputNumber, err := strconv.Atoi(dataArray[1])
  691. inputNumber := oldInputNumber
  692. if err == nil {
  693. if len(dataArray) == 3 {
  694. num, err := strconv.Atoi(dataArray[2])
  695. if err == nil {
  696. inputNumber = updateNumericInput(inputNumber, num)
  697. }
  698. if inputNumber == oldInputNumber {
  699. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))
  700. return
  701. }
  702. if inputNumber >= 999999 {
  703. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  704. return
  705. }
  706. }
  707. inlineKeyboard := t.numericKeypad(numericKeypadSpec{dataBase: "add_client_ip_limit", cancelData: "add_client_default_ip_limit", confirmLabelKey: "tgbot.buttons.confirmNumber"}, inputNumber)
  708. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  709. return
  710. }
  711. }
  712. case "clear_ips":
  713. inlineKeyboard := tu.InlineKeyboard(
  714. tu.InlineKeyboardRow(
  715. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancel")).WithCallbackData(t.encodeQuery("ips_cancel "+email)),
  716. ),
  717. tu.InlineKeyboardRow(
  718. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmClearIps")).WithCallbackData(t.encodeQuery("clear_ips_c "+email)),
  719. ),
  720. )
  721. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  722. case "clear_ips_c":
  723. err := t.inboundService.ClearClientIps(email)
  724. if err == nil {
  725. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.clearIpSuccess", "Email=="+email))
  726. t.searchClientIps(chatId, email, callbackQuery.Message.GetMessageID())
  727. } else {
  728. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  729. }
  730. case "ip_log":
  731. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.getIpLog", "Email=="+email))
  732. t.searchClientIps(chatId, email)
  733. case "tg_user":
  734. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.getUserInfo", "Email=="+email))
  735. t.clientTelegramUserInfo(chatId, email)
  736. case "tgid_remove":
  737. inlineKeyboard := tu.InlineKeyboard(
  738. tu.InlineKeyboardRow(
  739. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancel")).WithCallbackData(t.encodeQuery("tgid_cancel "+email)),
  740. ),
  741. tu.InlineKeyboardRow(
  742. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmRemoveTGUser")).WithCallbackData(t.encodeQuery("tgid_remove_c "+email)),
  743. ),
  744. )
  745. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  746. case "tgid_remove_c":
  747. traffic, err := t.inboundService.GetClientTrafficByEmail(email)
  748. if err != nil || traffic == nil {
  749. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  750. return
  751. }
  752. needRestart, err := t.clientService.SetClientTelegramUserID(&t.inboundService, traffic.Id, EmptyTelegramUserID)
  753. if needRestart {
  754. t.xrayService.SetToNeedRestart()
  755. }
  756. if err == nil {
  757. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.removedTGUserSuccess", "Email=="+email))
  758. t.clientTelegramUserInfo(chatId, email, callbackQuery.Message.GetMessageID())
  759. } else {
  760. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  761. }
  762. case "toggle_enable":
  763. inlineKeyboard := tu.InlineKeyboard(
  764. tu.InlineKeyboardRow(
  765. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancel")).WithCallbackData(t.encodeQuery("client_cancel "+email)),
  766. ),
  767. tu.InlineKeyboardRow(
  768. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmToggle")).WithCallbackData(t.encodeQuery("toggle_enable_c "+email)),
  769. ),
  770. )
  771. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  772. case "toggle_enable_c":
  773. enabled, needRestart, err := t.clientService.ToggleClientEnableByEmail(&t.inboundService, email)
  774. if needRestart {
  775. t.xrayService.SetToNeedRestart()
  776. }
  777. if err == nil {
  778. if enabled {
  779. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.enableSuccess", "Email=="+email))
  780. } else {
  781. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.disableSuccess", "Email=="+email))
  782. }
  783. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  784. } else {
  785. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  786. }
  787. case "get_clients":
  788. inboundId := dataArray[1]
  789. inboundIdInt, err := strconv.Atoi(inboundId)
  790. if err != nil {
  791. t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
  792. return
  793. }
  794. inbound, err := t.inboundService.GetInbound(inboundIdInt)
  795. if err != nil {
  796. t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
  797. return
  798. }
  799. clients, err := t.getInboundClients(inboundIdInt)
  800. if err != nil {
  801. t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
  802. return
  803. }
  804. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.chooseClient", "Inbound=="+inbound.Remark), clients)
  805. case "add_client_to":
  806. client_Email = t.randomLowerAndNum(8)
  807. client_LimitIP = 0
  808. client_TotalGB = 0
  809. client_ExpiryTime = 0
  810. client_Enable = true
  811. client_TgID = ""
  812. client_SubID = t.randomLowerAndNum(16)
  813. client_Comment = ""
  814. client_Reset = 0
  815. inboundId := dataArray[1]
  816. inboundIdInt, err := strconv.Atoi(inboundId)
  817. if err != nil {
  818. t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
  819. return
  820. }
  821. receiver_inbound_ID = inboundIdInt
  822. receiver_inbound_IDs = []int{inboundIdInt}
  823. t.addClient(callbackQuery.Message.GetChat().ID, t.BuildClientDraftMessage())
  824. case "add_client_toggle_attach":
  825. inboundIdStr := dataArray[1]
  826. inboundIdInt, err := strconv.Atoi(inboundIdStr)
  827. if err != nil {
  828. t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
  829. return
  830. }
  831. found := -1
  832. for i, id := range receiver_inbound_IDs {
  833. if id == inboundIdInt {
  834. found = i
  835. break
  836. }
  837. }
  838. if found >= 0 {
  839. receiver_inbound_IDs = append(receiver_inbound_IDs[:found], receiver_inbound_IDs[found+1:]...)
  840. } else {
  841. receiver_inbound_IDs = append(receiver_inbound_IDs, inboundIdInt)
  842. }
  843. picker, err := t.getInboundsAttachPicker()
  844. if err != nil {
  845. t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
  846. return
  847. }
  848. t.editMessageCallbackTgBot(callbackQuery.Message.GetChat().ID, callbackQuery.Message.GetMessageID(), picker)
  849. }
  850. return
  851. } else {
  852. switch callbackQuery.Data {
  853. case "get_inbounds":
  854. inbounds, err := t.getInbounds()
  855. if err != nil {
  856. t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
  857. return
  858. }
  859. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.allClients"))
  860. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.chooseInbound"), inbounds)
  861. case "admin_client_sub_links":
  862. inbounds, err := t.getInboundsFor("get_clients_for_sub")
  863. if err != nil {
  864. t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
  865. return
  866. }
  867. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.chooseInbound"), inbounds)
  868. case "admin_client_individual_links":
  869. inbounds, err := t.getInboundsFor("get_clients_for_individual")
  870. if err != nil {
  871. t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
  872. return
  873. }
  874. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.chooseInbound"), inbounds)
  875. case "admin_client_qr_links":
  876. inbounds, err := t.getInboundsFor("get_clients_for_qr")
  877. if err != nil {
  878. t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
  879. return
  880. }
  881. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.chooseInbound"), inbounds)
  882. }
  883. }
  884. }
  885. if !isAdmin && !isClientSelfCallback(callbackQuery.Data) {
  886. return
  887. }
  888. switch callbackQuery.Data {
  889. case "get_usage":
  890. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.serverUsage"))
  891. t.getServerUsage(chatId)
  892. case "usage_refresh":
  893. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))
  894. t.getServerUsage(chatId, callbackQuery.Message.GetMessageID())
  895. case "inbounds":
  896. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.getInbounds"))
  897. t.SendMsgToTgbot(chatId, t.getInboundUsages())
  898. case "deplete_soon":
  899. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.depleteSoon"))
  900. t.getExhausted(chatId)
  901. case "get_backup":
  902. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.dbBackup"))
  903. t.sendBackup(chatId)
  904. case "get_banlogs":
  905. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.getBanLogs"))
  906. t.sendBanLogs(chatId, true)
  907. case "client_traffic":
  908. tgUserID := callbackQuery.From.ID
  909. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.clientUsage"))
  910. t.getClientUsage(chatId, tgUserID)
  911. case "client_commands":
  912. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.commands"))
  913. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.commands.helpClientCommands"))
  914. case "client_sub_links":
  915. // show user's own clients to choose one for sub links
  916. tgUserID := callbackQuery.From.ID
  917. traffics, err := t.inboundService.GetClientTrafficTgBot(tgUserID)
  918. if err != nil {
  919. // fallback to message
  920. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.errorOperation")+"\r\n"+err.Error())
  921. return
  922. }
  923. if len(traffics) == 0 {
  924. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.askToAddUserId", "TgUserID=="+strconv.FormatInt(tgUserID, 10)))
  925. return
  926. }
  927. var buttons []telego.InlineKeyboardButton
  928. for _, tr := range traffics {
  929. buttons = append(buttons, tu.InlineKeyboardButton(tr.Email).WithCallbackData(t.encodeQuery("client_sub_links "+tr.Email)))
  930. }
  931. cols := 1
  932. if len(buttons) >= 6 {
  933. cols = 2
  934. }
  935. keyboard := tu.InlineKeyboardGrid(tu.InlineKeyboardCols(cols, buttons...))
  936. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.commands.pleaseChoose"), keyboard)
  937. case "client_individual_links":
  938. // show user's clients to choose for individual links
  939. tgUserID := callbackQuery.From.ID
  940. traffics, err := t.inboundService.GetClientTrafficTgBot(tgUserID)
  941. if err != nil {
  942. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.errorOperation")+"\r\n"+err.Error())
  943. return
  944. }
  945. if len(traffics) == 0 {
  946. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.askToAddUserId", "TgUserID=="+strconv.FormatInt(tgUserID, 10)))
  947. return
  948. }
  949. var buttons2 []telego.InlineKeyboardButton
  950. for _, tr := range traffics {
  951. buttons2 = append(buttons2, tu.InlineKeyboardButton(tr.Email).WithCallbackData(t.encodeQuery("client_individual_links "+tr.Email)))
  952. }
  953. cols2 := 1
  954. if len(buttons2) >= 6 {
  955. cols2 = 2
  956. }
  957. keyboard2 := tu.InlineKeyboardGrid(tu.InlineKeyboardCols(cols2, buttons2...))
  958. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.commands.pleaseChoose"), keyboard2)
  959. case "client_qr_links":
  960. // show user's clients to choose for QR codes
  961. tgUserID := callbackQuery.From.ID
  962. traffics, err := t.inboundService.GetClientTrafficTgBot(tgUserID)
  963. if err != nil {
  964. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.errorOccurred")+"\r\n"+err.Error())
  965. return
  966. }
  967. if len(traffics) == 0 {
  968. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.askToAddUserId", "TgUserID=="+strconv.FormatInt(tgUserID, 10)))
  969. return
  970. }
  971. var buttons3 []telego.InlineKeyboardButton
  972. for _, tr := range traffics {
  973. buttons3 = append(buttons3, tu.InlineKeyboardButton(tr.Email).WithCallbackData(t.encodeQuery("client_qr_links "+tr.Email)))
  974. }
  975. cols3 := 1
  976. if len(buttons3) >= 6 {
  977. cols3 = 2
  978. }
  979. keyboard3 := tu.InlineKeyboardGrid(tu.InlineKeyboardCols(cols3, buttons3...))
  980. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.commands.pleaseChoose"), keyboard3)
  981. case "onlines":
  982. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.onlines"))
  983. t.onlineClients(chatId)
  984. case "onlines_refresh":
  985. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))
  986. t.onlineClients(chatId, callbackQuery.Message.GetMessageID())
  987. case "commands":
  988. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.commands"))
  989. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.commands.helpAdminCommands"))
  990. case "add_client":
  991. client_Email = t.randomLowerAndNum(8)
  992. client_LimitIP = 0
  993. client_TotalGB = 0
  994. client_ExpiryTime = 0
  995. client_Enable = true
  996. client_TgID = ""
  997. client_SubID = t.randomLowerAndNum(16)
  998. client_Comment = ""
  999. client_Reset = 0
  1000. inbounds, err := t.getInboundsAddClient()
  1001. if err != nil {
  1002. t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
  1003. return
  1004. }
  1005. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.addClient"))
  1006. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.chooseInbound"), inbounds)
  1007. case "add_client_ch_default_email":
  1008. t.deleteMessageTgBot(chatId, callbackQuery.Message.GetMessageID())
  1009. userStateMgr.set(chatId, "awaiting_email")
  1010. cancel_btn_markup := tu.InlineKeyboard(
  1011. tu.InlineKeyboardRow(
  1012. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.use_default")).WithCallbackData("add_client_default_info"),
  1013. ),
  1014. )
  1015. prompt_message := t.I18nBot("tgbot.messages.email_prompt", "ClientEmail=="+client_Email)
  1016. t.SendMsgToTgbot(chatId, prompt_message, cancel_btn_markup)
  1017. case "add_client_ch_default_comment":
  1018. t.deleteMessageTgBot(chatId, callbackQuery.Message.GetMessageID())
  1019. userStateMgr.set(chatId, "awaiting_comment")
  1020. cancel_btn_markup := tu.InlineKeyboard(
  1021. tu.InlineKeyboardRow(
  1022. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.use_default")).WithCallbackData("add_client_default_info"),
  1023. ),
  1024. )
  1025. prompt_message := t.I18nBot("tgbot.messages.comment_prompt", "ClientComment=="+client_Comment)
  1026. t.SendMsgToTgbot(chatId, prompt_message, cancel_btn_markup)
  1027. case "add_client_ch_default_tg_id":
  1028. t.deleteMessageTgBot(chatId, callbackQuery.Message.GetMessageID())
  1029. userStateMgr.set(chatId, "awaiting_tg_id")
  1030. cancel_btn_markup := tu.InlineKeyboard(
  1031. tu.InlineKeyboardRow(
  1032. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.use_default")).WithCallbackData("add_client_default_info"),
  1033. ),
  1034. )
  1035. current := client_TgID
  1036. if current == "" {
  1037. current = "—"
  1038. }
  1039. 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)
  1040. case "add_client_ch_default_traffic":
  1041. inlineKeyboard := tu.InlineKeyboard(
  1042. tu.InlineKeyboardRow(
  1043. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancel")).WithCallbackData(t.encodeQuery("add_client_default_traffic_exp")),
  1044. ),
  1045. tu.InlineKeyboardRow(
  1046. tu.InlineKeyboardButton(t.I18nBot("tgbot.unlimited")).WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 0")),
  1047. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.custom")).WithCallbackData(t.encodeQuery("add_client_limit_traffic_in 0")),
  1048. ),
  1049. tu.InlineKeyboardRow(
  1050. tu.InlineKeyboardButton("1 GB").WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 1")),
  1051. tu.InlineKeyboardButton("5 GB").WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 5")),
  1052. tu.InlineKeyboardButton("10 GB").WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 10")),
  1053. ),
  1054. tu.InlineKeyboardRow(
  1055. tu.InlineKeyboardButton("20 GB").WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 20")),
  1056. tu.InlineKeyboardButton("30 GB").WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 30")),
  1057. tu.InlineKeyboardButton("40 GB").WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 40")),
  1058. ),
  1059. tu.InlineKeyboardRow(
  1060. tu.InlineKeyboardButton("50 GB").WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 50")),
  1061. tu.InlineKeyboardButton("60 GB").WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 60")),
  1062. tu.InlineKeyboardButton("80 GB").WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 80")),
  1063. ),
  1064. tu.InlineKeyboardRow(
  1065. tu.InlineKeyboardButton("100 GB").WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 100")),
  1066. tu.InlineKeyboardButton("150 GB").WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 150")),
  1067. tu.InlineKeyboardButton("200 GB").WithCallbackData(t.encodeQuery("add_client_limit_traffic_c 200")),
  1068. ),
  1069. )
  1070. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  1071. case "add_client_ch_default_exp":
  1072. inlineKeyboard := tu.InlineKeyboard(
  1073. tu.InlineKeyboardRow(
  1074. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancel")).WithCallbackData(t.encodeQuery("add_client_default_traffic_exp")),
  1075. ),
  1076. tu.InlineKeyboardRow(
  1077. tu.InlineKeyboardButton(t.I18nBot("tgbot.unlimited")).WithCallbackData(t.encodeQuery("add_client_reset_exp_c 0")),
  1078. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.custom")).WithCallbackData(t.encodeQuery("add_client_reset_exp_in 0")),
  1079. ),
  1080. tu.InlineKeyboardRow(
  1081. tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 7 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("add_client_reset_exp_c 7")),
  1082. tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 10 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("add_client_reset_exp_c 10")),
  1083. ),
  1084. tu.InlineKeyboardRow(
  1085. tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 14 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("add_client_reset_exp_c 14")),
  1086. tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 20 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("add_client_reset_exp_c 20")),
  1087. ),
  1088. tu.InlineKeyboardRow(
  1089. tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 1 "+t.I18nBot("tgbot.month")).WithCallbackData(t.encodeQuery("add_client_reset_exp_c 30")),
  1090. tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 3 "+t.I18nBot("tgbot.months")).WithCallbackData(t.encodeQuery("add_client_reset_exp_c 90")),
  1091. ),
  1092. tu.InlineKeyboardRow(
  1093. tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 6 "+t.I18nBot("tgbot.months")).WithCallbackData(t.encodeQuery("add_client_reset_exp_c 180")),
  1094. tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 12 "+t.I18nBot("tgbot.months")).WithCallbackData(t.encodeQuery("add_client_reset_exp_c 365")),
  1095. ),
  1096. )
  1097. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  1098. case "add_client_ch_default_ip_limit":
  1099. inlineKeyboard := tu.InlineKeyboard(
  1100. tu.InlineKeyboardRow(
  1101. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancel")).WithCallbackData(t.encodeQuery("add_client_default_ip_limit")),
  1102. ),
  1103. tu.InlineKeyboardRow(
  1104. tu.InlineKeyboardButton(t.I18nBot("tgbot.unlimited")).WithCallbackData(t.encodeQuery("add_client_ip_limit_c 0")),
  1105. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.custom")).WithCallbackData(t.encodeQuery("add_client_ip_limit_in 0")),
  1106. ),
  1107. tu.InlineKeyboardRow(
  1108. tu.InlineKeyboardButton("1").WithCallbackData(t.encodeQuery("add_client_ip_limit_c 1")),
  1109. tu.InlineKeyboardButton("2").WithCallbackData(t.encodeQuery("add_client_ip_limit_c 2")),
  1110. ),
  1111. tu.InlineKeyboardRow(
  1112. tu.InlineKeyboardButton("3").WithCallbackData(t.encodeQuery("add_client_ip_limit_c 3")),
  1113. tu.InlineKeyboardButton("4").WithCallbackData(t.encodeQuery("add_client_ip_limit_c 4")),
  1114. ),
  1115. tu.InlineKeyboardRow(
  1116. tu.InlineKeyboardButton("5").WithCallbackData(t.encodeQuery("add_client_ip_limit_c 5")),
  1117. tu.InlineKeyboardButton("6").WithCallbackData(t.encodeQuery("add_client_ip_limit_c 6")),
  1118. tu.InlineKeyboardButton("7").WithCallbackData(t.encodeQuery("add_client_ip_limit_c 7")),
  1119. ),
  1120. tu.InlineKeyboardRow(
  1121. tu.InlineKeyboardButton("8").WithCallbackData(t.encodeQuery("add_client_ip_limit_c 8")),
  1122. tu.InlineKeyboardButton("9").WithCallbackData(t.encodeQuery("add_client_ip_limit_c 9")),
  1123. tu.InlineKeyboardButton("10").WithCallbackData(t.encodeQuery("add_client_ip_limit_c 10")),
  1124. ),
  1125. )
  1126. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  1127. case "add_client_default_info":
  1128. t.deleteMessageTgBot(chatId, callbackQuery.Message.GetMessageID())
  1129. t.SendMsgToTgbotDeleteAfter(chatId, t.I18nBot("tgbot.messages.using_default_value"), 3, tu.ReplyKeyboardRemove())
  1130. userStateMgr.clear(chatId)
  1131. t.addClient(chatId, t.BuildClientDraftMessage())
  1132. case "add_client_cancel":
  1133. userStateMgr.clear(chatId)
  1134. receiver_inbound_ID = 0
  1135. receiver_inbound_IDs = nil
  1136. t.deleteMessageTgBot(chatId, callbackQuery.Message.GetMessageID())
  1137. t.SendMsgToTgbotDeleteAfter(chatId, t.I18nBot("tgbot.messages.cancel"), 3, tu.ReplyKeyboardRemove())
  1138. case "add_client_default_traffic_exp":
  1139. messageId := callbackQuery.Message.GetMessageID()
  1140. message_text := t.BuildClientDraftMessage()
  1141. t.addClient(chatId, message_text, messageId)
  1142. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.canceled", "Email=="+client_Email))
  1143. case "add_client_default_ip_limit":
  1144. messageId := callbackQuery.Message.GetMessageID()
  1145. message_text := t.BuildClientDraftMessage()
  1146. t.addClient(chatId, message_text, messageId)
  1147. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.canceled", "Email=="+client_Email))
  1148. case "add_client_attach_more":
  1149. picker, err := t.getInboundsAttachPicker()
  1150. if err != nil {
  1151. t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
  1152. return
  1153. }
  1154. t.SendMsgToTgbot(chatId, "Pick inbound(s) to attach:", picker)
  1155. case "add_client_attach_done":
  1156. if receiver_inbound_ID == 0 && len(receiver_inbound_IDs) > 0 {
  1157. receiver_inbound_ID = receiver_inbound_IDs[0]
  1158. }
  1159. if receiver_inbound_ID == 0 {
  1160. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.getInboundsFailed"))
  1161. return
  1162. }
  1163. message_text := t.BuildClientDraftMessage()
  1164. t.deleteMessageTgBot(chatId, callbackQuery.Message.GetMessageID())
  1165. t.addClient(chatId, message_text)
  1166. case "add_client_submit_disable":
  1167. client_Enable = false
  1168. _, err := t.SubmitAddClient()
  1169. if err != nil {
  1170. errorMessage := fmt.Sprintf("%v", err)
  1171. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.messages.error_add_client", "error=="+errorMessage), tu.ReplyKeyboardRemove())
  1172. } else {
  1173. t.deleteMessageTgBot(chatId, callbackQuery.Message.GetMessageID())
  1174. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.successfulOperation"), tu.ReplyKeyboardRemove())
  1175. t.sendClientIndividualLinks(chatId, client_Email)
  1176. t.sendClientQRLinks(chatId, client_Email)
  1177. receiver_inbound_ID = 0
  1178. receiver_inbound_IDs = nil
  1179. }
  1180. case "add_client_submit_enable":
  1181. client_Enable = true
  1182. _, err := t.SubmitAddClient()
  1183. if err != nil {
  1184. errorMessage := fmt.Sprintf("%v", err)
  1185. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.messages.error_add_client", "error=="+errorMessage), tu.ReplyKeyboardRemove())
  1186. } else {
  1187. t.deleteMessageTgBot(chatId, callbackQuery.Message.GetMessageID())
  1188. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.successfulOperation"), tu.ReplyKeyboardRemove())
  1189. t.sendClientIndividualLinks(chatId, client_Email)
  1190. t.sendClientQRLinks(chatId, client_Email)
  1191. receiver_inbound_ID = 0
  1192. receiver_inbound_IDs = nil
  1193. }
  1194. case "reset_all_traffics_cancel":
  1195. t.deleteMessageTgBot(chatId, callbackQuery.Message.GetMessageID())
  1196. t.SendMsgToTgbotDeleteAfter(chatId, t.I18nBot("tgbot.messages.cancel"), 1, tu.ReplyKeyboardRemove())
  1197. case "reset_all_traffics":
  1198. inlineKeyboard := tu.InlineKeyboard(
  1199. tu.InlineKeyboardRow(
  1200. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancelReset")).WithCallbackData(t.encodeQuery("reset_all_traffics_cancel")),
  1201. ),
  1202. tu.InlineKeyboardRow(
  1203. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmResetTraffic")).WithCallbackData(t.encodeQuery("reset_all_traffics_c")),
  1204. ),
  1205. )
  1206. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.messages.AreYouSure"), inlineKeyboard)
  1207. case "reset_all_traffics_c":
  1208. t.deleteMessageTgBot(chatId, callbackQuery.Message.GetMessageID())
  1209. emails, err := t.inboundService.GetAllEmails()
  1210. if err != nil {
  1211. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.errorOperation"), tu.ReplyKeyboardRemove())
  1212. return
  1213. }
  1214. for _, email := range emails {
  1215. err := t.inboundService.ResetClientTrafficByEmail(email)
  1216. if err == nil {
  1217. msg := t.I18nBot("tgbot.messages.SuccessResetTraffic", "ClientEmail=="+email)
  1218. t.SendMsgToTgbot(chatId, msg, tu.ReplyKeyboardRemove())
  1219. } else {
  1220. msg := t.I18nBot("tgbot.messages.FailedResetTraffic", "ClientEmail=="+email, "ErrorMessage=="+err.Error())
  1221. t.SendMsgToTgbot(chatId, msg, tu.ReplyKeyboardRemove())
  1222. }
  1223. }
  1224. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.messages.FinishProcess"), tu.ReplyKeyboardRemove())
  1225. case "get_sorted_traffic_usage_report":
  1226. t.deleteMessageTgBot(chatId, callbackQuery.Message.GetMessageID())
  1227. emails, err := t.inboundService.GetAllEmails()
  1228. if err != nil {
  1229. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.errorOperation"), tu.ReplyKeyboardRemove())
  1230. return
  1231. }
  1232. valid_emails, extra_emails, err := t.inboundService.FilterAndSortClientEmails(emails)
  1233. if err != nil {
  1234. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.errorOperation"), tu.ReplyKeyboardRemove())
  1235. return
  1236. }
  1237. for _, valid_emails := range valid_emails {
  1238. traffic, err := t.inboundService.GetClientTrafficByEmail(valid_emails)
  1239. if err != nil {
  1240. logger.Warning(err)
  1241. msg := t.I18nBot("tgbot.wentWrong")
  1242. t.SendMsgToTgbot(chatId, msg)
  1243. continue
  1244. }
  1245. if traffic == nil {
  1246. msg := t.I18nBot("tgbot.noResult")
  1247. t.SendMsgToTgbot(chatId, msg)
  1248. continue
  1249. }
  1250. output := t.clientInfoMsg(traffic, false, false, false, false, true, false)
  1251. t.SendMsgToTgbot(chatId, output, tu.ReplyKeyboardRemove())
  1252. }
  1253. for _, extra_emails := range extra_emails {
  1254. msg := fmt.Sprintf("📧 %s\n%s", extra_emails, t.I18nBot("tgbot.noResult"))
  1255. t.SendMsgToTgbot(chatId, msg, tu.ReplyKeyboardRemove())
  1256. }
  1257. default:
  1258. if after, ok := strings.CutPrefix(callbackQuery.Data, "client_sub_links "); ok {
  1259. email := after
  1260. t.sendClientSubLinks(chatId, email)
  1261. return
  1262. }
  1263. if after, ok := strings.CutPrefix(callbackQuery.Data, "client_individual_links "); ok {
  1264. email := after
  1265. t.sendClientIndividualLinks(chatId, email)
  1266. return
  1267. }
  1268. if after, ok := strings.CutPrefix(callbackQuery.Data, "client_qr_links "); ok {
  1269. email := after
  1270. t.sendClientQRLinks(chatId, email)
  1271. return
  1272. }
  1273. }
  1274. }
  1275. // checkAdmin checks if the given Telegram ID is an admin.
  1276. func checkAdmin(tgId int64) bool {
  1277. return slices.Contains(adminIds, tgId)
  1278. }
  1279. // isClientSelfCallback reports whether a callback is one of the per-user client
  1280. // actions that resolve their own data from the caller's Telegram id, and so are
  1281. // safe to run for a non-admin. Every other callback is admin-only (default-deny).
  1282. func isClientSelfCallback(data string) bool {
  1283. switch data {
  1284. case "client_traffic", "client_commands", "client_sub_links",
  1285. "client_individual_links", "client_qr_links":
  1286. return true
  1287. }
  1288. return strings.HasPrefix(data, "client_sub_links ") ||
  1289. strings.HasPrefix(data, "client_individual_links ") ||
  1290. strings.HasPrefix(data, "client_qr_links ")
  1291. }