mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-27 16:14:21 +00:00
fix(tgbot): reload bot on settings save so a new token takes effect without a panel restart
The Telegram bot was only started at panel boot, so saving a token or toggling tgBotEnable persisted to the DB but never reached the running bot until a full restart, making it look like the token did not save (issue #5539). The settings/update controller now reconciles the bot the same way panelOutbound reconciles Xray: when tgBotEnable, the token, chat ID, or API server change, it stops/(re)starts the bot and updates the event-bus subscription.
This commit is contained in:
@@ -88,6 +88,10 @@ func (a *SettingController) updateSetting(c *gin.Context) {
|
||||
}
|
||||
oldTwoFactor, twoFactorErr := a.settingService.GetTwoFactorEnable()
|
||||
oldPanelOutbound, _ := a.settingService.GetPanelOutbound()
|
||||
oldTgEnable, _ := a.settingService.GetTgbotEnabled()
|
||||
oldTgToken, _ := a.settingService.GetTgBotToken()
|
||||
oldTgChatId, _ := a.settingService.GetTgBotChatId()
|
||||
oldTgAPIServer, _ := a.settingService.GetTgBotAPIServer()
|
||||
err := a.settingService.UpdateAllSetting(allSetting)
|
||||
if err == nil && twoFactorErr == nil && !oldTwoFactor && allSetting.TwoFactorEnable {
|
||||
if bumpErr := a.userService.BumpLoginEpoch(); bumpErr != nil {
|
||||
@@ -102,6 +106,16 @@ func (a *SettingController) updateSetting(c *gin.Context) {
|
||||
logger.Warning("apply panel outbound change failed:", applyErr)
|
||||
}
|
||||
}
|
||||
// UpdateAllSetting already restored a redacted-blank token, so allSetting.TgBotToken is the effective value to compare.
|
||||
if err == nil && reloadTgbotFunc != nil {
|
||||
tgChanged := oldTgEnable != allSetting.TgBotEnable ||
|
||||
(allSetting.TgBotEnable && (oldTgToken != allSetting.TgBotToken ||
|
||||
oldTgChatId != allSetting.TgBotChatId ||
|
||||
oldTgAPIServer != allSetting.TgBotAPIServer))
|
||||
if tgChanged {
|
||||
reloadTgbotFunc()
|
||||
}
|
||||
}
|
||||
jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifySettings"), err)
|
||||
}
|
||||
|
||||
@@ -252,6 +266,11 @@ var testTgFunc func() error
|
||||
// SetTestTgFunc registers the function used to test Telegram sending.
|
||||
func SetTestTgFunc(fn func() error) { testTgFunc = fn }
|
||||
|
||||
// reloadTgbotFunc is wired from the web layer; importing tgbot here would be a circular dependency.
|
||||
var reloadTgbotFunc func()
|
||||
|
||||
func SetReloadTgbotFunc(fn func()) { reloadTgbotFunc = fn }
|
||||
|
||||
// emailService is set from web layer.
|
||||
var emailService *email.EmailService
|
||||
|
||||
|
||||
@@ -619,6 +619,28 @@ func (s *Server) start(restartXray bool, startTgBot bool) (err error) {
|
||||
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)
|
||||
|
||||
if startTgBot {
|
||||
|
||||
Reference in New Issue
Block a user