diff --git a/main.go b/main.go index f5da0704..d857ab46 100644 --- a/main.go +++ b/main.go @@ -136,7 +136,7 @@ func updateTgbotEnableSts(status bool) { return } -func updateTgbotSetting(tgBotToken string, tgBotChatid int, tgBotRuntime string) { +func updateTgbotSetting(tgBotToken string, tgBotChatid string, tgBotRuntime string) { err := database.InitDB(config.GetDBPath()) if err != nil { fmt.Println(err) @@ -165,7 +165,7 @@ func updateTgbotSetting(tgBotToken string, tgBotChatid int, tgBotRuntime string) } } - if tgBotChatid != 0 { + if tgBotChatid != "" { err := settingService.SetTgBotChatId(tgBotChatid) if err != nil { fmt.Println(err) @@ -224,7 +224,7 @@ func main() { var username string var password string var tgbottoken string - var tgbotchatid int + var tgbotchatid string var enabletgbot bool var tgbotRuntime string var reset bool @@ -236,7 +236,7 @@ func main() { settingCmd.StringVar(&password, "password", "", "set login password") settingCmd.StringVar(&tgbottoken, "tgbottoken", "", "set telegrame bot token") settingCmd.StringVar(&tgbotRuntime, "tgbotRuntime", "", "set telegrame bot cron time") - settingCmd.IntVar(&tgbotchatid, "tgbotchatid", 0, "set telegrame bot chat id") + settingCmd.StringVar(&tgbotchatid, "tgbotchatid", "", "set telegrame bot chat id") settingCmd.BoolVar(&enabletgbot, "enabletgbot", false, "enable telegram bot notify") oldUsage := flag.Usage @@ -287,7 +287,7 @@ func main() { if show { showSetting(show) } - if (tgbottoken != "") || (tgbotchatid != 0) || (tgbotRuntime != "") { + if (tgbottoken != "") || (tgbotchatid != "") || (tgbotRuntime != "") { updateTgbotSetting(tgbottoken, tgbotchatid, tgbotRuntime) } default: diff --git a/web/assets/js/model/models.js b/web/assets/js/model/models.js index 5e8bf6e3..50cf1d99 100644 --- a/web/assets/js/model/models.js +++ b/web/assets/js/model/models.js @@ -172,7 +172,7 @@ class AllSetting { this.webBasePath = "/"; this.tgBotEnable = false; this.tgBotToken = ""; - this.tgBotChatId = 0; + this.tgBotChatId = ""; this.tgRunTime = ""; this.xrayTemplateConfig = ""; diff --git a/web/entity/entity.go b/web/entity/entity.go index f8572f66..ef8efdc1 100644 --- a/web/entity/entity.go +++ b/web/entity/entity.go @@ -34,7 +34,7 @@ type AllSetting struct { WebBasePath string `json:"webBasePath" form:"webBasePath"` TgBotEnable bool `json:"tgBotEnable" form:"tgBotEnable"` TgBotToken string `json:"tgBotToken" form:"tgBotToken"` - TgBotChatId int `json:"tgBotChatId" form:"tgBotChatId"` + TgBotChatId string `json:"tgBotChatId" form:"tgBotChatId"` TgRunTime string `json:"tgRunTime" form:"tgRunTime"` XrayTemplateConfig string `json:"xrayTemplateConfig" form:"xrayTemplateConfig"` diff --git a/web/job/stats_notify_job.go b/web/job/stats_notify_job.go index 689ba200..f23ff0a9 100644 --- a/web/job/stats_notify_job.go +++ b/web/job/stats_notify_job.go @@ -18,10 +18,8 @@ const ( ) type StatsNotifyJob struct { - enable bool xrayService service.XrayService inboundService service.InboundService - settingService service.SettingService tgbotService service.Tgbot } @@ -80,10 +78,10 @@ func (j *StatsNotifyJob) Run() { for _, inbound := range inbouds { info += fmt.Sprintf("Node name:%s\r\nPort:%d\r\nUpload↑:%s\r\nDownload↓:%s\r\nTotal:%s\r\n", inbound.Remark, inbound.Port, common.FormatTraffic(inbound.Up), common.FormatTraffic(inbound.Down), common.FormatTraffic((inbound.Up + inbound.Down))) if inbound.ExpiryTime == 0 { - info += fmt.Sprintf("Expire date:unlimited\r\n \r\n") + info += "Expire date:unlimited\r\n \r\n" } else { info += fmt.Sprintf("Expire date:%s\r\n \r\n", time.Unix((inbound.ExpiryTime/1000), 0).Format("2006-01-02 15:04:05")) } } - j.tgbotService.SendMsgToTgbot(info) + j.tgbotService.SendMsgToTgbotAdmins(info) } diff --git a/web/service/setting.go b/web/service/setting.go index 4302af34..e21729db 100644 --- a/web/service/setting.go +++ b/web/service/setting.go @@ -31,7 +31,7 @@ var defaultValueMap = map[string]string{ "timeLocation": "Asia/Tehran", "tgBotEnable": "false", "tgBotToken": "", - "tgBotChatId": "0", + "tgBotChatId": "", "tgRunTime": "", } @@ -202,12 +202,12 @@ func (s *SettingService) SetTgBotToken(token string) error { return s.setString("tgBotToken", token) } -func (s *SettingService) GetTgBotChatId() (int, error) { - return s.getInt("tgBotChatId") +func (s *SettingService) GetTgBotChatId() (string, error) { + return s.getString("tgBotChatId") } -func (s *SettingService) SetTgBotChatId(chatId int) error { - return s.setInt("tgBotChatId", chatId) +func (s *SettingService) SetTgBotChatId(chatIds string) error { + return s.setString("tgBotChatId", chatIds) } func (s *SettingService) SetTgbotenabled(value bool) error { diff --git a/web/service/tgbot.go b/web/service/tgbot.go index b7fd288b..74c380df 100644 --- a/web/service/tgbot.go +++ b/web/service/tgbot.go @@ -3,6 +3,8 @@ package service import ( "fmt" "os" + "strconv" + "strings" "time" "x-ui/logger" "x-ui/util/common" @@ -11,7 +13,7 @@ import ( ) var bot *tgbotapi.BotAPI -var tgBotid int +var adminIds []int64 var isRunning bool var numericKeyboard = tgbotapi.NewInlineKeyboardMarkup( @@ -43,12 +45,21 @@ func (t *Tgbot) Start() error { return err } - tgBotid, err = t.settingService.GetTgBotChatId() + tgBotid, err := t.settingService.GetTgBotChatId() if err != nil { logger.Warning("Get GetTgBotChatId failed:", err) return err } + for _, adminId := range strings.Split(tgBotid, ",") { + id, err := strconv.Atoi(adminId) + if err != nil { + logger.Warning("Failed to get IDs from GetTgBotChatId:", err) + return err + } + adminIds = append(adminIds, int64(id)) + } + bot, err = tgbotapi.NewBotAPI(tgBottoken) if err != nil { fmt.Println("Get tgbot's api error:", err) @@ -58,7 +69,7 @@ func (t *Tgbot) Start() error { // listen for TG bot income messages if !isRunning { - logger.Info("Telegram receiver starting") + logger.Info("Starting Telegram receiver ...") go t.OnReceive() isRunning = true } @@ -72,8 +83,9 @@ func (t *Tgbot) IsRunnging() bool { func (t *Tgbot) Stop() { bot.StopReceivingUpdates() - logger.Info("Send Kill to Telegram listener ...") + logger.Info("Stop Telegram receiver ...") isRunning = false + adminIds = nil } func (t *Tgbot) OnReceive() { @@ -84,7 +96,6 @@ func (t *Tgbot) OnReceive() { for update := range updates { if update.Message == nil { - if update.CallbackQuery != nil { // Respond to the callback query, telling Telegram to show the user // a message with the data received. @@ -142,10 +153,18 @@ func (t *Tgbot) OnReceive() { } } -func (t *Tgbot) SendMsgToTgbot(msg string) { - info := tgbotapi.NewMessage(int64(tgBotid), msg) - //msg.ReplyToMessageID = int(tgBotid) - bot.Send(info) +func (t *Tgbot) SendMsgToTgbot(tgid int64, msg string) { + info := tgbotapi.NewMessage(tgid, msg) + _, err := bot.Send(info) + if err != nil { + logger.Warning("Error sending telegram message :", err) + } +} + +func (t *Tgbot) SendMsgToTgbotAdmins(msg string) { + for _, adminId := range adminIds { + t.SendMsgToTgbot(adminId, msg) + } } func (t *Tgbot) UserLoginNotify(username string, ip string, time string, status LoginStatus) { @@ -168,7 +187,7 @@ func (t *Tgbot) UserLoginNotify(username string, ip string, time string, status msg += fmt.Sprintf("Time:%s\r\n", time) msg += fmt.Sprintf("Username:%s\r\n", username) msg += fmt.Sprintf("IP:%s\r\n", ip) - t.SendMsgToTgbot(msg) + t.SendMsgToTgbotAdmins(msg) } func (t *Tgbot) getClientUsage(id string) string { diff --git a/web/translation/translate.en_US.toml b/web/translation/translate.en_US.toml index 7529a16b..f019e180 100644 --- a/web/translation/translate.en_US.toml +++ b/web/translation/translate.en_US.toml @@ -198,8 +198,8 @@ "telegramBotEnableDesc" = "Restart the panel to take effect" "telegramToken" = "Telegram Token" "telegramTokenDesc" = "Restart the panel to take effect" -"telegramChatId" = "Telegram ChatId" -"telegramChatIdDesc" = "Restart the panel to take effect" +"telegramChatId" = "Telegram Admin ChatIds" +"telegramChatIdDesc" = "Multi chatIDs separated by comma. Restart the panel to take effect" "telegramNotifyTime" = "Telegram bot notification time" "telegramNotifyTimeDesc" = "Using Crontab timing format, restart the panel to take effect" "timeZonee" = "Time Zone" diff --git a/web/translation/translate.fa_IR.toml b/web/translation/translate.fa_IR.toml index 48b2f16e..bdfb27be 100644 --- a/web/translation/translate.fa_IR.toml +++ b/web/translation/translate.fa_IR.toml @@ -198,8 +198,8 @@ "telegramBotEnableDesc" = "پنل را مجدداً راه اندازی کنید تا اعمال شود" "telegramToken" = "توکن تلگرام" "telegramTokenDesc" = "پنل را مجدداً راه اندازی کنید تا اعمال شود" -"telegramChatId" = "آی دی تلگرام مدیریت . از ربات @getidsbot آی دی خود را دریافت کنید" -"telegramChatIdDesc" = "پنل را مجدداً راه اندازی کنید تا اعمال شود" +"telegramChatId" = "آی دی تلگرام مدیریت" +"telegramChatIdDesc" = "با استفاده از کاما میتونید چند آی دی را از هم جدا کنید. پنل را مجدداً راه اندازی کنید تا اعمال شود" "telegramNotifyTime" = "مدت زمان نوتیفیکیشن ربات تلگرام" "telegramNotifyTimeDesc" = "از فرمت زمان بندی Crontab استفاده کنید . پنل را مجدداً راه اندازی کنید تا اعمال شود" "timeZonee" = "منظقه زمانی" diff --git a/web/translation/translate.zh_Hans.toml b/web/translation/translate.zh_Hans.toml index 5fb63076..d877a56c 100644 --- a/web/translation/translate.zh_Hans.toml +++ b/web/translation/translate.zh_Hans.toml @@ -198,7 +198,7 @@ "telegramBotEnableDesc" = "重启面板生效" "telegramToken" = "电报机器人TOKEN" "telegramTokenDesc" = "重启面板生效" -"telegramChatId" = "电报机器人ChatId" +"telegramChatId" = "以逗号分隔的多个 chatID 重启面板生效" "telegramChatIdDesc" = "重启面板生效" "telegramNotifyTime" = "电报机器人通知时间" "telegramNotifyTimeDesc" = "采用Crontab定时格式,重启面板生效"