精简: 去掉 Telegram 机器人+通知: tgbot 包/stats-notify 与 hash 清理 job/登录通知/backuptotgbot/testTgBot/全部 tg* 设置/locale Bot 本地化/SecretClears 机制; 连带清理 Swagger/外部流量/邮件/2FA 的残留测试
This commit is contained in:
+8
-135
@@ -31,7 +31,6 @@ import (
|
||||
"github.com/mhsanaei/3x-ui/v3/internal/web/runtime"
|
||||
"github.com/mhsanaei/3x-ui/v3/internal/web/service"
|
||||
"github.com/mhsanaei/3x-ui/v3/internal/web/service/panel"
|
||||
"github.com/mhsanaei/3x-ui/v3/internal/web/service/tgbot"
|
||||
"github.com/mhsanaei/3x-ui/v3/internal/web/websocket"
|
||||
"github.com/mhsanaei/3x-ui/v3/internal/xray"
|
||||
|
||||
@@ -119,7 +118,6 @@ type Server struct {
|
||||
|
||||
xrayService service.XrayService
|
||||
settingService service.SettingService
|
||||
tgbotService tgbot.Tgbot
|
||||
|
||||
wsHub *websocket.Hub
|
||||
|
||||
@@ -220,7 +218,7 @@ func (s *Server) initRouter() (*gin.Engine, error) {
|
||||
|
||||
// init i18n — still used by backend strings (errors, log messages,
|
||||
// SubPage menu entries) even though the Go template engine is gone.
|
||||
err = locale.InitLocalizer(i18nFS, &s.settingService)
|
||||
err = locale.InitLocalizer(i18nFS)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -371,36 +369,6 @@ func (s *Server) startTask(restartXray bool, loc *time.Location) {
|
||||
// Check monthly reset days at midnight
|
||||
_, _ = s.cron.AddJob("@daily", job.NewPeriodicTrafficResetJob("monthly", loc))
|
||||
|
||||
// Telegram-bot–dependent jobs: periodic stats report + callback-hash cleanup.
|
||||
isTgbotenabled, err := s.settingService.GetTgbotEnabled()
|
||||
if (err == nil) && isTgbotenabled {
|
||||
runtime, err := s.settingService.GetTgbotRuntime()
|
||||
if err != nil {
|
||||
logger.Warningf("Add NewStatsNotifyJob: failed to load runtime: %v; using default @daily", err)
|
||||
runtime = "@daily"
|
||||
} else if strings.TrimSpace(runtime) == "" {
|
||||
logger.Warning("Add NewStatsNotifyJob runtime is empty, using default @daily")
|
||||
runtime = "@daily"
|
||||
}
|
||||
logger.Infof("Tg notify enabled,run at %s", runtime)
|
||||
if _, err = s.cron.AddJob(runtime, job.NewStatsNotifyJob()); err != nil {
|
||||
logger.Warningf("Add NewStatsNotifyJob: failed to schedule runtime %q: %v", runtime, err)
|
||||
}
|
||||
|
||||
// check for Telegram bot callback query hash storage reset
|
||||
_, _ = s.cron.AddJob(cadenceCheckHash, job.NewCheckHashStorageJob())
|
||||
}
|
||||
|
||||
// CPU monitor publishes cpu.high events; register it whenever any notifier
|
||||
// (Telegram or Email) wants them, independent of the Telegram bot being on.
|
||||
if s.cpuAlarmWanted() {
|
||||
_, _ = s.cron.AddJob(cadenceCPUAlarm, job.NewCheckCpuJob())
|
||||
}
|
||||
// Memory monitor publishes memory.high events; register it whenever any notifier wants them.
|
||||
if s.memoryAlarmWanted() {
|
||||
_, _ = s.cron.AddJob(cadenceMemoryAlarm, job.NewCheckMemJob())
|
||||
}
|
||||
|
||||
if mins := sys.MemoryReleaseIntervalMinutes(); mins > 0 {
|
||||
_, _ = s.cron.AddJob(fmt.Sprintf("@every %dm", mins), job.NewMemoryReleaseJob())
|
||||
go func() {
|
||||
@@ -410,63 +378,16 @@ func (s *Server) startTask(restartXray bool, loc *time.Location) {
|
||||
}
|
||||
}
|
||||
|
||||
// cpuAlarmWanted reports whether any notifier is configured to receive cpu.high
|
||||
// alerts, so the minute-long blocking CPU sampler only runs when it's needed.
|
||||
func (s *Server) cpuAlarmWanted() bool {
|
||||
wants := func(events string, threshold int) bool {
|
||||
if threshold <= 0 {
|
||||
return false
|
||||
}
|
||||
for e := range strings.SplitSeq(events, ",") {
|
||||
if strings.TrimSpace(e) == string(eventbus.EventCPUHigh) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
if on, _ := s.settingService.GetTgbotEnabled(); on {
|
||||
events, _ := s.settingService.GetTgEnabledEvents()
|
||||
cpu, _ := s.settingService.GetTgCpu()
|
||||
if wants(events, cpu) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// memoryAlarmWanted reports whether any notifier is configured to receive memory.high alerts.
|
||||
func (s *Server) memoryAlarmWanted() bool {
|
||||
wants := func(events string, threshold int) bool {
|
||||
if threshold <= 0 {
|
||||
return false
|
||||
}
|
||||
for e := range strings.SplitSeq(events, ",") {
|
||||
if strings.TrimSpace(e) == string(eventbus.EventMemoryHigh) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
if on, _ := s.settingService.GetTgbotEnabled(); on {
|
||||
events, _ := s.settingService.GetTgEnabledEvents()
|
||||
mem, _ := s.settingService.GetTgMemory()
|
||||
if wants(events, mem) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Start initializes and starts the web server with configured settings, routes, and background jobs.
|
||||
func (s *Server) Start() (err error) {
|
||||
return s.start(true, true)
|
||||
return s.start(true)
|
||||
}
|
||||
|
||||
func (s *Server) StartPanelOnly() (err error) {
|
||||
return s.start(false, true)
|
||||
return s.start(false)
|
||||
}
|
||||
|
||||
func (s *Server) start(restartXray bool, startTgBot bool) (err error) {
|
||||
func (s *Server) start(restartXray bool) (err error) {
|
||||
// This is an anonymous function, no function name
|
||||
defer func() {
|
||||
if err != nil {
|
||||
@@ -589,7 +510,6 @@ func (s *Server) start(restartXray bool, startTgBot bool) (err error) {
|
||||
s.bus = eventbus.New(eventbus.DefaultBufferSize)
|
||||
service.SetEventBus(s.bus)
|
||||
job.EventBus = s.bus
|
||||
tgbot.EventBus = s.bus
|
||||
|
||||
// Wire xray crash callback BEFORE startTask so it's ready
|
||||
xray.OnCrash = func(err error) {
|
||||
@@ -601,65 +521,21 @@ func (s *Server) start(restartXray bool, startTgBot bool) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Wire Telegram test function to controller
|
||||
controller.SetTestTgFunc(func() error {
|
||||
if !s.tgbotService.IsRunning() {
|
||||
return fmt.Errorf("telegram bot is not running (check token and chat ID)")
|
||||
}
|
||||
if err := s.tgbotService.TestConnection(); err != nil {
|
||||
return fmt.Errorf("telegram API test failed: %w", err)
|
||||
}
|
||||
s.tgbotService.SendMsgToTgbotAdmins("✅ Test message from 3x-ui")
|
||||
return nil
|
||||
})
|
||||
|
||||
controller.SetReloadTgbotFunc(func() {
|
||||
enabled, err := s.settingService.GetTgbotEnabled()
|
||||
if err != nil || !enabled {
|
||||
if s.tgbotService.IsRunning() {
|
||||
s.tgbotService.Stop()
|
||||
}
|
||||
if s.bus != nil {
|
||||
s.bus.Unsubscribe("tg-notifier")
|
||||
}
|
||||
return
|
||||
}
|
||||
// Start() stops any previous receiver first, so it is safe whether or not the bot is already running.
|
||||
tgBot := s.tgbotService.NewTgbot()
|
||||
if startErr := tgBot.Start(i18nFS); startErr != nil {
|
||||
logger.Warning("reload Telegram bot failed:", startErr)
|
||||
return
|
||||
}
|
||||
if s.bus != nil {
|
||||
s.bus.Subscribe("tg-notifier", s.tgbotService.HandleEvent)
|
||||
}
|
||||
})
|
||||
|
||||
s.startTask(restartXray, loc)
|
||||
|
||||
if startTgBot {
|
||||
isTgbotenabled, err := s.settingService.GetTgbotEnabled()
|
||||
if (err == nil) && isTgbotenabled {
|
||||
tgBot := s.tgbotService.NewTgbot()
|
||||
_ = tgBot.Start(i18nFS)
|
||||
// Subscribe Telegram notifications for event bus
|
||||
s.bus.Subscribe("tg-notifier", s.tgbotService.HandleEvent)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop gracefully shuts down the web server, stops Xray, cron jobs, and Telegram bot.
|
||||
// Stop gracefully shuts down the web server, stops Xray, and cron jobs.
|
||||
func (s *Server) Stop() error {
|
||||
return s.stop(true, true)
|
||||
return s.stop(true)
|
||||
}
|
||||
|
||||
func (s *Server) StopPanelOnly() error {
|
||||
return s.stop(false, true)
|
||||
return s.stop(false)
|
||||
}
|
||||
|
||||
func (s *Server) stop(stopXray bool, stopTgBot bool) error {
|
||||
func (s *Server) stop(stopXray bool) error {
|
||||
s.cancel()
|
||||
if stopXray {
|
||||
_ = s.xrayService.StopXray()
|
||||
@@ -678,9 +554,6 @@ func (s *Server) stop(stopXray bool, stopTgBot bool) error {
|
||||
if stopXray {
|
||||
service.StopTrafficWriter()
|
||||
}
|
||||
if stopTgBot && s.tgbotService.IsRunning() {
|
||||
s.tgbotService.Stop()
|
||||
}
|
||||
// Gracefully stop WebSocket hub
|
||||
if s.wsHub != nil {
|
||||
s.wsHub.Stop()
|
||||
|
||||
Reference in New Issue
Block a user