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
28 lines
856 B
Go
28 lines
856 B
Go
package telegram
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/shirou/gopsutil/v4/cpu"
|
|
"github.com/shirou/gopsutil/v4/mem"
|
|
)
|
|
|
|
// cpuPercentSample returns a single-element slice giving the host's overall
|
|
// CPU utilization over a short sampling window. The 150ms blocking interval
|
|
// is acceptable here because callers run inside the notifier's periodic
|
|
// scheduler tick — not on a request hot path.
|
|
func cpuPercentSample() ([]float64, error) {
|
|
return cpu.Percent(150*time.Millisecond, false)
|
|
}
|
|
|
|
// memoryPercentSample returns the host's overall RAM used-percentage at the
|
|
// instant of the call. Unlike CPU sampling this is instantaneous (no window),
|
|
// because gopsutil's mem.VirtualMemory() reads /proc/meminfo directly.
|
|
func memoryPercentSample() (float64, error) {
|
|
m, err := mem.VirtualMemory()
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return m.UsedPercent, nil
|
|
}
|