tgbot.go 61 KB

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