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
35 lines
1.9 KiB
Go
35 lines
1.9 KiB
Go
package models
|
|
|
|
import "time"
|
|
|
|
// ProxyUser is a user account used to authenticate against Mihomo server nodes.
|
|
// It is deliberately separate from User, which represents a 3m-ui administrator.
|
|
type ProxyUser struct {
|
|
BaseModel
|
|
|
|
Username string `gorm:"size:100;not null;uniqueIndex" json:"username"`
|
|
// PasswordEncrypted contains an AES-GCM encrypted password. It is never serialized to API responses.
|
|
PasswordEncrypted string `gorm:"type:text" json:"-"`
|
|
UUID string `gorm:"size:64;not null;uniqueIndex" json:"-"`
|
|
TrafficLimit int64 `gorm:"not null;default:0" json:"traffic_limit"`
|
|
TrafficUsed int64 `gorm:"not null;default:0" json:"traffic_used"`
|
|
UploadBytes int64 `gorm:"not null;default:0" json:"upload_bytes"`
|
|
DownloadBytes int64 `gorm:"not null;default:0" json:"download_bytes"`
|
|
LastSeen *time.Time `json:"last_seen"`
|
|
Online bool `gorm:"not null;default:false" json:"online"`
|
|
ExpireTime time.Time `json:"expire_time"`
|
|
Enabled bool `gorm:"not null;default:true" json:"enabled"`
|
|
// IPLimit is max concurrent client IPs (0 = unlimited). Max concurrent client IPs.
|
|
IPLimit int `gorm:"not null;default:0" json:"ip_limit"`
|
|
// Remark is an admin-facing note (not used for auth).
|
|
Remark string `gorm:"size:255" json:"remark"`
|
|
// SubToken is the public subscription credential (client sub).
|
|
// Unique when set; empty legacy rows are filled during InitDB migration.
|
|
SubToken string `gorm:"size:64;uniqueIndex" json:"sub_token,omitempty"`
|
|
// TelegramID is the linked Telegram chat/user numeric ID (0 = not bound).
|
|
// Indexed so the bot can look up a proxy user from an incoming Telegram message.
|
|
TelegramID int64 `gorm:"index;default:0" json:"telegram_id,omitempty"`
|
|
// TelegramName is the display name of the linked Telegram account (best-effort cache).
|
|
TelegramName string `gorm:"size:64;default:''" json:"telegram_name,omitempty"`
|
|
}
|