4dde61e8dbcc8402f4dc245de120f514b1a2dc21
15
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
dc13e69951 |
feat(telegram): full bot enhancement with inline menus, cron reports, events
Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/ Field naming follows existing 3m-ui snake_case convention (not sanaei's tg* prefix) per project maintainer's request. == Data layer == - ProxyUser: add TelegramID (indexed) + TelegramName fields for linking proxy users to their Telegram accounts (self-service queries). - SafeUser + ToSafeUser: expose both new fields. - user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods. - user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram (registered before /:id to avoid path capture). - UpdateInput/CreateInput: accept TelegramID + TelegramName. == Settings expansion (8 new fields, snake_case) == - schedule: cron expr or @daily/@every 6h for periodic reports (default @daily) - attach_backup: include DB backup zip in periodic report - language: bot message language zh/en (default zh) - enabled_events: comma-sep event list (default 'login,cpu,crash') Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic - expiry_warn_days: remind N days before expiry (0=off) - traffic_warn_gb: remind when remaining traffic < N GB (0=off) - proxy_url: socks5:// or http:// proxy for Telegram API - api_server: custom Bot API server (empty=official) - EventEnabled(name) helper for per-event gating. == Client enhancements == - Proxy support: http(s):// via http.Transport.Proxy; socks5:// via golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback. - Custom API server (apiBase() replaces hardcoded URL). - SendDocument: multipart sendDocument for backup file attachment. - GetMe + SetMyCommands: for bot-info + set-my-commands endpoints. - sendWithKeyboard: sendMessage with reply_markup (inline keyboards). - answerCallbackQuery: clear callback loading spinner. == Bot commands + inline menus == - /id: reply with sender's Telegram numeric ID. - /usage: admin → search users; bound user → self-query traffic/expiry/sub URL. - /start + /help: send inline keyboard menu (admin menu for admin chats, user menu for bound users, plain text for unbound). - Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/ backup/restart) in 4 rows. - User menu: my_usage + my_sub buttons. - callback_query handling: answerCallbackQuery + dispatch on callback_data. - Access control: admin chats always pass; non-admin chats pass only when FromID matches a ProxyUser.TelegramID. - Bot struct: added userSvc field for GetByTelegramID lookups. - NewBot signature: NewBot(db, mihomoSvc, userSvc). == Cron scheduler (new telegram/scheduler.go) == - Periodic report goroutine driven by Settings.Schedule. - Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron. - Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted counts. - Optional backup: AttachBackup → system.WriteZip → SendDocument. - Settings reload on every tick (no restart needed for schedule changes). - NotifyEvent(event, details): generic event emitter for one-shot alerts. == Events layer == - login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure). Failure path added to auth/api.go Login handler. Both gated by EventEnabled('login') — admins can mute success spam yet keep failure alerts. - memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as shared 'resource warn %' threshold. 1-hour cooldown dedup. - crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash. Fires on non-zero exit while desired==true (unexpected crash, not admin stop). Wired in app/container.go. - Dual thresholds: expiry (hours + days), traffic (percent + GB) with separate dedup keys so neither suppresses the other. == API endpoints == - POST /telegram/set-my-commands: registers 12-command menu with Telegram. - GET /telegram/bot-info: returns bot username/first_name/id. == Frontend == - telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands + fetchTelegramBotInfo API functions. - Settings.tsx: 8 new form controls (schedule Input, language Select, enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb InputNumber, attach_backup Switch, proxy_url Input, api_server Input). Added 'Set bot commands' button calling setTelegramCommands. - i18n: 11 new keys (zh + en) for the new settings labels. == Verification == - go build ./... : PASS - go vet ./... : PASS - go test ./... : all 15 packages PASS - npm run build (tsc + vite) : PASS, 3241 modules - gofmt : clean feat(telegram): full bot enhancement with inline menus, cron reports, events Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/ Field naming follows existing 3m-ui snake_case convention (not sanaei's tg* prefix) per project maintainer's request. == Data layer == - ProxyUser: add TelegramID (indexed) + TelegramName fields for linking proxy users to their Telegram accounts (self-service queries). - SafeUser + ToSafeUser: expose both new fields. - user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods. - user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram (registered before /:id to avoid path capture). - UpdateInput/CreateInput: accept TelegramID + TelegramName. == Settings expansion (8 new fields, snake_case) == - schedule: cron expr or @daily/@every 6h for periodic reports (default @daily) - attach_backup: include DB backup zip in periodic report - language: bot message language zh/en (default zh) - enabled_events: comma-sep event list (default 'login,cpu,crash') Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic - expiry_warn_days: remind N days before expiry (0=off) - traffic_warn_gb: remind when remaining traffic < N GB (0=off) - proxy_url: socks5:// or http:// proxy for Telegram API - api_server: custom Bot API server (empty=official) - EventEnabled(name) helper for per-event gating. == Client enhancements == - Proxy support: http(s):// via http.Transport.Proxy; socks5:// via golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback. - Custom API server (apiBase() replaces hardcoded URL). - SendDocument: multipart sendDocument for backup file attachment. - GetMe + SetMyCommands: for bot-info + set-my-commands endpoints. - sendWithKeyboard: sendMessage with reply_markup (inline keyboards). - answerCallbackQuery: clear callback loading spinner. == Bot commands + inline menus == - /id: reply with sender's Telegram numeric ID. - /usage: admin → search users; bound user → self-query traffic/expiry/sub URL. - /start + /help: send inline keyboard menu (admin menu for admin chats, user menu for bound users, plain text for unbound). - Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/ backup/restart) in 4 rows. - User menu: my_usage + my_sub buttons. - callback_query handling: answerCallbackQuery + dispatch on callback_data. - Access control: admin chats always pass; non-admin chats pass only when FromID matches a ProxyUser.TelegramID. - Bot struct: added userSvc field for GetByTelegramID lookups. - NewBot signature: NewBot(db, mihomoSvc, userSvc). == Cron scheduler (new telegram/scheduler.go) == - Periodic report goroutine driven by Settings.Schedule. - Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron. - Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted counts. - Optional backup: AttachBackup → system.WriteZip → SendDocument. - Settings reload on every tick (no restart needed for schedule changes). - NotifyEvent(event, details): generic event emitter for one-shot alerts. == Events layer == - login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure). Failure path added to auth/api.go Login handler. Both gated by EventEnabled('login') — admins can mute success spam yet keep failure alerts. - memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as shared 'resource warn %' threshold. 1-hour cooldown dedup. - crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash. Fires on non-zero exit while desired==true (unexpected crash, not admin stop). Wired in app/container.go. - Dual thresholds: expiry (hours + days), traffic (percent + GB) with separate dedup keys so neither suppresses the other. == API endpoints == - POST /telegram/set-my-commands: registers 12-command menu with Telegram. - GET /telegram/bot-info: returns bot username/first_name/id. == Frontend == - telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands + fetchTelegramBotInfo API functions. - Settings.tsx: 8 new form controls (schedule Input, language Select, enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb InputNumber, attach_backup Switch, proxy_url Input, api_server Input). Added 'Set bot commands' button calling setTelegramCommands. - i18n: 11 new keys (zh + en) for the new settings labels. == Verification == - go build ./... : PASS - go vet ./... : PASS - go test ./... : all 15 packages PASS - npm run build (tsc + vite) : PASS, 3241 modules - gofmt : clean feat(telegram): full bot enhancement with inline menus, cron reports, events Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/ Field naming follows existing 3m-ui snake_case convention (not sanaei's tg* prefix) per project maintainer's request. == Data layer == - ProxyUser: add TelegramID (indexed) + TelegramName fields for linking proxy users to their Telegram accounts (self-service queries). - SafeUser + ToSafeUser: expose both new fields. - user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods. - user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram (registered before /:id to avoid path capture). - UpdateInput/CreateInput: accept TelegramID + TelegramName. == Settings expansion (8 new fields, snake_case) == - schedule: cron expr or @daily/@every 6h for periodic reports (default @daily) - attach_backup: include DB backup zip in periodic report - language: bot message language zh/en (default zh) - enabled_events: comma-sep event list (default 'login,cpu,crash') Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic - expiry_warn_days: remind N days before expiry (0=off) - traffic_warn_gb: remind when remaining traffic < N GB (0=off) - proxy_url: socks5:// or http:// proxy for Telegram API - api_server: custom Bot API server (empty=official) - EventEnabled(name) helper for per-event gating. == Client enhancements == - Proxy support: http(s):// via http.Transport.Proxy; socks5:// via golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback. - Custom API server (apiBase() replaces hardcoded URL). - SendDocument: multipart sendDocument for backup file attachment. - GetMe + SetMyCommands: for bot-info + set-my-commands endpoints. - sendWithKeyboard: sendMessage with reply_markup (inline keyboards). - answerCallbackQuery: clear callback loading spinner. == Bot commands + inline menus == - /id: reply with sender's Telegram numeric ID. - /usage: admin → search users; bound user → self-query traffic/expiry/sub URL. - /start + /help: send inline keyboard menu (admin menu for admin chats, user menu for bound users, plain text for unbound). - Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/ backup/restart) in 4 rows. - User menu: my_usage + my_sub buttons. - callback_query handling: answerCallbackQuery + dispatch on callback_data. - Access control: admin chats always pass; non-admin chats pass only when FromID matches a ProxyUser.TelegramID. - Bot struct: added userSvc field for GetByTelegramID lookups. - NewBot signature: NewBot(db, mihomoSvc, userSvc). == Cron scheduler (new telegram/scheduler.go) == - Periodic report goroutine driven by Settings.Schedule. - Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron. - Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted counts. - Optional backup: AttachBackup → system.WriteZip → SendDocument. - Settings reload on every tick (no restart needed for schedule changes). - NotifyEvent(event, details): generic event emitter for one-shot alerts. == Events layer == - login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure). Failure path added to auth/api.go Login handler. Both gated by EventEnabled('login') — admins can mute success spam yet keep failure alerts. - memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as shared 'resource warn %' threshold. 1-hour cooldown dedup. - crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash. Fires on non-zero exit while desired==true (unexpected crash, not admin stop). Wired in app/container.go. - Dual thresholds: expiry (hours + days), traffic (percent + GB) with separate dedup keys so neither suppresses the other. == API endpoints == - POST /telegram/set-my-commands: registers 12-command menu with Telegram. - GET /telegram/bot-info: returns bot username/first_name/id. == Frontend == - telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands + fetchTelegramBotInfo API functions. - Settings.tsx: 8 new form controls (schedule Input, language Select, enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb InputNumber, attach_backup Switch, proxy_url Input, api_server Input). Added 'Set bot commands' button calling setTelegramCommands. - i18n: 11 new keys (zh + en) for the new settings labels. == Verification == - go build ./... : PASS - go vet ./... : PASS - go test ./... : all 15 packages PASS - npm run build (tsc + vite) : PASS, 3241 modules - gofmt : clean feat(telegram): full bot enhancement with inline menus, cron reports, events Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/ Field naming follows existing 3m-ui snake_case convention (not sanaei's tg* prefix) per project maintainer's request. == Data layer == - ProxyUser: add TelegramID (indexed) + TelegramName fields for linking proxy users to their Telegram accounts (self-service queries). - SafeUser + ToSafeUser: expose both new fields. - user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods. - user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram (registered before /:id to avoid path capture). - UpdateInput/CreateInput: accept TelegramID + TelegramName. == Settings expansion (8 new fields, snake_case) == - schedule: cron expr or @daily/@every 6h for periodic reports (default @daily) - attach_backup: include DB backup zip in periodic report - language: bot message language zh/en (default zh) - enabled_events: comma-sep event list (default 'login,cpu,crash') Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic - expiry_warn_days: remind N days before expiry (0=off) - traffic_warn_gb: remind when remaining traffic < N GB (0=off) - proxy_url: socks5:// or http:// proxy for Telegram API - api_server: custom Bot API server (empty=official) - EventEnabled(name) helper for per-event gating. == Client enhancements == - Proxy support: http(s):// via http.Transport.Proxy; socks5:// via golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback. - Custom API server (apiBase() replaces hardcoded URL). - SendDocument: multipart sendDocument for backup file attachment. - GetMe + SetMyCommands: for bot-info + set-my-commands endpoints. - sendWithKeyboard: sendMessage with reply_markup (inline keyboards). - answerCallbackQuery: clear callback loading spinner. == Bot commands + inline menus == - /id: reply with sender's Telegram numeric ID. - /usage: admin → search users; bound user → self-query traffic/expiry/sub URL. - /start + /help: send inline keyboard menu (admin menu for admin chats, user menu for bound users, plain text for unbound). - Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/ backup/restart) in 4 rows. - User menu: my_usage + my_sub buttons. - callback_query handling: answerCallbackQuery + dispatch on callback_data. - Access control: admin chats always pass; non-admin chats pass only when FromID matches a ProxyUser.TelegramID. - Bot struct: added userSvc field for GetByTelegramID lookups. - NewBot signature: NewBot(db, mihomoSvc, userSvc). == Cron scheduler (new telegram/scheduler.go) == - Periodic report goroutine driven by Settings.Schedule. - Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron. - Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted counts. - Optional backup: AttachBackup → system.WriteZip → SendDocument. - Settings reload on every tick (no restart needed for schedule changes). - NotifyEvent(event, details): generic event emitter for one-shot alerts. == Events layer == - login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure). Failure path added to auth/api.go Login handler. Both gated by EventEnabled('login') — admins can mute success spam yet keep failure alerts. - memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as shared 'resource warn %' threshold. 1-hour cooldown dedup. - crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash. Fires on non-zero exit while desired==true (unexpected crash, not admin stop). Wired in app/container.go. - Dual thresholds: expiry (hours + days), traffic (percent + GB) with separate dedup keys so neither suppresses the other. == API endpoints == - POST /telegram/set-my-commands: registers 12-command menu with Telegram. - GET /telegram/bot-info: returns bot username/first_name/id. == Frontend == - telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands + fetchTelegramBotInfo API functions. - Settings.tsx: 8 new form controls (schedule Input, language Select, enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb InputNumber, attach_backup Switch, proxy_url Input, api_server Input). Added 'Set bot commands' button calling setTelegramCommands. - i18n: 11 new keys (zh + en) for the new settings labels. == Verification == - go build ./... : PASS - go vet ./... : PASS - go test ./... : all 15 packages PASS - npm run build (tsc + vite) : PASS, 3241 modules - gofmt : clean feat(telegram): full bot enhancement with inline menus, cron reports, events Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/ Field naming follows existing 3m-ui snake_case convention (not sanaei's tg* prefix) per project maintainer's request. == Data layer == - ProxyUser: add TelegramID (indexed) + TelegramName fields for linking proxy users to their Telegram accounts (self-service queries). - SafeUser + ToSafeUser: expose both new fields. - user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods. - user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram (registered before /:id to avoid path capture). - UpdateInput/CreateInput: accept TelegramID + TelegramName. == Settings expansion (8 new fields, snake_case) == - schedule: cron expr or @daily/@every 6h for periodic reports (default @daily) - attach_backup: include DB backup zip in periodic report - language: bot message language zh/en (default zh) - enabled_events: comma-sep event list (default 'login,cpu,crash') Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic - expiry_warn_days: remind N days before expiry (0=off) - traffic_warn_gb: remind when remaining traffic < N GB (0=off) - proxy_url: socks5:// or http:// proxy for Telegram API - api_server: custom Bot API server (empty=official) - EventEnabled(name) helper for per-event gating. == Client enhancements == - Proxy support: http(s):// via http.Transport.Proxy; socks5:// via golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback. - Custom API server (apiBase() replaces hardcoded URL). - SendDocument: multipart sendDocument for backup file attachment. - GetMe + SetMyCommands: for bot-info + set-my-commands endpoints. - sendWithKeyboard: sendMessage with reply_markup (inline keyboards). - answerCallbackQuery: clear callback loading spinner. == Bot commands + inline menus == - /id: reply with sender's Telegram numeric ID. - /usage: admin → search users; bound user → self-query traffic/expiry/sub URL. - /start + /help: send inline keyboard menu (admin menu for admin chats, user menu for bound users, plain text for unbound). - Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/ backup/restart) in 4 rows. - User menu: my_usage + my_sub buttons. - callback_query handling: answerCallbackQuery + dispatch on callback_data. - Access control: admin chats always pass; non-admin chats pass only when FromID matches a ProxyUser.TelegramID. - Bot struct: added userSvc field for GetByTelegramID lookups. - NewBot signature: NewBot(db, mihomoSvc, userSvc). == Cron scheduler (new telegram/scheduler.go) == - Periodic report goroutine driven by Settings.Schedule. - Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron. - Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted counts. - Optional backup: AttachBackup → system.WriteZip → SendDocument. - Settings reload on every tick (no restart needed for schedule changes). - NotifyEvent(event, details): generic event emitter for one-shot alerts. == Events layer == - login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure). Failure path added to auth/api.go Login handler. Both gated by EventEnabled('login') — admins can mute success spam yet keep failure alerts. - memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as shared 'resource warn %' threshold. 1-hour cooldown dedup. - crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash. Fires on non-zero exit while desired==true (unexpected crash, not admin stop). Wired in app/container.go. - Dual thresholds: expiry (hours + days), traffic (percent + GB) with separate dedup keys so neither suppresses the other. == API endpoints == - POST /telegram/set-my-commands: registers 12-command menu with Telegram. - GET /telegram/bot-info: returns bot username/first_name/id. == Frontend == - telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands + fetchTelegramBotInfo API functions. - Settings.tsx: 8 new form controls (schedule Input, language Select, enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb InputNumber, attach_backup Switch, proxy_url Input, api_server Input). Added 'Set bot commands' button calling setTelegramCommands. - i18n: 11 new keys (zh + en) for the new settings labels. == Verification == - go build ./... : PASS - go vet ./... : PASS - go test ./... : all 15 packages PASS - npm run build (tsc + vite) : PASS, 3241 modules - gofmt : clean feat(telegram): full bot enhancement with inline menus, cron reports, events Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/ Field naming follows existing 3m-ui snake_case convention (not sanaei's tg* prefix) per project maintainer's request. == Data layer == - ProxyUser: add TelegramID (indexed) + TelegramName fields for linking proxy users to their Telegram accounts (self-service queries). - SafeUser + ToSafeUser: expose both new fields. - user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods. - user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram (registered before /:id to avoid path capture). - UpdateInput/CreateInput: accept TelegramID + TelegramName. == Settings expansion (8 new fields, snake_case) == - schedule: cron expr or @daily/@every 6h for periodic reports (default @daily) - attach_backup: include DB backup zip in periodic report - language: bot message language zh/en (default zh) - enabled_events: comma-sep event list (default 'login,cpu,crash') Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic - expiry_warn_days: remind N days before expiry (0=off) - traffic_warn_gb: remind when remaining traffic < N GB (0=off) - proxy_url: socks5:// or http:// proxy for Telegram API - api_server: custom Bot API server (empty=official) - EventEnabled(name) helper for per-event gating. == Client enhancements == - Proxy support: http(s):// via http.Transport.Proxy; socks5:// via golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback. - Custom API server (apiBase() replaces hardcoded URL). - SendDocument: multipart sendDocument for backup file attachment. - GetMe + SetMyCommands: for bot-info + set-my-commands endpoints. - sendWithKeyboard: sendMessage with reply_markup (inline keyboards). - answerCallbackQuery: clear callback loading spinner. == Bot commands + inline menus == - /id: reply with sender's Telegram numeric ID. - /usage: admin → search users; bound user → self-query traffic/expiry/sub URL. - /start + /help: send inline keyboard menu (admin menu for admin chats, user menu for bound users, plain text for unbound). - Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/ backup/restart) in 4 rows. - User menu: my_usage + my_sub buttons. - callback_query handling: answerCallbackQuery + dispatch on callback_data. - Access control: admin chats always pass; non-admin chats pass only when FromID matches a ProxyUser.TelegramID. - Bot struct: added userSvc field for GetByTelegramID lookups. - NewBot signature: NewBot(db, mihomoSvc, userSvc). == Cron scheduler (new telegram/scheduler.go) == - Periodic report goroutine driven by Settings.Schedule. - Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron. - Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted counts. - Optional backup: AttachBackup → system.WriteZip → SendDocument. - Settings reload on every tick (no restart needed for schedule changes). - NotifyEvent(event, details): generic event emitter for one-shot alerts. == Events layer == - login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure). Failure path added to auth/api.go Login handler. Both gated by EventEnabled('login') — admins can mute success spam yet keep failure alerts. - memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as shared 'resource warn %' threshold. 1-hour cooldown dedup. - crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash. Fires on non-zero exit while desired==true (unexpected crash, not admin stop). Wired in app/container.go. - Dual thresholds: expiry (hours + days), traffic (percent + GB) with separate dedup keys so neither suppresses the other. == API endpoints == - POST /telegram/set-my-commands: registers 12-command menu with Telegram. - GET /telegram/bot-info: returns bot username/first_name/id. == Frontend == - telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands + fetchTelegramBotInfo API functions. - Settings.tsx: 8 new form controls (schedule Input, language Select, enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb InputNumber, attach_backup Switch, proxy_url Input, api_server Input). Added 'Set bot commands' button calling setTelegramCommands. - i18n: 11 new keys (zh + en) for the new settings labels. == Verification == - go build ./... : PASS - go vet ./... : PASS - go test ./... : all 15 packages PASS - npm run build (tsc + vite) : PASS, 3241 modules - gofmt : clean feat(telegram): full bot enhancement with inline menus, cron reports, events Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/ Field naming follows existing 3m-ui snake_case convention (not sanaei's tg* prefix) per project maintainer's request. == Data layer == - ProxyUser: add TelegramID (indexed) + TelegramName fields for linking proxy users to their Telegram accounts (self-service queries). - SafeUser + ToSafeUser: expose both new fields. - user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods. - user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram (registered before /:id to avoid path capture). - UpdateInput/CreateInput: accept TelegramID + TelegramName. == Settings expansion (8 new fields, snake_case) == - schedule: cron expr or @daily/@every 6h for periodic reports (default @daily) - attach_backup: include DB backup zip in periodic report - language: bot message language zh/en (default zh) - enabled_events: comma-sep event list (default 'login,cpu,crash') Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic - expiry_warn_days: remind N days before expiry (0=off) - traffic_warn_gb: remind when remaining traffic < N GB (0=off) - proxy_url: socks5:// or http:// proxy for Telegram API - api_server: custom Bot API server (empty=official) - EventEnabled(name) helper for per-event gating. == Client enhancements == - Proxy support: http(s):// via http.Transport.Proxy; socks5:// via golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback. - Custom API server (apiBase() replaces hardcoded URL). - SendDocument: multipart sendDocument for backup file attachment. - GetMe + SetMyCommands: for bot-info + set-my-commands endpoints. - sendWithKeyboard: sendMessage with reply_markup (inline keyboards). - answerCallbackQuery: clear callback loading spinner. == Bot commands + inline menus == - /id: reply with sender's Telegram numeric ID. - /usage: admin → search users; bound user → self-query traffic/expiry/sub URL. - /start + /help: send inline keyboard menu (admin menu for admin chats, user menu for bound users, plain text for unbound). - Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/ backup/restart) in 4 rows. - User menu: my_usage + my_sub buttons. - callback_query handling: answerCallbackQuery + dispatch on callback_data. - Access control: admin chats always pass; non-admin chats pass only when FromID matches a ProxyUser.TelegramID. - Bot struct: added userSvc field for GetByTelegramID lookups. - NewBot signature: NewBot(db, mihomoSvc, userSvc). == Cron scheduler (new telegram/scheduler.go) == - Periodic report goroutine driven by Settings.Schedule. - Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron. - Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted counts. - Optional backup: AttachBackup → system.WriteZip → SendDocument. - Settings reload on every tick (no restart needed for schedule changes). - NotifyEvent(event, details): generic event emitter for one-shot alerts. == Events layer == - login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure). Failure path added to auth/api.go Login handler. Both gated by EventEnabled('login') — admins can mute success spam yet keep failure alerts. - memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as shared 'resource warn %' threshold. 1-hour cooldown dedup. - crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash. Fires on non-zero exit while desired==true (unexpected crash, not admin stop). Wired in app/container.go. - Dual thresholds: expiry (hours + days), traffic (percent + GB) with separate dedup keys so neither suppresses the other. == API endpoints == - POST /telegram/set-my-commands: registers 12-command menu with Telegram. - GET /telegram/bot-info: returns bot username/first_name/id. == Frontend == - telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands + fetchTelegramBotInfo API functions. - Settings.tsx: 8 new form controls (schedule Input, language Select, enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb InputNumber, attach_backup Switch, proxy_url Input, api_server Input). Added 'Set bot commands' button calling setTelegramCommands. - i18n: 11 new keys (zh + en) for the new settings labels. == Verification == - go build ./... : PASS - go vet ./... : PASS - go test ./... : all 15 packages PASS - npm run build (tsc + vite) : PASS, 3241 modules - gofmt : clean feat(telegram): full bot enhancement with inline menus, cron reports, events Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/ Field naming follows existing 3m-ui snake_case convention (not sanaei's tg* prefix) per project maintainer's request. == Data layer == - ProxyUser: add TelegramID (indexed) + TelegramName fields for linking proxy users to their Telegram accounts (self-service queries). - SafeUser + ToSafeUser: expose both new fields. - user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods. - user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram (registered before /:id to avoid path capture). - UpdateInput/CreateInput: accept TelegramID + TelegramName. == Settings expansion (8 new fields, snake_case) == - schedule: cron expr or @daily/@every 6h for periodic reports (default @daily) - attach_backup: include DB backup zip in periodic report - language: bot message language zh/en (default zh) - enabled_events: comma-sep event list (default 'login,cpu,crash') Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic - expiry_warn_days: remind N days before expiry (0=off) - traffic_warn_gb: remind when remaining traffic < N GB (0=off) - proxy_url: socks5:// or http:// proxy for Telegram API - api_server: custom Bot API server (empty=official) - EventEnabled(name) helper for per-event gating. == Client enhancements == - Proxy support: http(s):// via http.Transport.Proxy; socks5:// via golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback. - Custom API server (apiBase() replaces hardcoded URL). - SendDocument: multipart sendDocument for backup file attachment. - GetMe + SetMyCommands: for bot-info + set-my-commands endpoints. - sendWithKeyboard: sendMessage with reply_markup (inline keyboards). - answerCallbackQuery: clear callback loading spinner. == Bot commands + inline menus == - /id: reply with sender's Telegram numeric ID. - /usage: admin → search users; bound user → self-query traffic/expiry/sub URL. - /start + /help: send inline keyboard menu (admin menu for admin chats, user menu for bound users, plain text for unbound). - Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/ backup/restart) in 4 rows. - User menu: my_usage + my_sub buttons. - callback_query handling: answerCallbackQuery + dispatch on callback_data. - Access control: admin chats always pass; non-admin chats pass only when FromID matches a ProxyUser.TelegramID. - Bot struct: added userSvc field for GetByTelegramID lookups. - NewBot signature: NewBot(db, mihomoSvc, userSvc). == Cron scheduler (new telegram/scheduler.go) == - Periodic report goroutine driven by Settings.Schedule. - Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron. - Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted counts. - Optional backup: AttachBackup → system.WriteZip → SendDocument. - Settings reload on every tick (no restart needed for schedule changes). - NotifyEvent(event, details): generic event emitter for one-shot alerts. == Events layer == - login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure). Failure path added to auth/api.go Login handler. Both gated by EventEnabled('login') — admins can mute success spam yet keep failure alerts. - memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as shared 'resource warn %' threshold. 1-hour cooldown dedup. - crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash. Fires on non-zero exit while desired==true (unexpected crash, not admin stop). Wired in app/container.go. - Dual thresholds: expiry (hours + days), traffic (percent + GB) with separate dedup keys so neither suppresses the other. == API endpoints == - POST /telegram/set-my-commands: registers 12-command menu with Telegram. - GET /telegram/bot-info: returns bot username/first_name/id. == Frontend == - telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands + fetchTelegramBotInfo API functions. - Settings.tsx: 8 new form controls (schedule Input, language Select, enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb InputNumber, attach_backup Switch, proxy_url Input, api_server Input). Added 'Set bot commands' button calling setTelegramCommands. - i18n: 11 new keys (zh + en) for the new settings labels. == Verification == - go build ./... : PASS - go vet ./... : PASS - go test ./... : all 15 packages PASS - npm run build (tsc + vite) : PASS, 3241 modules - gofmt : clean feat(telegram): full bot enhancement with inline menus, cron reports, events Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/ Field naming follows existing 3m-ui snake_case convention (not sanaei's tg* prefix) per project maintainer's request. == Data layer == - ProxyUser: add TelegramID (indexed) + TelegramName fields for linking proxy users to their Telegram accounts (self-service queries). - SafeUser + ToSafeUser: expose both new fields. - user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods. - user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram (registered before /:id to avoid path capture). - UpdateInput/CreateInput: accept TelegramID + TelegramName. == Settings expansion (8 new fields, snake_case) == - schedule: cron expr or @daily/@every 6h for periodic reports (default @daily) - attach_backup: include DB backup zip in periodic report - language: bot message language zh/en (default zh) - enabled_events: comma-sep event list (default 'login,cpu,crash') Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic - expiry_warn_days: remind N days before expiry (0=off) - traffic_warn_gb: remind when remaining traffic < N GB (0=off) - proxy_url: socks5:// or http:// proxy for Telegram API - api_server: custom Bot API server (empty=official) - EventEnabled(name) helper for per-event gating. == Client enhancements == - Proxy support: http(s):// via http.Transport.Proxy; socks5:// via golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback. - Custom API server (apiBase() replaces hardcoded URL). - SendDocument: multipart sendDocument for backup file attachment. - GetMe + SetMyCommands: for bot-info + set-my-commands endpoints. - sendWithKeyboard: sendMessage with reply_markup (inline keyboards). - answerCallbackQuery: clear callback loading spinner. == Bot commands + inline menus == - /id: reply with sender's Telegram numeric ID. - /usage: admin → search users; bound user → self-query traffic/expiry/sub URL. - /start + /help: send inline keyboard menu (admin menu for admin chats, user menu for bound users, plain text for unbound). - Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/ backup/restart) in 4 rows. - User menu: my_usage + my_sub buttons. - callback_query handling: answerCallbackQuery + dispatch on callback_data. - Access control: admin chats always pass; non-admin chats pass only when FromID matches a ProxyUser.TelegramID. - Bot struct: added userSvc field for GetByTelegramID lookups. - NewBot signature: NewBot(db, mihomoSvc, userSvc). == Cron scheduler (new telegram/scheduler.go) == - Periodic report goroutine driven by Settings.Schedule. - Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron. - Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted counts. - Optional backup: AttachBackup → system.WriteZip → SendDocument. - Settings reload on every tick (no restart needed for schedule changes). - NotifyEvent(event, details): generic event emitter for one-shot alerts. == Events layer == - login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure). Failure path added to auth/api.go Login handler. Both gated by EventEnabled('login') — admins can mute success spam yet keep failure alerts. - memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as shared 'resource warn %' threshold. 1-hour cooldown dedup. - crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash. Fires on non-zero exit while desired==true (unexpected crash, not admin stop). Wired in app/container.go. - Dual thresholds: expiry (hours + days), traffic (percent + GB) with separate dedup keys so neither suppresses the other. == API endpoints == - POST /telegram/set-my-commands: registers 12-command menu with Telegram. - GET /telegram/bot-info: returns bot username/first_name/id. == Frontend == - telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands + fetchTelegramBotInfo API functions. - Settings.tsx: 8 new form controls (schedule Input, language Select, enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb InputNumber, attach_backup Switch, proxy_url Input, api_server Input). Added 'Set bot commands' button calling setTelegramCommands. - i18n: 11 new keys (zh + en) for the new settings labels. == Verification == - go build ./... : PASS - go vet ./... : PASS - go test ./... : all 15 packages PASS - npm run build (tsc + vite) : PASS, 3241 modules - gofmt : clean feat(telegram): full bot enhancement with inline menus, cron reports, events Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/ Field naming follows existing 3m-ui snake_case convention (not sanaei's tg* prefix) per project maintainer's request. == Data layer == - ProxyUser: add TelegramID (indexed) + TelegramName fields for linking proxy users to their Telegram accounts (self-service queries). - SafeUser + ToSafeUser: expose both new fields. - user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods. - user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram (registered before /:id to avoid path capture). - UpdateInput/CreateInput: accept TelegramID + TelegramName. == Settings expansion (8 new fields, snake_case) == - schedule: cron expr or @daily/@every 6h for periodic reports (default @daily) - attach_backup: include DB backup zip in periodic report - language: bot message language zh/en (default zh) - enabled_events: comma-sep event list (default 'login,cpu,crash') Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic - expiry_warn_days: remind N days before expiry (0=off) - traffic_warn_gb: remind when remaining traffic < N GB (0=off) - proxy_url: socks5:// or http:// proxy for Telegram API - api_server: custom Bot API server (empty=official) - EventEnabled(name) helper for per-event gating. == Client enhancements == - Proxy support: http(s):// via http.Transport.Proxy; socks5:// via golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback. - Custom API server (apiBase() replaces hardcoded URL). - SendDocument: multipart sendDocument for backup file attachment. - GetMe + SetMyCommands: for bot-info + set-my-commands endpoints. - sendWithKeyboard: sendMessage with reply_markup (inline keyboards). - answerCallbackQuery: clear callback loading spinner. == Bot commands + inline menus == - /id: reply with sender's Telegram numeric ID. - /usage: admin → search users; bound user → self-query traffic/expiry/sub URL. - /start + /help: send inline keyboard menu (admin menu for admin chats, user menu for bound users, plain text for unbound). - Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/ backup/restart) in 4 rows. - User menu: my_usage + my_sub buttons. - callback_query handling: answerCallbackQuery + dispatch on callback_data. - Access control: admin chats always pass; non-admin chats pass only when FromID matches a ProxyUser.TelegramID. - Bot struct: added userSvc field for GetByTelegramID lookups. - NewBot signature: NewBot(db, mihomoSvc, userSvc). == Cron scheduler (new telegram/scheduler.go) == - Periodic report goroutine driven by Settings.Schedule. - Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron. - Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted counts. - Optional backup: AttachBackup → system.WriteZip → SendDocument. - Settings reload on every tick (no restart needed for schedule changes). - NotifyEvent(event, details): generic event emitter for one-shot alerts. == Events layer == - login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure). Failure path added to auth/api.go Login handler. Both gated by EventEnabled('login') — admins can mute success spam yet keep failure alerts. - memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as shared 'resource warn %' threshold. 1-hour cooldown dedup. - crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash. Fires on non-zero exit while desired==true (unexpected crash, not admin stop). Wired in app/container.go. - Dual thresholds: expiry (hours + days), traffic (percent + GB) with separate dedup keys so neither suppresses the other. == API endpoints == - POST /telegram/set-my-commands: registers 12-command menu with Telegram. - GET /telegram/bot-info: returns bot username/first_name/id. == Frontend == - telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands + fetchTelegramBotInfo API functions. - Settings.tsx: 8 new form controls (schedule Input, language Select, enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb InputNumber, attach_backup Switch, proxy_url Input, api_server Input). Added 'Set bot commands' button calling setTelegramCommands. - i18n: 11 new keys (zh + en) for the new settings labels. == Verification == - go build ./... : PASS - go vet ./... : PASS - go test ./... : all 15 packages PASS - npm run build (tsc + vite) : PASS, 3241 modules - gofmt : clean feat(telegram): full bot enhancement with inline menus, cron reports, events Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/ Field naming follows existing 3m-ui snake_case convention (not sanaei's tg* prefix) per project maintainer's request. == Data layer == - ProxyUser: add TelegramID (indexed) + TelegramName fields for linking proxy users to their Telegram accounts (self-service queries). - SafeUser + ToSafeUser: expose both new fields. - user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods. - user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram (registered before /:id to avoid path capture). - UpdateInput/CreateInput: accept TelegramID + TelegramName. == Settings expansion (8 new fields, snake_case) == - schedule: cron expr or @daily/@every 6h for periodic reports (default @daily) - attach_backup: include DB backup zip in periodic report - language: bot message language zh/en (default zh) - enabled_events: comma-sep event list (default 'login,cpu,crash') Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic - expiry_warn_days: remind N days before expiry (0=off) - traffic_warn_gb: remind when remaining traffic < N GB (0=off) - proxy_url: socks5:// or http:// proxy for Telegram API - api_server: custom Bot API server (empty=official) - EventEnabled(name) helper for per-event gating. == Client enhancements == - Proxy support: http(s):// via http.Transport.Proxy; socks5:// via golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback. - Custom API server (apiBase() replaces hardcoded URL). - SendDocument: multipart sendDocument for backup file attachment. - GetMe + SetMyCommands: for bot-info + set-my-commands endpoints. - sendWithKeyboard: sendMessage with reply_markup (inline keyboards). - answerCallbackQuery: clear callback loading spinner. == Bot commands + inline menus == - /id: reply with sender's Telegram numeric ID. - /usage: admin → search users; bound user → self-query traffic/expiry/sub URL. - /start + /help: send inline keyboard menu (admin menu for admin chats, user menu for bound users, plain text for unbound). - Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/ backup/restart) in 4 rows. - User menu: my_usage + my_sub buttons. - callback_query handling: answerCallbackQuery + dispatch on callback_data. - Access control: admin chats always pass; non-admin chats pass only when FromID matches a ProxyUser.TelegramID. - Bot struct: added userSvc field for GetByTelegramID lookups. - NewBot signature: NewBot(db, mihomoSvc, userSvc). == Cron scheduler (new telegram/scheduler.go) == - Periodic report goroutine driven by Settings.Schedule. - Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron. - Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted counts. - Optional backup: AttachBackup → system.WriteZip → SendDocument. - Settings reload on every tick (no restart needed for schedule changes). - NotifyEvent(event, details): generic event emitter for one-shot alerts. == Events layer == - login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure). Failure path added to auth/api.go Login handler. Both gated by EventEnabled('login') — admins can mute success spam yet keep failure alerts. - memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as shared 'resource warn %' threshold. 1-hour cooldown dedup. - crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash. Fires on non-zero exit while desired==true (unexpected crash, not admin stop). Wired in app/container.go. - Dual thresholds: expiry (hours + days), traffic (percent + GB) with separate dedup keys so neither suppresses the other. == API endpoints == - POST /telegram/set-my-commands: registers 12-command menu with Telegram. - GET /telegram/bot-info: returns bot username/first_name/id. == Frontend == - telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands + fetchTelegramBotInfo API functions. - Settings.tsx: 8 new form controls (schedule Input, language Select, enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb InputNumber, attach_backup Switch, proxy_url Input, api_server Input). Added 'Set bot commands' button calling setTelegramCommands. - i18n: 11 new keys (zh + en) for the new settings labels. == Verification == - go build ./... : PASS - go vet ./... : PASS - go test ./... : all 15 packages PASS - npm run build (tsc + vite) : PASS, 3241 modules - gofmt : clean feat(telegram): full bot enhancement with inline menus, cron reports, events Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/ Field naming follows existing 3m-ui snake_case convention (not sanaei's tg* prefix) per project maintainer's request. == Data layer == - ProxyUser: add TelegramID (indexed) + TelegramName fields for linking proxy users to their Telegram accounts (self-service queries). - SafeUser + ToSafeUser: expose both new fields. - user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods. - user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram (registered before /:id to avoid path capture). - UpdateInput/CreateInput: accept TelegramID + TelegramName. == Settings expansion (8 new fields, snake_case) == - schedule: cron expr or @daily/@every 6h for periodic reports (default @daily) - attach_backup: include DB backup zip in periodic report - language: bot message language zh/en (default zh) - enabled_events: comma-sep event list (default 'login,cpu,crash') Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic - expiry_warn_days: remind N days before expiry (0=off) - traffic_warn_gb: remind when remaining traffic < N GB (0=off) - proxy_url: socks5:// or http:// proxy for Telegram API - api_server: custom Bot API server (empty=official) - EventEnabled(name) helper for per-event gating. == Client enhancements == - Proxy support: http(s):// via http.Transport.Proxy; socks5:// via golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback. - Custom API server (apiBase() replaces hardcoded URL). - SendDocument: multipart sendDocument for backup file attachment. - GetMe + SetMyCommands: for bot-info + set-my-commands endpoints. - sendWithKeyboard: sendMessage with reply_markup (inline keyboards). - answerCallbackQuery: clear callback loading spinner. == Bot commands + inline menus == - /id: reply with sender's Telegram numeric ID. - /usage: admin → search users; bound user → self-query traffic/expiry/sub URL. - /start + /help: send inline keyboard menu (admin menu for admin chats, user menu for bound users, plain text for unbound). - Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/ backup/restart) in 4 rows. - User menu: my_usage + my_sub buttons. - callback_query handling: answerCallbackQuery + dispatch on callback_data. - Access control: admin chats always pass; non-admin chats pass only when FromID matches a ProxyUser.TelegramID. - Bot struct: added userSvc field for GetByTelegramID lookups. - NewBot signature: NewBot(db, mihomoSvc, userSvc). == Cron scheduler (new telegram/scheduler.go) == - Periodic report goroutine driven by Settings.Schedule. - Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron. - Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted counts. - Optional backup: AttachBackup → system.WriteZip → SendDocument. - Settings reload on every tick (no restart needed for schedule changes). - NotifyEvent(event, details): generic event emitter for one-shot alerts. == Events layer == - login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure). Failure path added to auth/api.go Login handler. Both gated by EventEnabled('login') — admins can mute success spam yet keep failure alerts. - memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as shared 'resource warn %' threshold. 1-hour cooldown dedup. - crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash. Fires on non-zero exit while desired==true (unexpected crash, not admin stop). Wired in app/container.go. - Dual thresholds: expiry (hours + days), traffic (percent + GB) with separate dedup keys so neither suppresses the other. == API endpoints == - POST /telegram/set-my-commands: registers 12-command menu with Telegram. - GET /telegram/bot-info: returns bot username/first_name/id. == Frontend == - telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands + fetchTelegramBotInfo API functions. - Settings.tsx: 8 new form controls (schedule Input, language Select, enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb InputNumber, attach_backup Switch, proxy_url Input, api_server Input). Added 'Set bot commands' button calling setTelegramCommands. - i18n: 11 new keys (zh + en) for the new settings labels. == Verification == - go build ./... : PASS - go vet ./... : PASS - go test ./... : all 15 packages PASS - npm run build (tsc + vite) : PASS, 3241 modules - gofmt : clean |
||
|
|
1823bdb38f |
fix(auth): block telegram bot token leak + rate-limit password change
- C-1: Correct misleading comment in EnsureAdmin. Default credentials remain admin/admin (per deployment ergonomics); RequireAuth already forces MustChangePassword on first login. Add a [SECURITY] log line at first-admin creation so operators are warned. - C-2: GET /api/v1/panel-settings leaked the Telegram Bot Token via a blocklist gap (key 'telegram' does not contain 'token'). Replace the substring filter with isSensitiveSettingKey() which blocks telegram, panel_ssl, and keys containing token/secret/credential/password/ private/bot. Applied to both GET and PUT handlers. - H-6: Add passwordChangeLimiter (3 attempts / 15 min / IP) so an attacker who reaches the panel before the operator cannot trivially rotate the default admin password. Returns 429 when exceeded. Initial admin credentials stay admin/admin; first-login change is still enforced by RequireAuth (only /auth/password and /auth/me are reachable while MustChangePassword=true). fix(auth): block telegram bot token leak + rate-limit password change - C-1: Correct misleading comment in EnsureAdmin. Default credentials remain admin/admin (per deployment ergonomics); RequireAuth already forces MustChangePassword on first login. Add a [SECURITY] log line at first-admin creation so operators are warned. - C-2: GET /api/v1/panel-settings leaked the Telegram Bot Token via a blocklist gap (key 'telegram' does not contain 'token'). Replace the substring filter with isSensitiveSettingKey() which blocks telegram, panel_ssl, and keys containing token/secret/credential/password/ private/bot. Applied to both GET and PUT handlers. - H-6: Add passwordChangeLimiter (3 attempts / 15 min / IP) so an attacker who reaches the panel before the operator cannot trivially rotate the default admin password. Returns 429 when exceeded. Initial admin credentials stay admin/admin; first-login change is still enforced by RequireAuth (only /auth/password and /auth/me are reachable while MustChangePassword=true). fix(auth): block telegram bot token leak + rate-limit password change - C-1: Correct misleading comment in EnsureAdmin. Default credentials remain admin/admin (per deployment ergonomics); RequireAuth already forces MustChangePassword on first login. Add a [SECURITY] log line at first-admin creation so operators are warned. - C-2: GET /api/v1/panel-settings leaked the Telegram Bot Token via a blocklist gap (key 'telegram' does not contain 'token'). Replace the substring filter with isSensitiveSettingKey() which blocks telegram, panel_ssl, and keys containing token/secret/credential/password/ private/bot. Applied to both GET and PUT handlers. - H-6: Add passwordChangeLimiter (3 attempts / 15 min / IP) so an attacker who reaches the panel before the operator cannot trivially rotate the default admin password. Returns 429 when exceeded. Initial admin credentials stay admin/admin; first-login change is still enforced by RequireAuth (only /auth/password and /auth/me are reachable while MustChangePassword=true). fix(auth): block telegram bot token leak + rate-limit password change - C-1: Correct misleading comment in EnsureAdmin. Default credentials remain admin/admin (per deployment ergonomics); RequireAuth already forces MustChangePassword on first login. Add a [SECURITY] log line at first-admin creation so operators are warned. - C-2: GET /api/v1/panel-settings leaked the Telegram Bot Token via a blocklist gap (key 'telegram' does not contain 'token'). Replace the substring filter with isSensitiveSettingKey() which blocks telegram, panel_ssl, and keys containing token/secret/credential/password/ private/bot. Applied to both GET and PUT handlers. - H-6: Add passwordChangeLimiter (3 attempts / 15 min / IP) so an attacker who reaches the panel before the operator cannot trivially rotate the default admin password. Returns 429 when exceeded. Initial admin credentials stay admin/admin; first-login change is still enforced by RequireAuth (only /auth/password and /auth/me are reachable while MustChangePassword=true). fix(auth): block telegram bot token leak + rate-limit password change - C-1: Correct misleading comment in EnsureAdmin. Default credentials remain admin/admin (per deployment ergonomics); RequireAuth already forces MustChangePassword on first login. Add a [SECURITY] log line at first-admin creation so operators are warned. - C-2: GET /api/v1/panel-settings leaked the Telegram Bot Token via a blocklist gap (key 'telegram' does not contain 'token'). Replace the substring filter with isSensitiveSettingKey() which blocks telegram, panel_ssl, and keys containing token/secret/credential/password/ private/bot. Applied to both GET and PUT handlers. - H-6: Add passwordChangeLimiter (3 attempts / 15 min / IP) so an attacker who reaches the panel before the operator cannot trivially rotate the default admin password. Returns 429 when exceeded. Initial admin credentials stay admin/admin; first-login change is still enforced by RequireAuth (only /auth/password and /auth/me are reachable while MustChangePassword=true). fix(auth): block telegram bot token leak + rate-limit password change - C-1: Correct misleading comment in EnsureAdmin. Default credentials remain admin/admin (per deployment ergonomics); RequireAuth already forces MustChangePassword on first login. Add a [SECURITY] log line at first-admin creation so operators are warned. - C-2: GET /api/v1/panel-settings leaked the Telegram Bot Token via a blocklist gap (key 'telegram' does not contain 'token'). Replace the substring filter with isSensitiveSettingKey() which blocks telegram, panel_ssl, and keys containing token/secret/credential/password/ private/bot. Applied to both GET and PUT handlers. - H-6: Add passwordChangeLimiter (3 attempts / 15 min / IP) so an attacker who reaches the panel before the operator cannot trivially rotate the default admin password. Returns 429 when exceeded. Initial admin credentials stay admin/admin; first-login change is still enforced by RequireAuth (only /auth/password and /auth/me are reachable while MustChangePassword=true). fix(auth): block telegram bot token leak + rate-limit password change - C-1: Correct misleading comment in EnsureAdmin. Default credentials remain admin/admin (per deployment ergonomics); RequireAuth already forces MustChangePassword on first login. Add a [SECURITY] log line at first-admin creation so operators are warned. - C-2: GET /api/v1/panel-settings leaked the Telegram Bot Token via a blocklist gap (key 'telegram' does not contain 'token'). Replace the substring filter with isSensitiveSettingKey() which blocks telegram, panel_ssl, and keys containing token/secret/credential/password/ private/bot. Applied to both GET and PUT handlers. - H-6: Add passwordChangeLimiter (3 attempts / 15 min / IP) so an attacker who reaches the panel before the operator cannot trivially rotate the default admin password. Returns 429 when exceeded. Initial admin credentials stay admin/admin; first-login change is still enforced by RequireAuth (only /auth/password and /auth/me are reachable while MustChangePassword=true). fix(auth): block telegram bot token leak + rate-limit password change - C-1: Correct misleading comment in EnsureAdmin. Default credentials remain admin/admin (per deployment ergonomics); RequireAuth already forces MustChangePassword on first login. Add a [SECURITY] log line at first-admin creation so operators are warned. - C-2: GET /api/v1/panel-settings leaked the Telegram Bot Token via a blocklist gap (key 'telegram' does not contain 'token'). Replace the substring filter with isSensitiveSettingKey() which blocks telegram, panel_ssl, and keys containing token/secret/credential/password/ private/bot. Applied to both GET and PUT handlers. - H-6: Add passwordChangeLimiter (3 attempts / 15 min / IP) so an attacker who reaches the panel before the operator cannot trivially rotate the default admin password. Returns 429 when exceeded. Initial admin credentials stay admin/admin; first-login change is still enforced by RequireAuth (only /auth/password and /auth/me are reachable while MustChangePassword=true). fix(auth): block telegram bot token leak + rate-limit password change - C-1: Correct misleading comment in EnsureAdmin. Default credentials remain admin/admin (per deployment ergonomics); RequireAuth already forces MustChangePassword on first login. Add a [SECURITY] log line at first-admin creation so operators are warned. - C-2: GET /api/v1/panel-settings leaked the Telegram Bot Token via a blocklist gap (key 'telegram' does not contain 'token'). Replace the substring filter with isSensitiveSettingKey() which blocks telegram, panel_ssl, and keys containing token/secret/credential/password/ private/bot. Applied to both GET and PUT handlers. - H-6: Add passwordChangeLimiter (3 attempts / 15 min / IP) so an attacker who reaches the panel before the operator cannot trivially rotate the default admin password. Returns 429 when exceeded. Initial admin credentials stay admin/admin; first-login change is still enforced by RequireAuth (only /auth/password and /auth/me are reachable while MustChangePassword=true). fix(auth): block telegram bot token leak + rate-limit password change - C-1: Correct misleading comment in EnsureAdmin. Default credentials remain admin/admin (per deployment ergonomics); RequireAuth already forces MustChangePassword on first login. Add a [SECURITY] log line at first-admin creation so operators are warned. - C-2: GET /api/v1/panel-settings leaked the Telegram Bot Token via a blocklist gap (key 'telegram' does not contain 'token'). Replace the substring filter with isSensitiveSettingKey() which blocks telegram, panel_ssl, and keys containing token/secret/credential/password/ private/bot. Applied to both GET and PUT handlers. - H-6: Add passwordChangeLimiter (3 attempts / 15 min / IP) so an attacker who reaches the panel before the operator cannot trivially rotate the default admin password. Returns 429 when exceeded. Initial admin credentials stay admin/admin; first-login change is still enforced by RequireAuth (only /auth/password and /auth/me are reachable while MustChangePassword=true). fix(auth): block telegram bot token leak + rate-limit password change - C-1: Correct misleading comment in EnsureAdmin. Default credentials remain admin/admin (per deployment ergonomics); RequireAuth already forces MustChangePassword on first login. Add a [SECURITY] log line at first-admin creation so operators are warned. - C-2: GET /api/v1/panel-settings leaked the Telegram Bot Token via a blocklist gap (key 'telegram' does not contain 'token'). Replace the substring filter with isSensitiveSettingKey() which blocks telegram, panel_ssl, and keys containing token/secret/credential/password/ private/bot. Applied to both GET and PUT handlers. - H-6: Add passwordChangeLimiter (3 attempts / 15 min / IP) so an attacker who reaches the panel before the operator cannot trivially rotate the default admin password. Returns 429 when exceeded. Initial admin credentials stay admin/admin; first-login change is still enforced by RequireAuth (only /auth/password and /auth/me are reachable while MustChangePassword=true). fix(auth): block telegram bot token leak + rate-limit password change - C-1: Correct misleading comment in EnsureAdmin. Default credentials remain admin/admin (per deployment ergonomics); RequireAuth already forces MustChangePassword on first login. Add a [SECURITY] log line at first-admin creation so operators are warned. - C-2: GET /api/v1/panel-settings leaked the Telegram Bot Token via a blocklist gap (key 'telegram' does not contain 'token'). Replace the substring filter with isSensitiveSettingKey() which blocks telegram, panel_ssl, and keys containing token/secret/credential/password/ private/bot. Applied to both GET and PUT handlers. - H-6: Add passwordChangeLimiter (3 attempts / 15 min / IP) so an attacker who reaches the panel before the operator cannot trivially rotate the default admin password. Returns 429 when exceeded. Initial admin credentials stay admin/admin; first-login change is still enforced by RequireAuth (only /auth/password and /auth/me are reachable while MustChangePassword=true). |
||
|
|
331cd20d31 | fix(auth): repair JWT source and validate claims | ||
|
|
d0b3f8ef51 | fix(auth): validate JWT claims and token inputs | ||
|
|
475c1fc172 |
style: gofmt for CI
style: gofmt for CI style: gofmt for CI style: gofmt for CI style: gofmt for CI style: gofmt for CI style: gofmt for CI style: gofmt for CI style: gofmt for CI style: gofmt for CI style: gofmt for CI style: gofmt for CI |
||
|
|
885a68e57f | chore: remove internal parity wording from comments and UI | ||
|
|
479ef4e0fa |
feat: more parity — sing-box sub, login TG notify, WARP, search
- Native sing-box JSON subscription (?target=singbox) + UA auto-detect - Enhanced ?format=info with multi-format links and blocked flag - Telegram notify on panel login (settings toggle) - Telegram /backup command; listener list ?q= / enabled filters - System WARP WireGuard YAML template endpoint - Frontend: Sing-box share link, login notify switch, listener search feat: more 3x-ui parity — sing-box sub, login TG notify, WARP, search - Native sing-box JSON subscription (?target=singbox) + UA auto-detect - Enhanced ?format=info with multi-format links and blocked flag - Telegram notify on panel login (settings toggle) - Telegram /backup command; listener list ?q= / enabled filters - System WARP WireGuard YAML template endpoint - Frontend: Sing-box share link, login notify switch, listener search feat: more 3x-ui parity — sing-box sub, login TG notify, WARP, search - Native sing-box JSON subscription (?target=singbox) + UA auto-detect - Enhanced ?format=info with multi-format links and blocked flag - Telegram notify on panel login (settings toggle) - Telegram /backup command; listener list ?q= / enabled filters - System WARP WireGuard YAML template endpoint - Frontend: Sing-box share link, login notify switch, listener search feat: more 3x-ui parity — sing-box sub, login TG notify, WARP, search - Native sing-box JSON subscription (?target=singbox) + UA auto-detect - Enhanced ?format=info with multi-format links and blocked flag - Telegram notify on panel login (settings toggle) - Telegram /backup command; listener list ?q= / enabled filters - System WARP WireGuard YAML template endpoint - Frontend: Sing-box share link, login notify switch, listener search feat: more 3x-ui parity — sing-box sub, login TG notify, WARP, search - Native sing-box JSON subscription (?target=singbox) + UA auto-detect - Enhanced ?format=info with multi-format links and blocked flag - Telegram notify on panel login (settings toggle) - Telegram /backup command; listener list ?q= / enabled filters - System WARP WireGuard YAML template endpoint - Frontend: Sing-box share link, login notify switch, listener search feat: more panel features — sing-box sub, login TG notify, WARP, search - Native sing-box JSON subscription (?target=singbox) + UA auto-detect - Enhanced ?format=info with multi-format links and blocked flag - Telegram notify on panel login (settings toggle) - Telegram /backup command; listener list ?q= / enabled filters - System WARP WireGuard YAML template endpoint - Frontend: Sing-box share link, login notify switch, listener search feat: more panel features — sing-box sub, login TG notify, WARP, search - Native sing-box JSON subscription (?target=singbox) + UA auto-detect - Enhanced ?format=info with multi-format links and blocked flag - Telegram notify on panel login (settings toggle) - Telegram /backup command; listener list ?q= / enabled filters - System WARP WireGuard YAML template endpoint - Frontend: Sing-box share link, login notify switch, listener search feat: more panel features — sing-box sub, login TG notify, WARP, search - Native sing-box JSON subscription (?target=singbox) + UA auto-detect - Enhanced ?format=info with multi-format links and blocked flag - Telegram notify on panel login (settings toggle) - Telegram /backup command; listener list ?q= / enabled filters - System WARP WireGuard YAML template endpoint - Frontend: Sing-box share link, login notify switch, listener search feat: more panel features — sing-box sub, login TG notify, WARP, search - Native sing-box JSON subscription (?target=singbox) + UA auto-detect - Enhanced ?format=info with multi-format links and blocked flag - Telegram notify on panel login (settings toggle) - Telegram /backup command; listener list ?q= / enabled filters - System WARP WireGuard YAML template endpoint - Frontend: Sing-box share link, login notify switch, listener search feat: more panel features — sing-box sub, login TG notify, WARP, search - Native sing-box JSON subscription (?target=singbox) + UA auto-detect - Enhanced ?format=info with multi-format links and blocked flag - Telegram notify on panel login (settings toggle) - Telegram /backup command; listener list ?q= / enabled filters - System WARP WireGuard YAML template endpoint - Frontend: Sing-box share link, login notify switch, listener search feat: more panel features — sing-box sub, login TG notify, WARP, search - Native sing-box JSON subscription (?target=singbox) + UA auto-detect - Enhanced ?format=info with multi-format links and blocked flag - Telegram notify on panel login (settings toggle) - Telegram /backup command; listener list ?q= / enabled filters - System WARP WireGuard YAML template endpoint - Frontend: Sing-box share link, login notify switch, listener search feat: more panel features — sing-box sub, login TG notify, WARP, search - Native sing-box JSON subscription (?target=singbox) + UA auto-detect - Enhanced ?format=info with multi-format links and blocked flag - Telegram notify on panel login (settings toggle) - Telegram /backup command; listener list ?q= / enabled filters - System WARP WireGuard YAML template endpoint - Frontend: Sing-box share link, login notify switch, listener search |
||
|
|
aad12647c9 |
test: cover case-insensitive Bearer parsing
test: cover case-insensitive Bearer parsing test: cover case-insensitive Bearer parsing test: cover case-insensitive Bearer parsing test: cover case-insensitive Bearer parsing test: cover case-insensitive Bearer parsing test: cover case-insensitive Bearer parsing test: cover case-insensitive Bearer parsing test: cover case-insensitive Bearer parsing test: cover case-insensitive Bearer parsing test: cover case-insensitive Bearer parsing test: cover case-insensitive Bearer parsing |
||
|
|
278eb52b1a | fix: parse Authorization scheme case-insensitively | ||
|
|
1591273ad9 | test(auth): cover bearer token extraction and JWT round trip | ||
|
|
0c5cd3d924 | fix(auth): format bearer token parser and claim metadata | ||
|
|
b8ecb2bc4a | Rename index.ts to index.tsx | ||
|
|
6ac6b31a39 | update | ||
|
|
28f4c14057 |
fix: align listener generation with mihomo official spec
- Port now supports mihomo ports format (single/range/list) - Add explicit RoutingMark field support - Auto-propagate UDP flag for vmess/vless/trojan/anytls/trusttunnel - Update validator to accept port ranges - Sync visual config and client converter port types - Rename module from dzx941 to kazeyukiro - Fix missing golang-jwt dependency - Fix frontend tsconfig and add missing axios/zustand dependencies |
||
|
|
5b4cb63a73 |
fix: align listener generation with mihomo official spec
- Port now supports mihomo ports format (single/range/list) - Add explicit RoutingMark field support - Auto-propagate UDP flag for vmess/vless/trojan/anytls/trusttunnel - Update validator to accept port ranges - Sync visual config and client converter port types - Rename module from dzx941 to kazeyukiro - Fix missing ExpiresAt in JWTClaims - Fix nodeDTO Port type to string - Fix frontend tsconfig and add missing dependencies |