From 5edc9dc842bc2ad88e5b1fe3c29818106a3d85ec Mon Sep 17 00:00:00 2001 From: line-6000 <154492442+line-6000@users.noreply.github.com> Date: Wed, 22 Apr 2026 03:04:15 +0800 Subject: [PATCH] feat: sync Telegram notification channels with settings updates --- src/controller/admin/settings_controller.go | 12 +++++-- src/model/dao/mdb_table_init.go | 39 ++++++++++++++++++--- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/controller/admin/settings_controller.go b/src/controller/admin/settings_controller.go index f03b0d1..16bb142 100644 --- a/src/controller/admin/settings_controller.go +++ b/src/controller/admin/settings_controller.go @@ -3,6 +3,7 @@ package admin import ( "strings" + "github.com/assimon/luuu/model/dao" "github.com/assimon/luuu/model/data" "github.com/assimon/luuu/model/mdb" "github.com/assimon/luuu/telegram" @@ -111,14 +112,19 @@ func (c *BaseAdminController) UpsertSettings(ctx echo.Context) error { } // When telegram credentials are updated via settings, reload the - // command bot so operators don't need to restart the process. + // command bot so operators don't need to restart the process, and + // sync the notification_channels row so the notify dispatcher picks + // up the new values immediately. telegramKeys := map[string]bool{ - "system.telegram_bot_token": true, - "system.telegram_chat_id": true, + "system.telegram_bot_token": true, + "system.telegram_chat_id": true, + "system.telegram_payment_notice_enabled": true, + "system.telegram_abnormal_notice_enabled": true, } for _, item := range req.Items { if telegramKeys[strings.TrimSpace(item.Key)] { telegram.ReloadBotAsync("settings upsert") + go dao.SyncTelegramChannelFromSettings() break } } diff --git a/src/model/dao/mdb_table_init.go b/src/model/dao/mdb_table_init.go index 644ebf6..e9e30c7 100644 --- a/src/model/dao/mdb_table_init.go +++ b/src/model/dao/mdb_table_init.go @@ -163,7 +163,17 @@ func seedTelegramChannelFromSettings() { if count > 0 { return } + SyncTelegramChannelFromSettings() +} +// SyncTelegramChannelFromSettings reads the four Telegram keys from the +// settings table and upserts the matching notification_channels row: +// - creates a new row when none exists yet +// - updates config+events on the first existing row when settings change +// +// This is called at startup (via seedTelegramChannelFromSettings) and by +// the settings controller whenever any Telegram key is changed at runtime. +func SyncTelegramChannelFromSettings() { keys := []string{ "system.telegram_bot_token", "system.telegram_chat_id", @@ -172,7 +182,7 @@ func seedTelegramChannelFromSettings() { } var rows []mdb.Setting if err := Mdb.Where("key IN ?", keys).Find(&rows).Error; err != nil { - color.Red.Printf("[store_db] seed telegram channel: read settings err=%s\n", err) + color.Red.Printf("[store_db] sync telegram channel: read settings err=%s\n", err) return } m := make(map[string]string, len(rows)) @@ -183,12 +193,12 @@ func seedTelegramChannelFromSettings() { botToken := strings.TrimSpace(m["system.telegram_bot_token"]) chatIDStr := strings.TrimSpace(m["system.telegram_chat_id"]) if botToken == "" || chatIDStr == "" { - return // No legacy telegram config to migrate. + return // No telegram config to sync. } chatID, err := strconv.ParseInt(chatIDStr, 10, 64) if err != nil { - color.Red.Printf("[store_db] seed telegram channel: invalid chat_id=%q\n", chatIDStr) + color.Red.Printf("[store_db] sync telegram channel: invalid chat_id=%q\n", chatIDStr) return } @@ -206,6 +216,25 @@ func seedTelegramChannelFromSettings() { mdb.NotifyEventDailyReport: false, }) + // Try to update an existing row first. + // Use Find (not First) to avoid GORM printing a spurious + // "record not found" log when the table is empty on first boot. + var existing mdb.NotificationChannel + Mdb.Model(&mdb.NotificationChannel{}). + Where("type = ?", mdb.NotificationTypeTelegram). + Order("id ASC").Limit(1).Find(&existing) + if existing.ID != 0 { + // Row exists — patch config and events. + if err2 := Mdb.Model(&existing).Updates(map[string]interface{}{ + "config": string(configJSON), + "events": string(eventsJSON), + }).Error; err2 != nil { + color.Red.Printf("[store_db] sync telegram channel update err=%s\n", err2) + } + return + } + + // No row yet — create one. ch := mdb.NotificationChannel{ Type: mdb.NotificationTypeTelegram, Name: "Telegram", @@ -214,8 +243,8 @@ func seedTelegramChannelFromSettings() { Enabled: true, } if err := Mdb.Create(&ch).Error; err != nil { - color.Red.Printf("[store_db] seed telegram channel err=%s\n", err) + color.Red.Printf("[store_db] sync telegram channel create err=%s\n", err) } else { - color.Green.Printf("[store_db] migrated legacy telegram settings to notification_channels (id=%d)\n", ch.ID) + color.Green.Printf("[store_db] created telegram notification_channel from settings (id=%d)\n", ch.ID) } }