tgbot.go 64 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810
  1. package service
  2. import (
  3. "embed"
  4. "errors"
  5. "fmt"
  6. "net"
  7. "net/url"
  8. "os"
  9. "strconv"
  10. "strings"
  11. "time"
  12. "x-ui/config"
  13. "x-ui/database"
  14. "x-ui/database/model"
  15. "x-ui/logger"
  16. "x-ui/util/common"
  17. "x-ui/web/global"
  18. "x-ui/web/locale"
  19. "x-ui/xray"
  20. "github.com/mymmrac/telego"
  21. th "github.com/mymmrac/telego/telegohandler"
  22. tu "github.com/mymmrac/telego/telegoutil"
  23. "github.com/valyala/fasthttp"
  24. "github.com/valyala/fasthttp/fasthttpproxy"
  25. )
  26. var (
  27. bot *telego.Bot
  28. botHandler *th.BotHandler
  29. adminIds []int64
  30. isRunning bool
  31. hostname string
  32. hashStorage *global.HashStorage
  33. )
  34. type LoginStatus byte
  35. const (
  36. LoginSuccess LoginStatus = 1
  37. LoginFail LoginStatus = 0
  38. EmptyTelegramUserID = int64(0)
  39. )
  40. type Tgbot struct {
  41. inboundService InboundService
  42. settingService SettingService
  43. serverService ServerService
  44. xrayService XrayService
  45. lastStatus *Status
  46. }
  47. func (t *Tgbot) NewTgbot() *Tgbot {
  48. return new(Tgbot)
  49. }
  50. func (t *Tgbot) I18nBot(name string, params ...string) string {
  51. return locale.I18n(locale.Bot, name, params...)
  52. }
  53. func (t *Tgbot) GetHashStorage() *global.HashStorage {
  54. return hashStorage
  55. }
  56. func (t *Tgbot) Start(i18nFS embed.FS) error {
  57. // Initialize localizer
  58. err := locale.InitLocalizer(i18nFS, &t.settingService)
  59. if err != nil {
  60. return err
  61. }
  62. // Initialize hash storage to store callback queries
  63. hashStorage = global.NewHashStorage(20 * time.Minute)
  64. t.SetHostname()
  65. // Get Telegram bot token
  66. tgBotToken, err := t.settingService.GetTgBotToken()
  67. if err != nil || tgBotToken == "" {
  68. logger.Warning("Failed to get Telegram bot token:", err)
  69. return err
  70. }
  71. // Get Telegram bot chat ID(s)
  72. tgBotID, err := t.settingService.GetTgBotChatId()
  73. if err != nil {
  74. logger.Warning("Failed to get Telegram bot chat ID:", err)
  75. return err
  76. }
  77. // Parse admin IDs from comma-separated string
  78. if tgBotID != "" {
  79. for _, adminID := range strings.Split(tgBotID, ",") {
  80. id, err := strconv.Atoi(adminID)
  81. if err != nil {
  82. logger.Warning("Failed to parse admin ID from Telegram bot chat ID:", err)
  83. return err
  84. }
  85. adminIds = append(adminIds, int64(id))
  86. }
  87. }
  88. // Get Telegram bot proxy URL
  89. tgBotProxy, err := t.settingService.GetTgBotProxy()
  90. if err != nil {
  91. logger.Warning("Failed to get Telegram bot proxy URL:", err)
  92. }
  93. // Create new Telegram bot instance
  94. bot, err = t.NewBot(tgBotToken, tgBotProxy)
  95. if err != nil {
  96. logger.Error("Failed to initialize Telegram bot API:", err)
  97. return err
  98. }
  99. // Start receiving Telegram bot messages
  100. if !isRunning {
  101. logger.Info("Telegram bot receiver started")
  102. go t.OnReceive()
  103. isRunning = true
  104. }
  105. return nil
  106. }
  107. func (t *Tgbot) NewBot(token string, proxyUrl string) (*telego.Bot, error) {
  108. if proxyUrl == "" {
  109. // No proxy URL provided, use default instance
  110. return telego.NewBot(token)
  111. }
  112. if !strings.HasPrefix(proxyUrl, "socks5://") {
  113. logger.Warning("Invalid socks5 URL, starting with default")
  114. return telego.NewBot(token)
  115. }
  116. _, err := url.Parse(proxyUrl)
  117. if err != nil {
  118. logger.Warning("Can't parse proxy URL, using default instance for tgbot:", err)
  119. return telego.NewBot(token)
  120. }
  121. return telego.NewBot(token, telego.WithFastHTTPClient(&fasthttp.Client{
  122. Dial: fasthttpproxy.FasthttpSocksDialer(proxyUrl),
  123. }))
  124. }
  125. func (t *Tgbot) IsRunning() bool {
  126. return isRunning
  127. }
  128. func (t *Tgbot) SetHostname() {
  129. host, err := os.Hostname()
  130. if err != nil {
  131. logger.Error("get hostname error:", err)
  132. hostname = ""
  133. return
  134. }
  135. hostname = host
  136. }
  137. func (t *Tgbot) Stop() {
  138. botHandler.Stop()
  139. bot.StopLongPolling()
  140. logger.Info("Stop Telegram receiver ...")
  141. isRunning = false
  142. adminIds = nil
  143. }
  144. func (t *Tgbot) encodeQuery(query string) string {
  145. // NOTE: we only need to hash for more than 64 chars
  146. if len(query) <= 64 {
  147. return query
  148. }
  149. return hashStorage.SaveHash(query)
  150. }
  151. func (t *Tgbot) decodeQuery(query string) (string, error) {
  152. if !hashStorage.IsMD5(query) {
  153. return query, nil
  154. }
  155. decoded, exists := hashStorage.GetValue(query)
  156. if !exists {
  157. return "", common.NewError("hash not found in storage!")
  158. }
  159. return decoded, nil
  160. }
  161. func (t *Tgbot) OnReceive() {
  162. params := telego.GetUpdatesParams{
  163. Timeout: 10,
  164. }
  165. updates, _ := bot.UpdatesViaLongPolling(&params)
  166. botHandler, _ = th.NewBotHandler(bot, updates)
  167. botHandler.HandleMessage(func(_ *telego.Bot, message telego.Message) {
  168. t.SendMsgToTgbot(message.Chat.ID, t.I18nBot("tgbot.keyboardClosed"), tu.ReplyKeyboardRemove())
  169. }, th.TextEqual(t.I18nBot("tgbot.buttons.closeKeyboard")))
  170. botHandler.HandleMessage(func(_ *telego.Bot, message telego.Message) {
  171. t.answerCommand(&message, message.Chat.ID, checkAdmin(message.From.ID))
  172. }, th.AnyCommand())
  173. botHandler.HandleCallbackQuery(func(_ *telego.Bot, query telego.CallbackQuery) {
  174. t.answerCallback(&query, checkAdmin(query.From.ID))
  175. }, th.AnyCallbackQueryWithMessage())
  176. botHandler.HandleMessage(func(_ *telego.Bot, message telego.Message) {
  177. if message.UsersShared != nil {
  178. if checkAdmin(message.From.ID) {
  179. for _, sharedUser := range message.UsersShared.Users {
  180. userID := sharedUser.UserID
  181. needRestart, err := t.inboundService.SetClientTelegramUserID(message.UsersShared.RequestID, userID)
  182. if needRestart {
  183. t.xrayService.SetToNeedRestart()
  184. }
  185. output := ""
  186. if err != nil {
  187. output += t.I18nBot("tgbot.messages.selectUserFailed")
  188. } else {
  189. output += t.I18nBot("tgbot.messages.userSaved")
  190. }
  191. t.SendMsgToTgbot(message.Chat.ID, output, tu.ReplyKeyboardRemove())
  192. }
  193. } else {
  194. t.SendMsgToTgbot(message.Chat.ID, t.I18nBot("tgbot.noResult"), tu.ReplyKeyboardRemove())
  195. }
  196. }
  197. }, th.AnyMessage())
  198. botHandler.Start()
  199. }
  200. func (t *Tgbot) answerCommand(message *telego.Message, chatId int64, isAdmin bool) {
  201. msg, onlyMessage := "", false
  202. command, _, commandArgs := tu.ParseCommand(message.Text)
  203. // Extract the command from the Message.
  204. switch command {
  205. case "help":
  206. msg += t.I18nBot("tgbot.commands.help")
  207. msg += t.I18nBot("tgbot.commands.pleaseChoose")
  208. case "start":
  209. msg += t.I18nBot("tgbot.commands.start", "Firstname=="+message.From.FirstName)
  210. if isAdmin {
  211. msg += t.I18nBot("tgbot.commands.welcome", "Hostname=="+hostname)
  212. }
  213. msg += "\n\n" + t.I18nBot("tgbot.commands.pleaseChoose")
  214. case "status":
  215. onlyMessage = true
  216. msg += t.I18nBot("tgbot.commands.status")
  217. case "id":
  218. onlyMessage = true
  219. msg += t.I18nBot("tgbot.commands.getID", "ID=="+strconv.FormatInt(message.From.ID, 10))
  220. case "usage":
  221. onlyMessage = true
  222. if len(commandArgs) > 0 {
  223. if isAdmin {
  224. t.searchClient(chatId, commandArgs[0])
  225. } else {
  226. // Convert message.From.ID to int64
  227. fromID := int64(message.From.ID)
  228. t.getClientUsage(chatId, fromID, commandArgs[0])
  229. }
  230. } else {
  231. msg += t.I18nBot("tgbot.commands.usage")
  232. }
  233. case "inbound":
  234. onlyMessage = true
  235. if isAdmin && len(commandArgs) > 0 {
  236. t.searchInbound(chatId, commandArgs[0])
  237. } else {
  238. msg += t.I18nBot("tgbot.commands.unknown")
  239. }
  240. default:
  241. msg += t.I18nBot("tgbot.commands.unknown")
  242. }
  243. if msg != "" {
  244. if onlyMessage {
  245. t.SendMsgToTgbot(chatId, msg)
  246. return
  247. } else {
  248. t.SendAnswer(chatId, msg, isAdmin)
  249. }
  250. }
  251. }
  252. func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool) {
  253. chatId := callbackQuery.Message.GetChat().ID
  254. if isAdmin {
  255. // get query from hash storage
  256. decodedQuery, err := t.decodeQuery(callbackQuery.Data)
  257. if err != nil {
  258. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.noQuery"))
  259. return
  260. }
  261. dataArray := strings.Split(decodedQuery, " ")
  262. if len(dataArray) >= 2 && len(dataArray[1]) > 0 {
  263. email := dataArray[1]
  264. switch dataArray[0] {
  265. case "client_get_usage":
  266. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.messages.email", "Email=="+email))
  267. t.searchClient(chatId, email)
  268. case "client_refresh":
  269. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.clientRefreshSuccess", "Email=="+email))
  270. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  271. case "client_cancel":
  272. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.canceled", "Email=="+email))
  273. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  274. case "ips_refresh":
  275. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.IpRefreshSuccess", "Email=="+email))
  276. t.searchClientIps(chatId, email, callbackQuery.Message.GetMessageID())
  277. case "ips_cancel":
  278. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.canceled", "Email=="+email))
  279. t.searchClientIps(chatId, email, callbackQuery.Message.GetMessageID())
  280. case "tgid_refresh":
  281. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.TGIdRefreshSuccess", "Email=="+email))
  282. t.clientTelegramUserInfo(chatId, email, callbackQuery.Message.GetMessageID())
  283. case "tgid_cancel":
  284. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.canceled", "Email=="+email))
  285. t.clientTelegramUserInfo(chatId, email, callbackQuery.Message.GetMessageID())
  286. case "reset_traffic":
  287. inlineKeyboard := tu.InlineKeyboard(
  288. tu.InlineKeyboardRow(
  289. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancelReset")).WithCallbackData(t.encodeQuery("client_cancel "+email)),
  290. ),
  291. tu.InlineKeyboardRow(
  292. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmResetTraffic")).WithCallbackData(t.encodeQuery("reset_traffic_c "+email)),
  293. ),
  294. )
  295. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  296. case "reset_traffic_c":
  297. err := t.inboundService.ResetClientTrafficByEmail(email)
  298. if err == nil {
  299. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.resetTrafficSuccess", "Email=="+email))
  300. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  301. } else {
  302. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  303. }
  304. case "limit_traffic":
  305. inlineKeyboard := tu.InlineKeyboard(
  306. tu.InlineKeyboardRow(
  307. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancel")).WithCallbackData(t.encodeQuery("client_cancel "+email)),
  308. ),
  309. tu.InlineKeyboardRow(
  310. tu.InlineKeyboardButton(t.I18nBot("tgbot.unlimited")).WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 0")),
  311. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.custom")).WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" 0")),
  312. ),
  313. tu.InlineKeyboardRow(
  314. tu.InlineKeyboardButton("1 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 1")),
  315. tu.InlineKeyboardButton("5 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 5")),
  316. tu.InlineKeyboardButton("10 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 10")),
  317. ),
  318. tu.InlineKeyboardRow(
  319. tu.InlineKeyboardButton("20 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 20")),
  320. tu.InlineKeyboardButton("30 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 30")),
  321. tu.InlineKeyboardButton("40 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 40")),
  322. ),
  323. tu.InlineKeyboardRow(
  324. tu.InlineKeyboardButton("50 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 50")),
  325. tu.InlineKeyboardButton("60 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 60")),
  326. tu.InlineKeyboardButton("80 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 80")),
  327. ),
  328. tu.InlineKeyboardRow(
  329. tu.InlineKeyboardButton("100 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 100")),
  330. tu.InlineKeyboardButton("150 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 150")),
  331. tu.InlineKeyboardButton("200 GB").WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" 200")),
  332. ),
  333. )
  334. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  335. case "limit_traffic_c":
  336. if len(dataArray) == 3 {
  337. limitTraffic, err := strconv.Atoi(dataArray[2])
  338. if err == nil {
  339. needRestart, err := t.inboundService.ResetClientTrafficLimitByEmail(email, limitTraffic)
  340. if needRestart {
  341. t.xrayService.SetToNeedRestart()
  342. }
  343. if err == nil {
  344. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.setTrafficLimitSuccess", "Email=="+email))
  345. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  346. return
  347. }
  348. }
  349. }
  350. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  351. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  352. case "limit_traffic_in":
  353. if len(dataArray) >= 3 {
  354. oldInputNumber, err := strconv.Atoi(dataArray[2])
  355. inputNumber := oldInputNumber
  356. if err == nil {
  357. if len(dataArray) == 4 {
  358. num, err := strconv.Atoi(dataArray[3])
  359. if err == nil {
  360. if num == -2 {
  361. inputNumber = 0
  362. } else if num == -1 {
  363. if inputNumber > 0 {
  364. inputNumber = (inputNumber / 10)
  365. }
  366. } else {
  367. inputNumber = (inputNumber * 10) + num
  368. }
  369. }
  370. if inputNumber == oldInputNumber {
  371. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))
  372. return
  373. }
  374. if inputNumber >= 999999 {
  375. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  376. return
  377. }
  378. }
  379. inlineKeyboard := tu.InlineKeyboard(
  380. tu.InlineKeyboardRow(
  381. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancel")).WithCallbackData(t.encodeQuery("client_cancel "+email)),
  382. ),
  383. tu.InlineKeyboardRow(
  384. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmNumberAdd", "Num=="+strconv.Itoa(inputNumber))).WithCallbackData(t.encodeQuery("limit_traffic_c "+email+" "+strconv.Itoa(inputNumber))),
  385. ),
  386. tu.InlineKeyboardRow(
  387. tu.InlineKeyboardButton("1").WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" "+strconv.Itoa(inputNumber)+" 1")),
  388. tu.InlineKeyboardButton("2").WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" "+strconv.Itoa(inputNumber)+" 2")),
  389. tu.InlineKeyboardButton("3").WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" "+strconv.Itoa(inputNumber)+" 3")),
  390. ),
  391. tu.InlineKeyboardRow(
  392. tu.InlineKeyboardButton("4").WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" "+strconv.Itoa(inputNumber)+" 4")),
  393. tu.InlineKeyboardButton("5").WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" "+strconv.Itoa(inputNumber)+" 5")),
  394. tu.InlineKeyboardButton("6").WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" "+strconv.Itoa(inputNumber)+" 6")),
  395. ),
  396. tu.InlineKeyboardRow(
  397. tu.InlineKeyboardButton("7").WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" "+strconv.Itoa(inputNumber)+" 7")),
  398. tu.InlineKeyboardButton("8").WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" "+strconv.Itoa(inputNumber)+" 8")),
  399. tu.InlineKeyboardButton("9").WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" "+strconv.Itoa(inputNumber)+" 9")),
  400. ),
  401. tu.InlineKeyboardRow(
  402. tu.InlineKeyboardButton("🔄").WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" "+strconv.Itoa(inputNumber)+" -2")),
  403. tu.InlineKeyboardButton("0").WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" "+strconv.Itoa(inputNumber)+" 0")),
  404. tu.InlineKeyboardButton("⬅️").WithCallbackData(t.encodeQuery("limit_traffic_in "+email+" "+strconv.Itoa(inputNumber)+" -1")),
  405. ),
  406. )
  407. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  408. return
  409. }
  410. }
  411. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  412. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  413. case "reset_exp":
  414. inlineKeyboard := tu.InlineKeyboard(
  415. tu.InlineKeyboardRow(
  416. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancelReset")).WithCallbackData(t.encodeQuery("client_cancel "+email)),
  417. ),
  418. tu.InlineKeyboardRow(
  419. tu.InlineKeyboardButton(t.I18nBot("tgbot.unlimited")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 0")),
  420. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.custom")).WithCallbackData(t.encodeQuery("reset_exp_in "+email+" 0")),
  421. ),
  422. tu.InlineKeyboardRow(
  423. tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 7 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 7")),
  424. tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 10 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 10")),
  425. ),
  426. tu.InlineKeyboardRow(
  427. tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 14 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 14")),
  428. tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 20 "+t.I18nBot("tgbot.days")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 20")),
  429. ),
  430. tu.InlineKeyboardRow(
  431. tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 1 "+t.I18nBot("tgbot.month")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 30")),
  432. tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 3 "+t.I18nBot("tgbot.months")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 90")),
  433. ),
  434. tu.InlineKeyboardRow(
  435. tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 6 "+t.I18nBot("tgbot.months")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 180")),
  436. tu.InlineKeyboardButton(t.I18nBot("tgbot.add")+" 12 "+t.I18nBot("tgbot.months")).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" 365")),
  437. ),
  438. )
  439. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  440. case "reset_exp_c":
  441. if len(dataArray) == 3 {
  442. days, err := strconv.Atoi(dataArray[2])
  443. if err == nil {
  444. var date int64 = 0
  445. if days > 0 {
  446. traffic, err := t.inboundService.GetClientTrafficByEmail(email)
  447. if err != nil {
  448. logger.Warning(err)
  449. msg := t.I18nBot("tgbot.wentWrong")
  450. t.SendMsgToTgbot(chatId, msg)
  451. return
  452. }
  453. if traffic == nil {
  454. msg := t.I18nBot("tgbot.noResult")
  455. t.SendMsgToTgbot(chatId, msg)
  456. return
  457. }
  458. if traffic.ExpiryTime > 0 {
  459. if traffic.ExpiryTime-time.Now().Unix()*1000 < 0 {
  460. date = -int64(days * 24 * 60 * 60000)
  461. } else {
  462. date = traffic.ExpiryTime + int64(days*24*60*60000)
  463. }
  464. } else {
  465. date = traffic.ExpiryTime - int64(days*24*60*60000)
  466. }
  467. }
  468. needRestart, err := t.inboundService.ResetClientExpiryTimeByEmail(email, date)
  469. if needRestart {
  470. t.xrayService.SetToNeedRestart()
  471. }
  472. if err == nil {
  473. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.expireResetSuccess", "Email=="+email))
  474. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  475. return
  476. }
  477. }
  478. }
  479. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  480. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  481. case "reset_exp_in":
  482. if len(dataArray) >= 3 {
  483. oldInputNumber, err := strconv.Atoi(dataArray[2])
  484. inputNumber := oldInputNumber
  485. if err == nil {
  486. if len(dataArray) == 4 {
  487. num, err := strconv.Atoi(dataArray[3])
  488. if err == nil {
  489. if num == -2 {
  490. inputNumber = 0
  491. } else if num == -1 {
  492. if inputNumber > 0 {
  493. inputNumber = (inputNumber / 10)
  494. }
  495. } else {
  496. inputNumber = (inputNumber * 10) + num
  497. }
  498. }
  499. if inputNumber == oldInputNumber {
  500. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))
  501. return
  502. }
  503. if inputNumber >= 999999 {
  504. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  505. return
  506. }
  507. }
  508. inlineKeyboard := tu.InlineKeyboard(
  509. tu.InlineKeyboardRow(
  510. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancel")).WithCallbackData(t.encodeQuery("client_cancel "+email)),
  511. ),
  512. tu.InlineKeyboardRow(
  513. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmNumber", "Num=="+strconv.Itoa(inputNumber))).WithCallbackData(t.encodeQuery("reset_exp_c "+email+" "+strconv.Itoa(inputNumber))),
  514. ),
  515. tu.InlineKeyboardRow(
  516. tu.InlineKeyboardButton("1").WithCallbackData(t.encodeQuery("reset_exp_in "+email+" "+strconv.Itoa(inputNumber)+" 1")),
  517. tu.InlineKeyboardButton("2").WithCallbackData(t.encodeQuery("reset_exp_in "+email+" "+strconv.Itoa(inputNumber)+" 2")),
  518. tu.InlineKeyboardButton("3").WithCallbackData(t.encodeQuery("reset_exp_in "+email+" "+strconv.Itoa(inputNumber)+" 3")),
  519. ),
  520. tu.InlineKeyboardRow(
  521. tu.InlineKeyboardButton("4").WithCallbackData(t.encodeQuery("reset_exp_in "+email+" "+strconv.Itoa(inputNumber)+" 4")),
  522. tu.InlineKeyboardButton("5").WithCallbackData(t.encodeQuery("reset_exp_in "+email+" "+strconv.Itoa(inputNumber)+" 5")),
  523. tu.InlineKeyboardButton("6").WithCallbackData(t.encodeQuery("reset_exp_in "+email+" "+strconv.Itoa(inputNumber)+" 6")),
  524. ),
  525. tu.InlineKeyboardRow(
  526. tu.InlineKeyboardButton("7").WithCallbackData(t.encodeQuery("reset_exp_in "+email+" "+strconv.Itoa(inputNumber)+" 7")),
  527. tu.InlineKeyboardButton("8").WithCallbackData(t.encodeQuery("reset_exp_in "+email+" "+strconv.Itoa(inputNumber)+" 8")),
  528. tu.InlineKeyboardButton("9").WithCallbackData(t.encodeQuery("reset_exp_in "+email+" "+strconv.Itoa(inputNumber)+" 9")),
  529. ),
  530. tu.InlineKeyboardRow(
  531. tu.InlineKeyboardButton("🔄").WithCallbackData(t.encodeQuery("reset_exp_in "+email+" "+strconv.Itoa(inputNumber)+" -2")),
  532. tu.InlineKeyboardButton("0").WithCallbackData(t.encodeQuery("reset_exp_in "+email+" "+strconv.Itoa(inputNumber)+" 0")),
  533. tu.InlineKeyboardButton("⬅️").WithCallbackData(t.encodeQuery("reset_exp_in "+email+" "+strconv.Itoa(inputNumber)+" -1")),
  534. ),
  535. )
  536. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  537. return
  538. }
  539. }
  540. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  541. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  542. case "ip_limit":
  543. inlineKeyboard := tu.InlineKeyboard(
  544. tu.InlineKeyboardRow(
  545. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancelIpLimit")).WithCallbackData(t.encodeQuery("client_cancel "+email)),
  546. ),
  547. tu.InlineKeyboardRow(
  548. tu.InlineKeyboardButton(t.I18nBot("tgbot.unlimited")).WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 0")),
  549. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.custom")).WithCallbackData(t.encodeQuery("ip_limit_in "+email+" 0")),
  550. ),
  551. tu.InlineKeyboardRow(
  552. tu.InlineKeyboardButton("1").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 1")),
  553. tu.InlineKeyboardButton("2").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 2")),
  554. ),
  555. tu.InlineKeyboardRow(
  556. tu.InlineKeyboardButton("3").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 3")),
  557. tu.InlineKeyboardButton("4").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 4")),
  558. ),
  559. tu.InlineKeyboardRow(
  560. tu.InlineKeyboardButton("5").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 5")),
  561. tu.InlineKeyboardButton("6").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 6")),
  562. tu.InlineKeyboardButton("7").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 7")),
  563. ),
  564. tu.InlineKeyboardRow(
  565. tu.InlineKeyboardButton("8").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 8")),
  566. tu.InlineKeyboardButton("9").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 9")),
  567. tu.InlineKeyboardButton("10").WithCallbackData(t.encodeQuery("ip_limit_c "+email+" 10")),
  568. ),
  569. )
  570. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  571. case "ip_limit_c":
  572. if len(dataArray) == 3 {
  573. count, err := strconv.Atoi(dataArray[2])
  574. if err == nil {
  575. needRestart, err := t.inboundService.ResetClientIpLimitByEmail(email, count)
  576. if needRestart {
  577. t.xrayService.SetToNeedRestart()
  578. }
  579. if err == nil {
  580. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.resetIpSuccess", "Email=="+email, "Count=="+strconv.Itoa(count)))
  581. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  582. return
  583. }
  584. }
  585. }
  586. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  587. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  588. case "ip_limit_in":
  589. if len(dataArray) >= 3 {
  590. oldInputNumber, err := strconv.Atoi(dataArray[2])
  591. inputNumber := oldInputNumber
  592. if err == nil {
  593. if len(dataArray) == 4 {
  594. num, err := strconv.Atoi(dataArray[3])
  595. if err == nil {
  596. if num == -2 {
  597. inputNumber = 0
  598. } else if num == -1 {
  599. if inputNumber > 0 {
  600. inputNumber = (inputNumber / 10)
  601. }
  602. } else {
  603. inputNumber = (inputNumber * 10) + num
  604. }
  605. }
  606. if inputNumber == oldInputNumber {
  607. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))
  608. return
  609. }
  610. if inputNumber >= 999999 {
  611. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  612. return
  613. }
  614. }
  615. inlineKeyboard := tu.InlineKeyboard(
  616. tu.InlineKeyboardRow(
  617. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancel")).WithCallbackData(t.encodeQuery("client_cancel "+email)),
  618. ),
  619. tu.InlineKeyboardRow(
  620. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmNumber", "Num=="+strconv.Itoa(inputNumber))).WithCallbackData(t.encodeQuery("ip_limit_c "+email+" "+strconv.Itoa(inputNumber))),
  621. ),
  622. tu.InlineKeyboardRow(
  623. tu.InlineKeyboardButton("1").WithCallbackData(t.encodeQuery("ip_limit_in "+email+" "+strconv.Itoa(inputNumber)+" 1")),
  624. tu.InlineKeyboardButton("2").WithCallbackData(t.encodeQuery("ip_limit_in "+email+" "+strconv.Itoa(inputNumber)+" 2")),
  625. tu.InlineKeyboardButton("3").WithCallbackData(t.encodeQuery("ip_limit_in "+email+" "+strconv.Itoa(inputNumber)+" 3")),
  626. ),
  627. tu.InlineKeyboardRow(
  628. tu.InlineKeyboardButton("4").WithCallbackData(t.encodeQuery("ip_limit_in "+email+" "+strconv.Itoa(inputNumber)+" 4")),
  629. tu.InlineKeyboardButton("5").WithCallbackData(t.encodeQuery("ip_limit_in "+email+" "+strconv.Itoa(inputNumber)+" 5")),
  630. tu.InlineKeyboardButton("6").WithCallbackData(t.encodeQuery("ip_limit_in "+email+" "+strconv.Itoa(inputNumber)+" 6")),
  631. ),
  632. tu.InlineKeyboardRow(
  633. tu.InlineKeyboardButton("7").WithCallbackData(t.encodeQuery("ip_limit_in "+email+" "+strconv.Itoa(inputNumber)+" 7")),
  634. tu.InlineKeyboardButton("8").WithCallbackData(t.encodeQuery("ip_limit_in "+email+" "+strconv.Itoa(inputNumber)+" 8")),
  635. tu.InlineKeyboardButton("9").WithCallbackData(t.encodeQuery("ip_limit_in "+email+" "+strconv.Itoa(inputNumber)+" 9")),
  636. ),
  637. tu.InlineKeyboardRow(
  638. tu.InlineKeyboardButton("🔄").WithCallbackData(t.encodeQuery("ip_limit_in "+email+" "+strconv.Itoa(inputNumber)+" -2")),
  639. tu.InlineKeyboardButton("0").WithCallbackData(t.encodeQuery("ip_limit_in "+email+" "+strconv.Itoa(inputNumber)+" 0")),
  640. tu.InlineKeyboardButton("⬅️").WithCallbackData(t.encodeQuery("ip_limit_in "+email+" "+strconv.Itoa(inputNumber)+" -1")),
  641. ),
  642. )
  643. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  644. return
  645. }
  646. }
  647. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  648. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  649. case "clear_ips":
  650. inlineKeyboard := tu.InlineKeyboard(
  651. tu.InlineKeyboardRow(
  652. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancel")).WithCallbackData(t.encodeQuery("ips_cancel "+email)),
  653. ),
  654. tu.InlineKeyboardRow(
  655. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmClearIps")).WithCallbackData(t.encodeQuery("clear_ips_c "+email)),
  656. ),
  657. )
  658. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  659. case "clear_ips_c":
  660. err := t.inboundService.ClearClientIps(email)
  661. if err == nil {
  662. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.clearIpSuccess", "Email=="+email))
  663. t.searchClientIps(chatId, email, callbackQuery.Message.GetMessageID())
  664. } else {
  665. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  666. }
  667. case "ip_log":
  668. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.getIpLog", "Email=="+email))
  669. t.searchClientIps(chatId, email)
  670. case "tg_user":
  671. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.getUserInfo", "Email=="+email))
  672. t.clientTelegramUserInfo(chatId, email)
  673. case "tgid_remove":
  674. inlineKeyboard := tu.InlineKeyboard(
  675. tu.InlineKeyboardRow(
  676. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancel")).WithCallbackData(t.encodeQuery("tgid_cancel "+email)),
  677. ),
  678. tu.InlineKeyboardRow(
  679. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmRemoveTGUser")).WithCallbackData(t.encodeQuery("tgid_remove_c "+email)),
  680. ),
  681. )
  682. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  683. case "tgid_remove_c":
  684. traffic, err := t.inboundService.GetClientTrafficByEmail(email)
  685. if err != nil || traffic == nil {
  686. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  687. return
  688. }
  689. needRestart, err := t.inboundService.SetClientTelegramUserID(traffic.Id, EmptyTelegramUserID)
  690. if needRestart {
  691. t.xrayService.SetToNeedRestart()
  692. }
  693. if err == nil {
  694. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.removedTGUserSuccess", "Email=="+email))
  695. t.clientTelegramUserInfo(chatId, email, callbackQuery.Message.GetMessageID())
  696. } else {
  697. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  698. }
  699. case "toggle_enable":
  700. inlineKeyboard := tu.InlineKeyboard(
  701. tu.InlineKeyboardRow(
  702. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancel")).WithCallbackData(t.encodeQuery("client_cancel "+email)),
  703. ),
  704. tu.InlineKeyboardRow(
  705. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.confirmToggle")).WithCallbackData(t.encodeQuery("toggle_enable_c "+email)),
  706. ),
  707. )
  708. t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard)
  709. case "toggle_enable_c":
  710. enabled, needRestart, err := t.inboundService.ToggleClientEnableByEmail(email)
  711. if needRestart {
  712. t.xrayService.SetToNeedRestart()
  713. }
  714. if err == nil {
  715. if enabled {
  716. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.enableSuccess", "Email=="+email))
  717. } else {
  718. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.disableSuccess", "Email=="+email))
  719. }
  720. t.searchClient(chatId, email, callbackQuery.Message.GetMessageID())
  721. } else {
  722. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.errorOperation"))
  723. }
  724. case "get_clients":
  725. inboundId := dataArray[1]
  726. inboundIdInt, err := strconv.Atoi(inboundId)
  727. if err != nil {
  728. t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
  729. return
  730. }
  731. inbound, err := t.inboundService.GetInbound(inboundIdInt)
  732. if err != nil {
  733. t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
  734. return
  735. }
  736. clients, err := t.getInboundClients(inboundIdInt)
  737. if err != nil {
  738. t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
  739. return
  740. }
  741. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.chooseClient", "Inbound=="+inbound.Remark), clients)
  742. }
  743. return
  744. } else {
  745. switch callbackQuery.Data {
  746. case "get_inbounds":
  747. inbounds, err := t.getInbounds()
  748. if err != nil {
  749. t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error())
  750. return
  751. }
  752. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.allClients"))
  753. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.chooseInbound"), inbounds)
  754. }
  755. }
  756. }
  757. switch callbackQuery.Data {
  758. case "get_usage":
  759. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.serverUsage"))
  760. t.getServerUsage(chatId)
  761. case "usage_refresh":
  762. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))
  763. t.getServerUsage(chatId, callbackQuery.Message.GetMessageID())
  764. case "inbounds":
  765. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.getInbounds"))
  766. t.SendMsgToTgbot(chatId, t.getInboundUsages())
  767. case "deplete_soon":
  768. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.depleteSoon"))
  769. t.getExhausted(chatId)
  770. case "get_backup":
  771. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.dbBackup"))
  772. t.sendBackup(chatId)
  773. case "get_banlogs":
  774. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.getBanLogs"))
  775. t.sendBanLogs(chatId, true)
  776. case "client_traffic":
  777. tgUserID := callbackQuery.From.ID
  778. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.clientUsage"))
  779. t.getClientUsage(chatId, tgUserID)
  780. case "client_commands":
  781. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.commands"))
  782. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.commands.helpClientCommands"))
  783. case "onlines":
  784. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.onlines"))
  785. t.onlineClients(chatId)
  786. case "onlines_refresh":
  787. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation"))
  788. t.onlineClients(chatId, callbackQuery.Message.GetMessageID())
  789. case "commands":
  790. t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.buttons.commands"))
  791. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.commands.helpAdminCommands"))
  792. }
  793. }
  794. func checkAdmin(tgId int64) bool {
  795. for _, adminId := range adminIds {
  796. if adminId == tgId {
  797. return true
  798. }
  799. }
  800. return false
  801. }
  802. func (t *Tgbot) SendAnswer(chatId int64, msg string, isAdmin bool) {
  803. numericKeyboard := tu.InlineKeyboard(
  804. tu.InlineKeyboardRow(
  805. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.serverUsage")).WithCallbackData(t.encodeQuery("get_usage")),
  806. ),
  807. tu.InlineKeyboardRow(
  808. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.dbBackup")).WithCallbackData(t.encodeQuery("get_backup")),
  809. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.getBanLogs")).WithCallbackData(t.encodeQuery("get_banlogs")),
  810. ),
  811. tu.InlineKeyboardRow(
  812. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.getInbounds")).WithCallbackData(t.encodeQuery("inbounds")),
  813. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.depleteSoon")).WithCallbackData(t.encodeQuery("deplete_soon")),
  814. ),
  815. tu.InlineKeyboardRow(
  816. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.commands")).WithCallbackData(t.encodeQuery("commands")),
  817. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.onlines")).WithCallbackData(t.encodeQuery("onlines")),
  818. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.allClients")).WithCallbackData(t.encodeQuery("get_inbounds")),
  819. ),
  820. )
  821. numericKeyboardClient := tu.InlineKeyboard(
  822. tu.InlineKeyboardRow(
  823. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.clientUsage")).WithCallbackData(t.encodeQuery("client_traffic")),
  824. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.commands")).WithCallbackData(t.encodeQuery("client_commands")),
  825. ),
  826. )
  827. var ReplyMarkup telego.ReplyMarkup
  828. if isAdmin {
  829. ReplyMarkup = numericKeyboard
  830. } else {
  831. ReplyMarkup = numericKeyboardClient
  832. }
  833. t.SendMsgToTgbot(chatId, msg, ReplyMarkup)
  834. }
  835. func (t *Tgbot) SendMsgToTgbot(chatId int64, msg string, replyMarkup ...telego.ReplyMarkup) {
  836. if !isRunning {
  837. return
  838. }
  839. if msg == "" {
  840. logger.Info("[tgbot] message is empty!")
  841. return
  842. }
  843. var allMessages []string
  844. limit := 2000
  845. // paging message if it is big
  846. if len(msg) > limit {
  847. messages := strings.Split(msg, "\r\n\r\n")
  848. lastIndex := -1
  849. for _, message := range messages {
  850. if (len(allMessages) == 0) || (len(allMessages[lastIndex])+len(message) > limit) {
  851. allMessages = append(allMessages, message)
  852. lastIndex++
  853. } else {
  854. allMessages[lastIndex] += "\r\n\r\n" + message
  855. }
  856. }
  857. if strings.TrimSpace(allMessages[len(allMessages)-1]) == "" {
  858. allMessages = allMessages[:len(allMessages)-1]
  859. }
  860. } else {
  861. allMessages = append(allMessages, msg)
  862. }
  863. for n, message := range allMessages {
  864. params := telego.SendMessageParams{
  865. ChatID: tu.ID(chatId),
  866. Text: message,
  867. ParseMode: "HTML",
  868. }
  869. // only add replyMarkup to last message
  870. if len(replyMarkup) > 0 && n == (len(allMessages)-1) {
  871. params.ReplyMarkup = replyMarkup[0]
  872. }
  873. _, err := bot.SendMessage(&params)
  874. if err != nil {
  875. logger.Warning("Error sending telegram message :", err)
  876. }
  877. time.Sleep(500 * time.Millisecond)
  878. }
  879. }
  880. func (t *Tgbot) SendMsgToTgbotAdmins(msg string, replyMarkup ...telego.ReplyMarkup) {
  881. if len(replyMarkup) > 0 {
  882. for _, adminId := range adminIds {
  883. t.SendMsgToTgbot(adminId, msg, replyMarkup[0])
  884. }
  885. } else {
  886. for _, adminId := range adminIds {
  887. t.SendMsgToTgbot(adminId, msg)
  888. }
  889. }
  890. }
  891. func (t *Tgbot) SendReport() {
  892. runTime, err := t.settingService.GetTgbotRuntime()
  893. if err == nil && len(runTime) > 0 {
  894. msg := ""
  895. msg += t.I18nBot("tgbot.messages.report", "RunTime=="+runTime)
  896. msg += t.I18nBot("tgbot.messages.datetime", "DateTime=="+time.Now().Format("2006-01-02 15:04:05"))
  897. t.SendMsgToTgbotAdmins(msg)
  898. }
  899. info := t.sendServerUsage()
  900. t.SendMsgToTgbotAdmins(info)
  901. t.sendExhaustedToAdmins()
  902. t.notifyExhausted()
  903. backupEnable, err := t.settingService.GetTgBotBackup()
  904. if err == nil && backupEnable {
  905. t.SendBackupToAdmins()
  906. }
  907. }
  908. func (t *Tgbot) SendBackupToAdmins() {
  909. if !t.IsRunning() {
  910. return
  911. }
  912. for _, adminId := range adminIds {
  913. t.sendBackup(int64(adminId))
  914. }
  915. }
  916. func (t *Tgbot) sendExhaustedToAdmins() {
  917. if !t.IsRunning() {
  918. return
  919. }
  920. for _, adminId := range adminIds {
  921. t.getExhausted(int64(adminId))
  922. }
  923. }
  924. func (t *Tgbot) getServerUsage(chatId int64, messageID ...int) string {
  925. info := t.prepareServerUsageInfo()
  926. keyboard := tu.InlineKeyboard(tu.InlineKeyboardRow(
  927. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.refresh")).WithCallbackData(t.encodeQuery("usage_refresh"))))
  928. if len(messageID) > 0 {
  929. t.editMessageTgBot(chatId, messageID[0], info, keyboard)
  930. } else {
  931. t.SendMsgToTgbot(chatId, info, keyboard)
  932. }
  933. return info
  934. }
  935. // Send server usage without an inline keyboard
  936. func (t *Tgbot) sendServerUsage() string {
  937. info := t.prepareServerUsageInfo()
  938. return info
  939. }
  940. func (t *Tgbot) prepareServerUsageInfo() string {
  941. info, ipv4, ipv6 := "", "", ""
  942. // get latest status of server
  943. t.lastStatus = t.serverService.GetStatus(t.lastStatus)
  944. onlines := p.GetOnlineClients()
  945. info += t.I18nBot("tgbot.messages.hostname", "Hostname=="+hostname)
  946. info += t.I18nBot("tgbot.messages.version", "Version=="+config.GetVersion())
  947. info += t.I18nBot("tgbot.messages.xrayVersion", "XrayVersion=="+fmt.Sprint(t.lastStatus.Xray.Version))
  948. // get ip address
  949. netInterfaces, err := net.Interfaces()
  950. if err != nil {
  951. logger.Error("net.Interfaces failed, err: ", err.Error())
  952. info += t.I18nBot("tgbot.messages.ip", "IP=="+t.I18nBot("tgbot.unknown"))
  953. info += "\r\n"
  954. } else {
  955. for i := 0; i < len(netInterfaces); i++ {
  956. if (netInterfaces[i].Flags & net.FlagUp) != 0 {
  957. addrs, _ := netInterfaces[i].Addrs()
  958. for _, address := range addrs {
  959. if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
  960. if ipnet.IP.To4() != nil {
  961. ipv4 += ipnet.IP.String() + " "
  962. } else if ipnet.IP.To16() != nil && !ipnet.IP.IsLinkLocalUnicast() {
  963. ipv6 += ipnet.IP.String() + " "
  964. }
  965. }
  966. }
  967. }
  968. }
  969. info += t.I18nBot("tgbot.messages.ipv4", "IPv4=="+ipv4)
  970. info += t.I18nBot("tgbot.messages.ipv6", "IPv6=="+ipv6)
  971. }
  972. info += t.I18nBot("tgbot.messages.serverUpTime", "UpTime=="+strconv.FormatUint(t.lastStatus.Uptime/86400, 10), "Unit=="+t.I18nBot("tgbot.days"))
  973. info += t.I18nBot("tgbot.messages.serverLoad", "Load1=="+strconv.FormatFloat(t.lastStatus.Loads[0], 'f', 2, 64), "Load2=="+strconv.FormatFloat(t.lastStatus.Loads[1], 'f', 2, 64), "Load3=="+strconv.FormatFloat(t.lastStatus.Loads[2], 'f', 2, 64))
  974. info += t.I18nBot("tgbot.messages.serverMemory", "Current=="+common.FormatTraffic(int64(t.lastStatus.Mem.Current)), "Total=="+common.FormatTraffic(int64(t.lastStatus.Mem.Total)))
  975. info += t.I18nBot("tgbot.messages.onlinesCount", "Count=="+fmt.Sprint(len(onlines)))
  976. info += t.I18nBot("tgbot.messages.tcpCount", "Count=="+strconv.Itoa(t.lastStatus.TcpCount))
  977. info += t.I18nBot("tgbot.messages.udpCount", "Count=="+strconv.Itoa(t.lastStatus.UdpCount))
  978. info += t.I18nBot("tgbot.messages.traffic", "Total=="+common.FormatTraffic(int64(t.lastStatus.NetTraffic.Sent+t.lastStatus.NetTraffic.Recv)), "Upload=="+common.FormatTraffic(int64(t.lastStatus.NetTraffic.Sent)), "Download=="+common.FormatTraffic(int64(t.lastStatus.NetTraffic.Recv)))
  979. info += t.I18nBot("tgbot.messages.xrayStatus", "State=="+fmt.Sprint(t.lastStatus.Xray.State))
  980. return info
  981. }
  982. func (t *Tgbot) UserLoginNotify(username string, password string, ip string, time string, status LoginStatus) {
  983. if !t.IsRunning() {
  984. return
  985. }
  986. if username == "" || ip == "" || time == "" {
  987. logger.Warning("UserLoginNotify failed, invalid info!")
  988. return
  989. }
  990. loginNotifyEnabled, err := t.settingService.GetTgBotLoginNotify()
  991. if err != nil || !loginNotifyEnabled {
  992. return
  993. }
  994. msg := ""
  995. if status == LoginSuccess {
  996. msg += t.I18nBot("tgbot.messages.loginSuccess")
  997. msg += t.I18nBot("tgbot.messages.hostname", "Hostname=="+hostname)
  998. } else if status == LoginFail {
  999. msg += t.I18nBot("tgbot.messages.loginFailed")
  1000. msg += t.I18nBot("tgbot.messages.hostname", "Hostname=="+hostname)
  1001. msg += t.I18nBot("tgbot.messages.password", "Password=="+password)
  1002. }
  1003. msg += t.I18nBot("tgbot.messages.username", "Username=="+username)
  1004. msg += t.I18nBot("tgbot.messages.ip", "IP=="+ip)
  1005. msg += t.I18nBot("tgbot.messages.time", "Time=="+time)
  1006. t.SendMsgToTgbotAdmins(msg)
  1007. }
  1008. func (t *Tgbot) getInboundUsages() string {
  1009. info := ""
  1010. // get traffic
  1011. inbounds, err := t.inboundService.GetAllInbounds()
  1012. if err != nil {
  1013. logger.Warning("GetAllInbounds run failed:", err)
  1014. info += t.I18nBot("tgbot.answers.getInboundsFailed")
  1015. } else {
  1016. // NOTE:If there no any sessions here,need to notify here
  1017. // TODO:Sub-node push, automatic conversion format
  1018. for _, inbound := range inbounds {
  1019. info += t.I18nBot("tgbot.messages.inbound", "Remark=="+inbound.Remark)
  1020. info += t.I18nBot("tgbot.messages.port", "Port=="+strconv.Itoa(inbound.Port))
  1021. info += t.I18nBot("tgbot.messages.traffic", "Total=="+common.FormatTraffic((inbound.Up+inbound.Down)), "Upload=="+common.FormatTraffic(inbound.Up), "Download=="+common.FormatTraffic(inbound.Down))
  1022. if inbound.ExpiryTime == 0 {
  1023. info += t.I18nBot("tgbot.messages.expire", "Time=="+t.I18nBot("tgbot.unlimited"))
  1024. } else {
  1025. info += t.I18nBot("tgbot.messages.expire", "Time=="+time.Unix((inbound.ExpiryTime/1000), 0).Format("2006-01-02 15:04:05"))
  1026. }
  1027. info += "\r\n"
  1028. }
  1029. }
  1030. return info
  1031. }
  1032. func (t *Tgbot) getInbounds() (*telego.InlineKeyboardMarkup, error) {
  1033. inbounds, err := t.inboundService.GetAllInbounds()
  1034. var buttons []telego.InlineKeyboardButton
  1035. if err != nil {
  1036. logger.Warning("GetAllInbounds run failed:", err)
  1037. return nil, errors.New(t.I18nBot("tgbot.answers.getInboundsFailed"))
  1038. } else {
  1039. if len(inbounds) > 0 {
  1040. for _, inbound := range inbounds {
  1041. status := "❌"
  1042. if inbound.Enable {
  1043. status = "✅"
  1044. }
  1045. buttons = append(buttons, tu.InlineKeyboardButton(fmt.Sprintf("%v - %v", inbound.Remark, status)).WithCallbackData(t.encodeQuery("get_clients "+strconv.Itoa(inbound.Id))))
  1046. }
  1047. } else {
  1048. logger.Warning("GetAllInbounds run failed:", err)
  1049. return nil, errors.New(t.I18nBot("tgbot.answers.getInboundsFailed"))
  1050. }
  1051. }
  1052. cols := 0
  1053. if len(buttons) < 6 {
  1054. cols = 3
  1055. } else {
  1056. cols = 2
  1057. }
  1058. keyboard := tu.InlineKeyboardGrid(tu.InlineKeyboardCols(cols, buttons...))
  1059. return keyboard, nil
  1060. }
  1061. func (t *Tgbot) getInboundClients(id int) (*telego.InlineKeyboardMarkup, error) {
  1062. inbound, err := t.inboundService.GetInbound(id)
  1063. if err != nil {
  1064. logger.Warning("getIboundClients run failed:", err)
  1065. return nil, errors.New(t.I18nBot("tgbot.answers.getInboundsFailed"))
  1066. }
  1067. clients, err := t.inboundService.GetClients(inbound)
  1068. var buttons []telego.InlineKeyboardButton
  1069. if err != nil {
  1070. logger.Warning("GetInboundClients run failed:", err)
  1071. return nil, errors.New(t.I18nBot("tgbot.answers.getInboundsFailed"))
  1072. } else {
  1073. if len(clients) > 0 {
  1074. for _, client := range clients {
  1075. buttons = append(buttons, tu.InlineKeyboardButton(client.Email).WithCallbackData(t.encodeQuery("client_get_usage "+client.Email)))
  1076. }
  1077. } else {
  1078. return nil, errors.New(t.I18nBot("tgbot.answers.getClientsFailed"))
  1079. }
  1080. }
  1081. cols := 0
  1082. if len(buttons) < 6 {
  1083. cols = 3
  1084. } else {
  1085. cols = 2
  1086. }
  1087. keyboard := tu.InlineKeyboardGrid(tu.InlineKeyboardCols(cols, buttons...))
  1088. return keyboard, nil
  1089. }
  1090. func (t *Tgbot) clientInfoMsg(
  1091. traffic *xray.ClientTraffic,
  1092. printEnabled bool,
  1093. printOnline bool,
  1094. printActive bool,
  1095. printDate bool,
  1096. printTraffic bool,
  1097. printRefreshed bool,
  1098. ) string {
  1099. now := time.Now().Unix()
  1100. expiryTime := ""
  1101. flag := false
  1102. diff := traffic.ExpiryTime/1000 - now
  1103. if traffic.ExpiryTime == 0 {
  1104. expiryTime = t.I18nBot("tgbot.unlimited")
  1105. } else if diff > 172800 || !traffic.Enable {
  1106. expiryTime = time.Unix((traffic.ExpiryTime / 1000), 0).Format("2006-01-02 15:04:05")
  1107. } else if traffic.ExpiryTime < 0 {
  1108. expiryTime = fmt.Sprintf("%d %s", traffic.ExpiryTime/-86400000, t.I18nBot("tgbot.days"))
  1109. flag = true
  1110. } else {
  1111. expiryTime = fmt.Sprintf("%d %s", diff/3600, t.I18nBot("tgbot.hours"))
  1112. flag = true
  1113. }
  1114. total := ""
  1115. if traffic.Total == 0 {
  1116. total = t.I18nBot("tgbot.unlimited")
  1117. } else {
  1118. total = common.FormatTraffic((traffic.Total))
  1119. }
  1120. enabled := ""
  1121. isEnabled, err := t.inboundService.checkIsEnabledByEmail(traffic.Email)
  1122. if err != nil {
  1123. logger.Warning(err)
  1124. enabled = t.I18nBot("tgbot.wentWrong")
  1125. } else if isEnabled {
  1126. enabled = t.I18nBot("tgbot.messages.yes")
  1127. } else {
  1128. enabled = t.I18nBot("tgbot.messages.no")
  1129. }
  1130. active := ""
  1131. if traffic.Enable {
  1132. active = t.I18nBot("tgbot.messages.yes")
  1133. } else {
  1134. active = t.I18nBot("tgbot.messages.no")
  1135. }
  1136. status := t.I18nBot("tgbot.offline")
  1137. if p.IsRunning() {
  1138. for _, online := range p.GetOnlineClients() {
  1139. if online == traffic.Email {
  1140. status = t.I18nBot("tgbot.online")
  1141. break
  1142. }
  1143. }
  1144. }
  1145. output := ""
  1146. output += t.I18nBot("tgbot.messages.email", "Email=="+traffic.Email)
  1147. if printEnabled {
  1148. output += t.I18nBot("tgbot.messages.enabled", "Enable=="+enabled)
  1149. }
  1150. if printOnline {
  1151. output += t.I18nBot("tgbot.messages.online", "Status=="+status)
  1152. }
  1153. if printActive {
  1154. output += t.I18nBot("tgbot.messages.active", "Enable=="+active)
  1155. }
  1156. if printDate {
  1157. if flag {
  1158. output += t.I18nBot("tgbot.messages.expireIn", "Time=="+expiryTime)
  1159. } else {
  1160. output += t.I18nBot("tgbot.messages.expire", "Time=="+expiryTime)
  1161. }
  1162. }
  1163. if printTraffic {
  1164. output += t.I18nBot("tgbot.messages.upload", "Upload=="+common.FormatTraffic(traffic.Up))
  1165. output += t.I18nBot("tgbot.messages.download", "Download=="+common.FormatTraffic(traffic.Down))
  1166. output += t.I18nBot("tgbot.messages.total", "UpDown=="+common.FormatTraffic((traffic.Up+traffic.Down)), "Total=="+total)
  1167. }
  1168. if printRefreshed {
  1169. output += t.I18nBot("tgbot.messages.refreshedOn", "Time=="+time.Now().Format("2006-01-02 15:04:05"))
  1170. }
  1171. return output
  1172. }
  1173. func (t *Tgbot) getClientUsage(chatId int64, tgUserID int64, email ...string) {
  1174. traffics, err := t.inboundService.GetClientTrafficTgBot(tgUserID)
  1175. if err != nil {
  1176. logger.Warning(err)
  1177. msg := t.I18nBot("tgbot.wentWrong")
  1178. t.SendMsgToTgbot(chatId, msg)
  1179. return
  1180. }
  1181. if len(traffics) == 0 {
  1182. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.answers.askToAddUserId", "TgUserID=="+strconv.FormatInt(tgUserID, 10)))
  1183. return
  1184. }
  1185. output := ""
  1186. if len(traffics) > 0 {
  1187. if len(email) > 0 {
  1188. for _, traffic := range traffics {
  1189. if traffic.Email == email[0] {
  1190. output := t.clientInfoMsg(traffic, true, true, true, true, true, true)
  1191. t.SendMsgToTgbot(chatId, output)
  1192. return
  1193. }
  1194. }
  1195. msg := t.I18nBot("tgbot.noResult")
  1196. t.SendMsgToTgbot(chatId, msg)
  1197. return
  1198. } else {
  1199. for _, traffic := range traffics {
  1200. output += t.clientInfoMsg(traffic, true, true, true, true, true, false)
  1201. output += "\r\n"
  1202. }
  1203. }
  1204. }
  1205. output += t.I18nBot("tgbot.messages.refreshedOn", "Time=="+time.Now().Format("2006-01-02 15:04:05"))
  1206. t.SendMsgToTgbot(chatId, output)
  1207. output = t.I18nBot("tgbot.commands.pleaseChoose")
  1208. t.SendAnswer(chatId, output, false)
  1209. }
  1210. func (t *Tgbot) searchClientIps(chatId int64, email string, messageID ...int) {
  1211. ips, err := t.inboundService.GetInboundClientIps(email)
  1212. if err != nil || len(ips) == 0 {
  1213. ips = t.I18nBot("tgbot.noIpRecord")
  1214. }
  1215. output := ""
  1216. output += t.I18nBot("tgbot.messages.email", "Email=="+email)
  1217. output += t.I18nBot("tgbot.messages.ips", "IPs=="+ips)
  1218. output += t.I18nBot("tgbot.messages.refreshedOn", "Time=="+time.Now().Format("2006-01-02 15:04:05"))
  1219. inlineKeyboard := tu.InlineKeyboard(
  1220. tu.InlineKeyboardRow(
  1221. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.refresh")).WithCallbackData(t.encodeQuery("ips_refresh "+email)),
  1222. ),
  1223. tu.InlineKeyboardRow(
  1224. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.clearIPs")).WithCallbackData(t.encodeQuery("clear_ips "+email)),
  1225. ),
  1226. )
  1227. if len(messageID) > 0 {
  1228. t.editMessageTgBot(chatId, messageID[0], output, inlineKeyboard)
  1229. } else {
  1230. t.SendMsgToTgbot(chatId, output, inlineKeyboard)
  1231. }
  1232. }
  1233. func (t *Tgbot) clientTelegramUserInfo(chatId int64, email string, messageID ...int) {
  1234. traffic, client, err := t.inboundService.GetClientByEmail(email)
  1235. if err != nil {
  1236. logger.Warning(err)
  1237. msg := t.I18nBot("tgbot.wentWrong")
  1238. t.SendMsgToTgbot(chatId, msg)
  1239. return
  1240. }
  1241. if client == nil {
  1242. msg := t.I18nBot("tgbot.noResult")
  1243. t.SendMsgToTgbot(chatId, msg)
  1244. return
  1245. }
  1246. tgId := "None"
  1247. if client.TgID != 0 {
  1248. tgId = strconv.FormatInt(client.TgID, 10)
  1249. }
  1250. output := ""
  1251. output += t.I18nBot("tgbot.messages.email", "Email=="+email)
  1252. output += t.I18nBot("tgbot.messages.TGUser", "TelegramID=="+tgId)
  1253. output += t.I18nBot("tgbot.messages.refreshedOn", "Time=="+time.Now().Format("2006-01-02 15:04:05"))
  1254. inlineKeyboard := tu.InlineKeyboard(
  1255. tu.InlineKeyboardRow(
  1256. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.refresh")).WithCallbackData(t.encodeQuery("tgid_refresh "+email)),
  1257. ),
  1258. tu.InlineKeyboardRow(
  1259. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.removeTGUser")).WithCallbackData(t.encodeQuery("tgid_remove "+email)),
  1260. ),
  1261. )
  1262. if len(messageID) > 0 {
  1263. t.editMessageTgBot(chatId, messageID[0], output, inlineKeyboard)
  1264. } else {
  1265. t.SendMsgToTgbot(chatId, output, inlineKeyboard)
  1266. requestUser := telego.KeyboardButtonRequestUsers{
  1267. RequestID: int32(traffic.Id),
  1268. UserIsBot: new(bool),
  1269. }
  1270. keyboard := tu.Keyboard(
  1271. tu.KeyboardRow(
  1272. tu.KeyboardButton(t.I18nBot("tgbot.buttons.selectTGUser")).WithRequestUsers(&requestUser),
  1273. ),
  1274. tu.KeyboardRow(
  1275. tu.KeyboardButton(t.I18nBot("tgbot.buttons.closeKeyboard")),
  1276. ),
  1277. ).WithIsPersistent().WithResizeKeyboard()
  1278. t.SendMsgToTgbot(chatId, t.I18nBot("tgbot.buttons.selectOneTGUser"), keyboard)
  1279. }
  1280. }
  1281. func (t *Tgbot) searchClient(chatId int64, email string, messageID ...int) {
  1282. traffic, err := t.inboundService.GetClientTrafficByEmail(email)
  1283. if err != nil {
  1284. logger.Warning(err)
  1285. msg := t.I18nBot("tgbot.wentWrong")
  1286. t.SendMsgToTgbot(chatId, msg)
  1287. return
  1288. }
  1289. if traffic == nil {
  1290. msg := t.I18nBot("tgbot.noResult")
  1291. t.SendMsgToTgbot(chatId, msg)
  1292. return
  1293. }
  1294. output := t.clientInfoMsg(traffic, true, true, true, true, true, true)
  1295. inlineKeyboard := tu.InlineKeyboard(
  1296. tu.InlineKeyboardRow(
  1297. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.refresh")).WithCallbackData(t.encodeQuery("client_refresh "+email)),
  1298. ),
  1299. tu.InlineKeyboardRow(
  1300. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.resetTraffic")).WithCallbackData(t.encodeQuery("reset_traffic "+email)),
  1301. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.limitTraffic")).WithCallbackData(t.encodeQuery("limit_traffic "+email)),
  1302. ),
  1303. tu.InlineKeyboardRow(
  1304. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.resetExpire")).WithCallbackData(t.encodeQuery("reset_exp "+email)),
  1305. ),
  1306. tu.InlineKeyboardRow(
  1307. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.ipLog")).WithCallbackData(t.encodeQuery("ip_log "+email)),
  1308. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.ipLimit")).WithCallbackData(t.encodeQuery("ip_limit "+email)),
  1309. ),
  1310. tu.InlineKeyboardRow(
  1311. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.setTGUser")).WithCallbackData(t.encodeQuery("tg_user "+email)),
  1312. ),
  1313. tu.InlineKeyboardRow(
  1314. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.toggle")).WithCallbackData(t.encodeQuery("toggle_enable "+email)),
  1315. ),
  1316. )
  1317. if len(messageID) > 0 {
  1318. t.editMessageTgBot(chatId, messageID[0], output, inlineKeyboard)
  1319. } else {
  1320. t.SendMsgToTgbot(chatId, output, inlineKeyboard)
  1321. }
  1322. }
  1323. func (t *Tgbot) searchInbound(chatId int64, remark string) {
  1324. inbounds, err := t.inboundService.SearchInbounds(remark)
  1325. if err != nil {
  1326. logger.Warning(err)
  1327. msg := t.I18nBot("tgbot.wentWrong")
  1328. t.SendMsgToTgbot(chatId, msg)
  1329. return
  1330. }
  1331. if len(inbounds) == 0 {
  1332. msg := t.I18nBot("tgbot.noInbounds")
  1333. t.SendMsgToTgbot(chatId, msg)
  1334. return
  1335. }
  1336. for _, inbound := range inbounds {
  1337. info := ""
  1338. info += t.I18nBot("tgbot.messages.inbound", "Remark=="+inbound.Remark)
  1339. info += t.I18nBot("tgbot.messages.port", "Port=="+strconv.Itoa(inbound.Port))
  1340. info += t.I18nBot("tgbot.messages.traffic", "Total=="+common.FormatTraffic((inbound.Up+inbound.Down)), "Upload=="+common.FormatTraffic(inbound.Up), "Download=="+common.FormatTraffic(inbound.Down))
  1341. if inbound.ExpiryTime == 0 {
  1342. info += t.I18nBot("tgbot.messages.expire", "Time=="+t.I18nBot("tgbot.unlimited"))
  1343. } else {
  1344. info += t.I18nBot("tgbot.messages.expire", "Time=="+time.Unix((inbound.ExpiryTime/1000), 0).Format("2006-01-02 15:04:05"))
  1345. }
  1346. t.SendMsgToTgbot(chatId, info)
  1347. if len(inbound.ClientStats) > 0 {
  1348. output := ""
  1349. for _, traffic := range inbound.ClientStats {
  1350. output += t.clientInfoMsg(&traffic, true, true, true, true, true, true)
  1351. }
  1352. t.SendMsgToTgbot(chatId, output)
  1353. }
  1354. }
  1355. }
  1356. func (t *Tgbot) getExhausted(chatId int64) {
  1357. trDiff := int64(0)
  1358. exDiff := int64(0)
  1359. now := time.Now().Unix() * 1000
  1360. var exhaustedInbounds []model.Inbound
  1361. var exhaustedClients []xray.ClientTraffic
  1362. var disabledInbounds []model.Inbound
  1363. var disabledClients []xray.ClientTraffic
  1364. TrafficThreshold, err := t.settingService.GetTrafficDiff()
  1365. if err == nil && TrafficThreshold > 0 {
  1366. trDiff = int64(TrafficThreshold) * 1073741824
  1367. }
  1368. ExpireThreshold, err := t.settingService.GetExpireDiff()
  1369. if err == nil && ExpireThreshold > 0 {
  1370. exDiff = int64(ExpireThreshold) * 86400000
  1371. }
  1372. inbounds, err := t.inboundService.GetAllInbounds()
  1373. if err != nil {
  1374. logger.Warning("Unable to load Inbounds", err)
  1375. }
  1376. for _, inbound := range inbounds {
  1377. if inbound.Enable {
  1378. if (inbound.ExpiryTime > 0 && (inbound.ExpiryTime-now < exDiff)) ||
  1379. (inbound.Total > 0 && (inbound.Total-(inbound.Up+inbound.Down) < trDiff)) {
  1380. exhaustedInbounds = append(exhaustedInbounds, *inbound)
  1381. }
  1382. if len(inbound.ClientStats) > 0 {
  1383. for _, client := range inbound.ClientStats {
  1384. if client.Enable {
  1385. if (client.ExpiryTime > 0 && (client.ExpiryTime-now < exDiff)) ||
  1386. (client.Total > 0 && (client.Total-(client.Up+client.Down) < trDiff)) {
  1387. exhaustedClients = append(exhaustedClients, client)
  1388. }
  1389. } else {
  1390. disabledClients = append(disabledClients, client)
  1391. }
  1392. }
  1393. }
  1394. } else {
  1395. disabledInbounds = append(disabledInbounds, *inbound)
  1396. }
  1397. }
  1398. // Inbounds
  1399. output := ""
  1400. output += t.I18nBot("tgbot.messages.exhaustedCount", "Type=="+t.I18nBot("tgbot.inbounds"))
  1401. output += t.I18nBot("tgbot.messages.disabled", "Disabled=="+strconv.Itoa(len(disabledInbounds)))
  1402. output += t.I18nBot("tgbot.messages.depleteSoon", "Deplete=="+strconv.Itoa(len(exhaustedInbounds)))
  1403. if len(exhaustedInbounds) > 0 {
  1404. output += t.I18nBot("tgbot.messages.depleteSoon", "Deplete=="+t.I18nBot("tgbot.inbounds"))
  1405. for _, inbound := range exhaustedInbounds {
  1406. output += t.I18nBot("tgbot.messages.inbound", "Remark=="+inbound.Remark)
  1407. output += t.I18nBot("tgbot.messages.port", "Port=="+strconv.Itoa(inbound.Port))
  1408. output += t.I18nBot("tgbot.messages.traffic", "Total=="+common.FormatTraffic((inbound.Up+inbound.Down)), "Upload=="+common.FormatTraffic(inbound.Up), "Download=="+common.FormatTraffic(inbound.Down))
  1409. if inbound.ExpiryTime == 0 {
  1410. output += t.I18nBot("tgbot.messages.expire", "Time=="+t.I18nBot("tgbot.unlimited"))
  1411. } else {
  1412. output += t.I18nBot("tgbot.messages.expire", "Time=="+time.Unix((inbound.ExpiryTime/1000), 0).Format("2006-01-02 15:04:05"))
  1413. }
  1414. output += "\r\n"
  1415. }
  1416. }
  1417. // Clients
  1418. exhaustedCC := len(exhaustedClients)
  1419. output += t.I18nBot("tgbot.messages.exhaustedCount", "Type=="+t.I18nBot("tgbot.clients"))
  1420. output += t.I18nBot("tgbot.messages.disabled", "Disabled=="+strconv.Itoa(len(disabledClients)))
  1421. output += t.I18nBot("tgbot.messages.depleteSoon", "Deplete=="+strconv.Itoa(exhaustedCC))
  1422. if exhaustedCC > 0 {
  1423. output += t.I18nBot("tgbot.messages.depleteSoon", "Deplete=="+t.I18nBot("tgbot.clients"))
  1424. var buttons []telego.InlineKeyboardButton
  1425. for _, traffic := range exhaustedClients {
  1426. output += t.clientInfoMsg(&traffic, true, false, false, true, true, false)
  1427. output += "\r\n"
  1428. buttons = append(buttons, tu.InlineKeyboardButton(traffic.Email).WithCallbackData(t.encodeQuery("client_get_usage "+traffic.Email)))
  1429. }
  1430. cols := 0
  1431. if exhaustedCC < 11 {
  1432. cols = 1
  1433. } else {
  1434. cols = 2
  1435. }
  1436. output += t.I18nBot("tgbot.messages.refreshedOn", "Time=="+time.Now().Format("2006-01-02 15:04:05"))
  1437. keyboard := tu.InlineKeyboardGrid(tu.InlineKeyboardCols(cols, buttons...))
  1438. t.SendMsgToTgbot(chatId, output, keyboard)
  1439. } else {
  1440. output += t.I18nBot("tgbot.messages.refreshedOn", "Time=="+time.Now().Format("2006-01-02 15:04:05"))
  1441. t.SendMsgToTgbot(chatId, output)
  1442. }
  1443. }
  1444. func (t *Tgbot) notifyExhausted() {
  1445. trDiff := int64(0)
  1446. exDiff := int64(0)
  1447. now := time.Now().Unix() * 1000
  1448. TrafficThreshold, err := t.settingService.GetTrafficDiff()
  1449. if err == nil && TrafficThreshold > 0 {
  1450. trDiff = int64(TrafficThreshold) * 1073741824
  1451. }
  1452. ExpireThreshold, err := t.settingService.GetExpireDiff()
  1453. if err == nil && ExpireThreshold > 0 {
  1454. exDiff = int64(ExpireThreshold) * 86400000
  1455. }
  1456. inbounds, err := t.inboundService.GetAllInbounds()
  1457. if err != nil {
  1458. logger.Warning("Unable to load Inbounds", err)
  1459. }
  1460. var chatIDsDone []int64
  1461. for _, inbound := range inbounds {
  1462. if inbound.Enable {
  1463. if len(inbound.ClientStats) > 0 {
  1464. clients, err := t.inboundService.GetClients(inbound)
  1465. if err == nil {
  1466. for _, client := range clients {
  1467. if client.TgID != 0 {
  1468. chatID := client.TgID
  1469. if !int64Contains(chatIDsDone, chatID) && !checkAdmin(chatID) {
  1470. var disabledClients []xray.ClientTraffic
  1471. var exhaustedClients []xray.ClientTraffic
  1472. traffics, err := t.inboundService.GetClientTrafficTgBot(client.TgID)
  1473. if err == nil && len(traffics) > 0 {
  1474. output := t.I18nBot("tgbot.messages.exhaustedCount", "Type=="+t.I18nBot("tgbot.clients"))
  1475. for _, traffic := range traffics {
  1476. if traffic.Enable {
  1477. if (traffic.ExpiryTime > 0 && (traffic.ExpiryTime-now < exDiff)) ||
  1478. (traffic.Total > 0 && (traffic.Total-(traffic.Up+traffic.Down) < trDiff)) {
  1479. exhaustedClients = append(exhaustedClients, *traffic)
  1480. }
  1481. } else {
  1482. disabledClients = append(disabledClients, *traffic)
  1483. }
  1484. }
  1485. if len(exhaustedClients) > 0 {
  1486. output += t.I18nBot("tgbot.messages.disabled", "Disabled=="+strconv.Itoa(len(disabledClients)))
  1487. if len(disabledClients) > 0 {
  1488. output += t.I18nBot("tgbot.clients") + ":\r\n"
  1489. for _, traffic := range disabledClients {
  1490. output += " " + traffic.Email
  1491. }
  1492. output += "\r\n"
  1493. }
  1494. output += "\r\n"
  1495. output += t.I18nBot("tgbot.messages.depleteSoon", "Deplete=="+strconv.Itoa(len(exhaustedClients)))
  1496. for _, traffic := range exhaustedClients {
  1497. output += t.clientInfoMsg(&traffic, true, false, false, true, true, false)
  1498. output += "\r\n"
  1499. }
  1500. t.SendMsgToTgbot(chatID, output)
  1501. }
  1502. chatIDsDone = append(chatIDsDone, chatID)
  1503. }
  1504. }
  1505. }
  1506. }
  1507. }
  1508. }
  1509. }
  1510. }
  1511. }
  1512. func int64Contains(slice []int64, item int64) bool {
  1513. for _, s := range slice {
  1514. if s == item {
  1515. return true
  1516. }
  1517. }
  1518. return false
  1519. }
  1520. func (t *Tgbot) onlineClients(chatId int64, messageID ...int) {
  1521. if !p.IsRunning() {
  1522. return
  1523. }
  1524. onlines := p.GetOnlineClients()
  1525. onlinesCount := len(onlines)
  1526. output := t.I18nBot("tgbot.messages.onlinesCount", "Count=="+fmt.Sprint(onlinesCount))
  1527. keyboard := tu.InlineKeyboard(tu.InlineKeyboardRow(
  1528. tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.refresh")).WithCallbackData(t.encodeQuery("onlines_refresh"))))
  1529. if onlinesCount > 0 {
  1530. var buttons []telego.InlineKeyboardButton
  1531. for _, online := range onlines {
  1532. buttons = append(buttons, tu.InlineKeyboardButton(online).WithCallbackData(t.encodeQuery("client_get_usage "+online)))
  1533. }
  1534. cols := 0
  1535. if onlinesCount < 21 {
  1536. cols = 2
  1537. } else if onlinesCount < 61 {
  1538. cols = 3
  1539. } else {
  1540. cols = 4
  1541. }
  1542. keyboard.InlineKeyboard = append(keyboard.InlineKeyboard, tu.InlineKeyboardCols(cols, buttons...)...)
  1543. }
  1544. if len(messageID) > 0 {
  1545. t.editMessageTgBot(chatId, messageID[0], output, keyboard)
  1546. } else {
  1547. t.SendMsgToTgbot(chatId, output, keyboard)
  1548. }
  1549. }
  1550. func (t *Tgbot) sendBackup(chatId int64) {
  1551. output := t.I18nBot("tgbot.messages.backupTime", "Time=="+time.Now().Format("2006-01-02 15:04:05"))
  1552. t.SendMsgToTgbot(chatId, output)
  1553. // Update by manually trigger a checkpoint operation
  1554. err := database.Checkpoint()
  1555. if err != nil {
  1556. logger.Error("Error in trigger a checkpoint operation: ", err)
  1557. }
  1558. file, err := os.Open(config.GetDBPath())
  1559. if err == nil {
  1560. document := tu.Document(
  1561. tu.ID(chatId),
  1562. tu.File(file),
  1563. )
  1564. _, err = bot.SendDocument(document)
  1565. if err != nil {
  1566. logger.Error("Error in uploading backup: ", err)
  1567. }
  1568. } else {
  1569. logger.Error("Error in opening db file for backup: ", err)
  1570. }
  1571. file, err = os.Open(xray.GetConfigPath())
  1572. if err == nil {
  1573. document := tu.Document(
  1574. tu.ID(chatId),
  1575. tu.File(file),
  1576. )
  1577. _, err = bot.SendDocument(document)
  1578. if err != nil {
  1579. logger.Error("Error in uploading config.json: ", err)
  1580. }
  1581. } else {
  1582. logger.Error("Error in opening config.json file for backup: ", err)
  1583. }
  1584. }
  1585. func (t *Tgbot) sendBanLogs(chatId int64, dt bool) {
  1586. if dt {
  1587. output := t.I18nBot("tgbot.messages.datetime", "DateTime=="+time.Now().Format("2006-01-02 15:04:05"))
  1588. t.SendMsgToTgbot(chatId, output)
  1589. }
  1590. file, err := os.Open(xray.GetIPLimitBannedPrevLogPath())
  1591. if err == nil {
  1592. // Check if the file is non-empty before attempting to upload
  1593. fileInfo, _ := file.Stat()
  1594. if fileInfo.Size() > 0 {
  1595. document := tu.Document(
  1596. tu.ID(chatId),
  1597. tu.File(file),
  1598. )
  1599. _, err = bot.SendDocument(document)
  1600. if err != nil {
  1601. logger.Error("Error in uploading IPLimitBannedPrevLog: ", err)
  1602. }
  1603. } else {
  1604. logger.Warning("IPLimitBannedPrevLog file is empty, not uploading.")
  1605. }
  1606. file.Close()
  1607. } else {
  1608. logger.Error("Error in opening IPLimitBannedPrevLog file for backup: ", err)
  1609. }
  1610. file, err = os.Open(xray.GetIPLimitBannedLogPath())
  1611. if err == nil {
  1612. // Check if the file is non-empty before attempting to upload
  1613. fileInfo, _ := file.Stat()
  1614. if fileInfo.Size() > 0 {
  1615. document := tu.Document(
  1616. tu.ID(chatId),
  1617. tu.File(file),
  1618. )
  1619. _, err = bot.SendDocument(document)
  1620. if err != nil {
  1621. logger.Error("Error in uploading IPLimitBannedLog: ", err)
  1622. }
  1623. } else {
  1624. logger.Warning("IPLimitBannedLog file is empty, not uploading.")
  1625. }
  1626. file.Close()
  1627. } else {
  1628. logger.Error("Error in opening IPLimitBannedLog file for backup: ", err)
  1629. }
  1630. }
  1631. func (t *Tgbot) sendCallbackAnswerTgBot(id string, message string) {
  1632. params := telego.AnswerCallbackQueryParams{
  1633. CallbackQueryID: id,
  1634. Text: message,
  1635. }
  1636. if err := bot.AnswerCallbackQuery(&params); err != nil {
  1637. logger.Warning(err)
  1638. }
  1639. }
  1640. func (t *Tgbot) editMessageCallbackTgBot(chatId int64, messageID int, inlineKeyboard *telego.InlineKeyboardMarkup) {
  1641. params := telego.EditMessageReplyMarkupParams{
  1642. ChatID: tu.ID(chatId),
  1643. MessageID: messageID,
  1644. ReplyMarkup: inlineKeyboard,
  1645. }
  1646. if _, err := bot.EditMessageReplyMarkup(&params); err != nil {
  1647. logger.Warning(err)
  1648. }
  1649. }
  1650. func (t *Tgbot) editMessageTgBot(chatId int64, messageID int, text string, inlineKeyboard ...*telego.InlineKeyboardMarkup) {
  1651. params := telego.EditMessageTextParams{
  1652. ChatID: tu.ID(chatId),
  1653. MessageID: messageID,
  1654. Text: text,
  1655. ParseMode: "HTML",
  1656. }
  1657. if len(inlineKeyboard) > 0 {
  1658. params.ReplyMarkup = inlineKeyboard[0]
  1659. }
  1660. if _, err := bot.EditMessageText(&params); err != nil {
  1661. logger.Warning(err)
  1662. }
  1663. }