Files
3m-ui/backend/internal/auth
風雪 dc13e69951 feat(telegram): full bot enhancement with inline menus, cron reports, events
Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/
Field naming follows existing 3m-ui snake_case convention (not sanaei's
tg* prefix) per project maintainer's request.
== Data layer ==
- ProxyUser: add TelegramID (indexed) + TelegramName fields for linking
proxy users to their Telegram accounts (self-service queries).
- SafeUser + ToSafeUser: expose both new fields.
- user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods.
- user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram
(registered before /:id to avoid path capture).
- UpdateInput/CreateInput: accept TelegramID + TelegramName.
== Settings expansion (8 new fields, snake_case) ==
- schedule: cron expr or @daily/@every 6h for periodic reports (default @daily)
- attach_backup: include DB backup zip in periodic report
- language: bot message language zh/en (default zh)
- enabled_events: comma-sep event list (default 'login,cpu,crash')
Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic
- expiry_warn_days: remind N days before expiry (0=off)
- traffic_warn_gb: remind when remaining traffic < N GB (0=off)
- proxy_url: socks5:// or http:// proxy for Telegram API
- api_server: custom Bot API server (empty=official)
- EventEnabled(name) helper for per-event gating.
== Client enhancements ==
- Proxy support: http(s):// via http.Transport.Proxy; socks5:// via
golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback.
- Custom API server (apiBase() replaces hardcoded URL).
- SendDocument: multipart sendDocument for backup file attachment.
- GetMe + SetMyCommands: for bot-info + set-my-commands endpoints.
- sendWithKeyboard: sendMessage with reply_markup (inline keyboards).
- answerCallbackQuery: clear callback loading spinner.
== Bot commands + inline menus ==
- /id: reply with sender's Telegram numeric ID.
- /usage: admin → search users; bound user → self-query traffic/expiry/sub URL.
- /start + /help: send inline keyboard menu (admin menu for admin chats,
user menu for bound users, plain text for unbound).
- Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/
backup/restart) in 4 rows.
- User menu: my_usage + my_sub buttons.
- callback_query handling: answerCallbackQuery + dispatch on callback_data.
- Access control: admin chats always pass; non-admin chats pass only when
FromID matches a ProxyUser.TelegramID.
- Bot struct: added userSvc field for GetByTelegramID lookups.
- NewBot signature: NewBot(db, mihomoSvc, userSvc).
== Cron scheduler (new telegram/scheduler.go) ==
- Periodic report goroutine driven by Settings.Schedule.
- Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron.
- Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted
counts.
- Optional backup: AttachBackup → system.WriteZip → SendDocument.
- Settings reload on every tick (no restart needed for schedule changes).
- NotifyEvent(event, details): generic event emitter for one-shot alerts.
== Events layer ==
- login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure).
Failure path added to auth/api.go Login handler. Both gated by
EventEnabled('login') — admins can mute success spam yet keep failure alerts.
- memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as
shared 'resource warn %' threshold. 1-hour cooldown dedup.
- crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash.
Fires on non-zero exit while desired==true (unexpected crash, not admin stop).
Wired in app/container.go.
- Dual thresholds: expiry (hours + days), traffic (percent + GB) with
separate dedup keys so neither suppresses the other.
== API endpoints ==
- POST /telegram/set-my-commands: registers 12-command menu with Telegram.
- GET /telegram/bot-info: returns bot username/first_name/id.
== Frontend ==
- telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands
+ fetchTelegramBotInfo API functions.
- Settings.tsx: 8 new form controls (schedule Input, language Select,
enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb
InputNumber, attach_backup Switch, proxy_url Input, api_server Input).
Added 'Set bot commands' button calling setTelegramCommands.
- i18n: 11 new keys (zh + en) for the new settings labels.
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : all 15 packages PASS
- npm run build (tsc + vite) : PASS, 3241 modules
- gofmt : clean
feat(telegram): full bot enhancement with inline menus, cron reports, events
Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/
Field naming follows existing 3m-ui snake_case convention (not sanaei's
tg* prefix) per project maintainer's request.
== Data layer ==
- ProxyUser: add TelegramID (indexed) + TelegramName fields for linking
proxy users to their Telegram accounts (self-service queries).
- SafeUser + ToSafeUser: expose both new fields.
- user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods.
- user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram
(registered before /:id to avoid path capture).
- UpdateInput/CreateInput: accept TelegramID + TelegramName.
== Settings expansion (8 new fields, snake_case) ==
- schedule: cron expr or @daily/@every 6h for periodic reports (default @daily)
- attach_backup: include DB backup zip in periodic report
- language: bot message language zh/en (default zh)
- enabled_events: comma-sep event list (default 'login,cpu,crash')
Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic
- expiry_warn_days: remind N days before expiry (0=off)
- traffic_warn_gb: remind when remaining traffic < N GB (0=off)
- proxy_url: socks5:// or http:// proxy for Telegram API
- api_server: custom Bot API server (empty=official)
- EventEnabled(name) helper for per-event gating.
== Client enhancements ==
- Proxy support: http(s):// via http.Transport.Proxy; socks5:// via
golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback.
- Custom API server (apiBase() replaces hardcoded URL).
- SendDocument: multipart sendDocument for backup file attachment.
- GetMe + SetMyCommands: for bot-info + set-my-commands endpoints.
- sendWithKeyboard: sendMessage with reply_markup (inline keyboards).
- answerCallbackQuery: clear callback loading spinner.
== Bot commands + inline menus ==
- /id: reply with sender's Telegram numeric ID.
- /usage: admin → search users; bound user → self-query traffic/expiry/sub URL.
- /start + /help: send inline keyboard menu (admin menu for admin chats,
user menu for bound users, plain text for unbound).
- Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/
backup/restart) in 4 rows.
- User menu: my_usage + my_sub buttons.
- callback_query handling: answerCallbackQuery + dispatch on callback_data.
- Access control: admin chats always pass; non-admin chats pass only when
FromID matches a ProxyUser.TelegramID.
- Bot struct: added userSvc field for GetByTelegramID lookups.
- NewBot signature: NewBot(db, mihomoSvc, userSvc).
== Cron scheduler (new telegram/scheduler.go) ==
- Periodic report goroutine driven by Settings.Schedule.
- Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron.
- Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted
counts.
- Optional backup: AttachBackup → system.WriteZip → SendDocument.
- Settings reload on every tick (no restart needed for schedule changes).
- NotifyEvent(event, details): generic event emitter for one-shot alerts.
== Events layer ==
- login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure).
Failure path added to auth/api.go Login handler. Both gated by
EventEnabled('login') — admins can mute success spam yet keep failure alerts.
- memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as
shared 'resource warn %' threshold. 1-hour cooldown dedup.
- crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash.
Fires on non-zero exit while desired==true (unexpected crash, not admin stop).
Wired in app/container.go.
- Dual thresholds: expiry (hours + days), traffic (percent + GB) with
separate dedup keys so neither suppresses the other.
== API endpoints ==
- POST /telegram/set-my-commands: registers 12-command menu with Telegram.
- GET /telegram/bot-info: returns bot username/first_name/id.
== Frontend ==
- telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands
+ fetchTelegramBotInfo API functions.
- Settings.tsx: 8 new form controls (schedule Input, language Select,
enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb
InputNumber, attach_backup Switch, proxy_url Input, api_server Input).
Added 'Set bot commands' button calling setTelegramCommands.
- i18n: 11 new keys (zh + en) for the new settings labels.
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : all 15 packages PASS
- npm run build (tsc + vite) : PASS, 3241 modules
- gofmt : clean
feat(telegram): full bot enhancement with inline menus, cron reports, events
Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/
Field naming follows existing 3m-ui snake_case convention (not sanaei's
tg* prefix) per project maintainer's request.
== Data layer ==
- ProxyUser: add TelegramID (indexed) + TelegramName fields for linking
proxy users to their Telegram accounts (self-service queries).
- SafeUser + ToSafeUser: expose both new fields.
- user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods.
- user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram
(registered before /:id to avoid path capture).
- UpdateInput/CreateInput: accept TelegramID + TelegramName.
== Settings expansion (8 new fields, snake_case) ==
- schedule: cron expr or @daily/@every 6h for periodic reports (default @daily)
- attach_backup: include DB backup zip in periodic report
- language: bot message language zh/en (default zh)
- enabled_events: comma-sep event list (default 'login,cpu,crash')
Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic
- expiry_warn_days: remind N days before expiry (0=off)
- traffic_warn_gb: remind when remaining traffic < N GB (0=off)
- proxy_url: socks5:// or http:// proxy for Telegram API
- api_server: custom Bot API server (empty=official)
- EventEnabled(name) helper for per-event gating.
== Client enhancements ==
- Proxy support: http(s):// via http.Transport.Proxy; socks5:// via
golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback.
- Custom API server (apiBase() replaces hardcoded URL).
- SendDocument: multipart sendDocument for backup file attachment.
- GetMe + SetMyCommands: for bot-info + set-my-commands endpoints.
- sendWithKeyboard: sendMessage with reply_markup (inline keyboards).
- answerCallbackQuery: clear callback loading spinner.
== Bot commands + inline menus ==
- /id: reply with sender's Telegram numeric ID.
- /usage: admin → search users; bound user → self-query traffic/expiry/sub URL.
- /start + /help: send inline keyboard menu (admin menu for admin chats,
user menu for bound users, plain text for unbound).
- Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/
backup/restart) in 4 rows.
- User menu: my_usage + my_sub buttons.
- callback_query handling: answerCallbackQuery + dispatch on callback_data.
- Access control: admin chats always pass; non-admin chats pass only when
FromID matches a ProxyUser.TelegramID.
- Bot struct: added userSvc field for GetByTelegramID lookups.
- NewBot signature: NewBot(db, mihomoSvc, userSvc).
== Cron scheduler (new telegram/scheduler.go) ==
- Periodic report goroutine driven by Settings.Schedule.
- Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron.
- Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted
counts.
- Optional backup: AttachBackup → system.WriteZip → SendDocument.
- Settings reload on every tick (no restart needed for schedule changes).
- NotifyEvent(event, details): generic event emitter for one-shot alerts.
== Events layer ==
- login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure).
Failure path added to auth/api.go Login handler. Both gated by
EventEnabled('login') — admins can mute success spam yet keep failure alerts.
- memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as
shared 'resource warn %' threshold. 1-hour cooldown dedup.
- crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash.
Fires on non-zero exit while desired==true (unexpected crash, not admin stop).
Wired in app/container.go.
- Dual thresholds: expiry (hours + days), traffic (percent + GB) with
separate dedup keys so neither suppresses the other.
== API endpoints ==
- POST /telegram/set-my-commands: registers 12-command menu with Telegram.
- GET /telegram/bot-info: returns bot username/first_name/id.
== Frontend ==
- telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands
+ fetchTelegramBotInfo API functions.
- Settings.tsx: 8 new form controls (schedule Input, language Select,
enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb
InputNumber, attach_backup Switch, proxy_url Input, api_server Input).
Added 'Set bot commands' button calling setTelegramCommands.
- i18n: 11 new keys (zh + en) for the new settings labels.
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : all 15 packages PASS
- npm run build (tsc + vite) : PASS, 3241 modules
- gofmt : clean
feat(telegram): full bot enhancement with inline menus, cron reports, events
Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/
Field naming follows existing 3m-ui snake_case convention (not sanaei's
tg* prefix) per project maintainer's request.
== Data layer ==
- ProxyUser: add TelegramID (indexed) + TelegramName fields for linking
proxy users to their Telegram accounts (self-service queries).
- SafeUser + ToSafeUser: expose both new fields.
- user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods.
- user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram
(registered before /:id to avoid path capture).
- UpdateInput/CreateInput: accept TelegramID + TelegramName.
== Settings expansion (8 new fields, snake_case) ==
- schedule: cron expr or @daily/@every 6h for periodic reports (default @daily)
- attach_backup: include DB backup zip in periodic report
- language: bot message language zh/en (default zh)
- enabled_events: comma-sep event list (default 'login,cpu,crash')
Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic
- expiry_warn_days: remind N days before expiry (0=off)
- traffic_warn_gb: remind when remaining traffic < N GB (0=off)
- proxy_url: socks5:// or http:// proxy for Telegram API
- api_server: custom Bot API server (empty=official)
- EventEnabled(name) helper for per-event gating.
== Client enhancements ==
- Proxy support: http(s):// via http.Transport.Proxy; socks5:// via
golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback.
- Custom API server (apiBase() replaces hardcoded URL).
- SendDocument: multipart sendDocument for backup file attachment.
- GetMe + SetMyCommands: for bot-info + set-my-commands endpoints.
- sendWithKeyboard: sendMessage with reply_markup (inline keyboards).
- answerCallbackQuery: clear callback loading spinner.
== Bot commands + inline menus ==
- /id: reply with sender's Telegram numeric ID.
- /usage: admin → search users; bound user → self-query traffic/expiry/sub URL.
- /start + /help: send inline keyboard menu (admin menu for admin chats,
user menu for bound users, plain text for unbound).
- Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/
backup/restart) in 4 rows.
- User menu: my_usage + my_sub buttons.
- callback_query handling: answerCallbackQuery + dispatch on callback_data.
- Access control: admin chats always pass; non-admin chats pass only when
FromID matches a ProxyUser.TelegramID.
- Bot struct: added userSvc field for GetByTelegramID lookups.
- NewBot signature: NewBot(db, mihomoSvc, userSvc).
== Cron scheduler (new telegram/scheduler.go) ==
- Periodic report goroutine driven by Settings.Schedule.
- Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron.
- Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted
counts.
- Optional backup: AttachBackup → system.WriteZip → SendDocument.
- Settings reload on every tick (no restart needed for schedule changes).
- NotifyEvent(event, details): generic event emitter for one-shot alerts.
== Events layer ==
- login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure).
Failure path added to auth/api.go Login handler. Both gated by
EventEnabled('login') — admins can mute success spam yet keep failure alerts.
- memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as
shared 'resource warn %' threshold. 1-hour cooldown dedup.
- crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash.
Fires on non-zero exit while desired==true (unexpected crash, not admin stop).
Wired in app/container.go.
- Dual thresholds: expiry (hours + days), traffic (percent + GB) with
separate dedup keys so neither suppresses the other.
== API endpoints ==
- POST /telegram/set-my-commands: registers 12-command menu with Telegram.
- GET /telegram/bot-info: returns bot username/first_name/id.
== Frontend ==
- telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands
+ fetchTelegramBotInfo API functions.
- Settings.tsx: 8 new form controls (schedule Input, language Select,
enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb
InputNumber, attach_backup Switch, proxy_url Input, api_server Input).
Added 'Set bot commands' button calling setTelegramCommands.
- i18n: 11 new keys (zh + en) for the new settings labels.
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : all 15 packages PASS
- npm run build (tsc + vite) : PASS, 3241 modules
- gofmt : clean
feat(telegram): full bot enhancement with inline menus, cron reports, events
Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/
Field naming follows existing 3m-ui snake_case convention (not sanaei's
tg* prefix) per project maintainer's request.
== Data layer ==
- ProxyUser: add TelegramID (indexed) + TelegramName fields for linking
proxy users to their Telegram accounts (self-service queries).
- SafeUser + ToSafeUser: expose both new fields.
- user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods.
- user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram
(registered before /:id to avoid path capture).
- UpdateInput/CreateInput: accept TelegramID + TelegramName.
== Settings expansion (8 new fields, snake_case) ==
- schedule: cron expr or @daily/@every 6h for periodic reports (default @daily)
- attach_backup: include DB backup zip in periodic report
- language: bot message language zh/en (default zh)
- enabled_events: comma-sep event list (default 'login,cpu,crash')
Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic
- expiry_warn_days: remind N days before expiry (0=off)
- traffic_warn_gb: remind when remaining traffic < N GB (0=off)
- proxy_url: socks5:// or http:// proxy for Telegram API
- api_server: custom Bot API server (empty=official)
- EventEnabled(name) helper for per-event gating.
== Client enhancements ==
- Proxy support: http(s):// via http.Transport.Proxy; socks5:// via
golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback.
- Custom API server (apiBase() replaces hardcoded URL).
- SendDocument: multipart sendDocument for backup file attachment.
- GetMe + SetMyCommands: for bot-info + set-my-commands endpoints.
- sendWithKeyboard: sendMessage with reply_markup (inline keyboards).
- answerCallbackQuery: clear callback loading spinner.
== Bot commands + inline menus ==
- /id: reply with sender's Telegram numeric ID.
- /usage: admin → search users; bound user → self-query traffic/expiry/sub URL.
- /start + /help: send inline keyboard menu (admin menu for admin chats,
user menu for bound users, plain text for unbound).
- Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/
backup/restart) in 4 rows.
- User menu: my_usage + my_sub buttons.
- callback_query handling: answerCallbackQuery + dispatch on callback_data.
- Access control: admin chats always pass; non-admin chats pass only when
FromID matches a ProxyUser.TelegramID.
- Bot struct: added userSvc field for GetByTelegramID lookups.
- NewBot signature: NewBot(db, mihomoSvc, userSvc).
== Cron scheduler (new telegram/scheduler.go) ==
- Periodic report goroutine driven by Settings.Schedule.
- Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron.
- Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted
counts.
- Optional backup: AttachBackup → system.WriteZip → SendDocument.
- Settings reload on every tick (no restart needed for schedule changes).
- NotifyEvent(event, details): generic event emitter for one-shot alerts.
== Events layer ==
- login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure).
Failure path added to auth/api.go Login handler. Both gated by
EventEnabled('login') — admins can mute success spam yet keep failure alerts.
- memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as
shared 'resource warn %' threshold. 1-hour cooldown dedup.
- crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash.
Fires on non-zero exit while desired==true (unexpected crash, not admin stop).
Wired in app/container.go.
- Dual thresholds: expiry (hours + days), traffic (percent + GB) with
separate dedup keys so neither suppresses the other.
== API endpoints ==
- POST /telegram/set-my-commands: registers 12-command menu with Telegram.
- GET /telegram/bot-info: returns bot username/first_name/id.
== Frontend ==
- telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands
+ fetchTelegramBotInfo API functions.
- Settings.tsx: 8 new form controls (schedule Input, language Select,
enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb
InputNumber, attach_backup Switch, proxy_url Input, api_server Input).
Added 'Set bot commands' button calling setTelegramCommands.
- i18n: 11 new keys (zh + en) for the new settings labels.
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : all 15 packages PASS
- npm run build (tsc + vite) : PASS, 3241 modules
- gofmt : clean
feat(telegram): full bot enhancement with inline menus, cron reports, events
Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/
Field naming follows existing 3m-ui snake_case convention (not sanaei's
tg* prefix) per project maintainer's request.
== Data layer ==
- ProxyUser: add TelegramID (indexed) + TelegramName fields for linking
proxy users to their Telegram accounts (self-service queries).
- SafeUser + ToSafeUser: expose both new fields.
- user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods.
- user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram
(registered before /:id to avoid path capture).
- UpdateInput/CreateInput: accept TelegramID + TelegramName.
== Settings expansion (8 new fields, snake_case) ==
- schedule: cron expr or @daily/@every 6h for periodic reports (default @daily)
- attach_backup: include DB backup zip in periodic report
- language: bot message language zh/en (default zh)
- enabled_events: comma-sep event list (default 'login,cpu,crash')
Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic
- expiry_warn_days: remind N days before expiry (0=off)
- traffic_warn_gb: remind when remaining traffic < N GB (0=off)
- proxy_url: socks5:// or http:// proxy for Telegram API
- api_server: custom Bot API server (empty=official)
- EventEnabled(name) helper for per-event gating.
== Client enhancements ==
- Proxy support: http(s):// via http.Transport.Proxy; socks5:// via
golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback.
- Custom API server (apiBase() replaces hardcoded URL).
- SendDocument: multipart sendDocument for backup file attachment.
- GetMe + SetMyCommands: for bot-info + set-my-commands endpoints.
- sendWithKeyboard: sendMessage with reply_markup (inline keyboards).
- answerCallbackQuery: clear callback loading spinner.
== Bot commands + inline menus ==
- /id: reply with sender's Telegram numeric ID.
- /usage: admin → search users; bound user → self-query traffic/expiry/sub URL.
- /start + /help: send inline keyboard menu (admin menu for admin chats,
user menu for bound users, plain text for unbound).
- Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/
backup/restart) in 4 rows.
- User menu: my_usage + my_sub buttons.
- callback_query handling: answerCallbackQuery + dispatch on callback_data.
- Access control: admin chats always pass; non-admin chats pass only when
FromID matches a ProxyUser.TelegramID.
- Bot struct: added userSvc field for GetByTelegramID lookups.
- NewBot signature: NewBot(db, mihomoSvc, userSvc).
== Cron scheduler (new telegram/scheduler.go) ==
- Periodic report goroutine driven by Settings.Schedule.
- Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron.
- Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted
counts.
- Optional backup: AttachBackup → system.WriteZip → SendDocument.
- Settings reload on every tick (no restart needed for schedule changes).
- NotifyEvent(event, details): generic event emitter for one-shot alerts.
== Events layer ==
- login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure).
Failure path added to auth/api.go Login handler. Both gated by
EventEnabled('login') — admins can mute success spam yet keep failure alerts.
- memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as
shared 'resource warn %' threshold. 1-hour cooldown dedup.
- crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash.
Fires on non-zero exit while desired==true (unexpected crash, not admin stop).
Wired in app/container.go.
- Dual thresholds: expiry (hours + days), traffic (percent + GB) with
separate dedup keys so neither suppresses the other.
== API endpoints ==
- POST /telegram/set-my-commands: registers 12-command menu with Telegram.
- GET /telegram/bot-info: returns bot username/first_name/id.
== Frontend ==
- telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands
+ fetchTelegramBotInfo API functions.
- Settings.tsx: 8 new form controls (schedule Input, language Select,
enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb
InputNumber, attach_backup Switch, proxy_url Input, api_server Input).
Added 'Set bot commands' button calling setTelegramCommands.
- i18n: 11 new keys (zh + en) for the new settings labels.
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : all 15 packages PASS
- npm run build (tsc + vite) : PASS, 3241 modules
- gofmt : clean
feat(telegram): full bot enhancement with inline menus, cron reports, events
Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/
Field naming follows existing 3m-ui snake_case convention (not sanaei's
tg* prefix) per project maintainer's request.
== Data layer ==
- ProxyUser: add TelegramID (indexed) + TelegramName fields for linking
proxy users to their Telegram accounts (self-service queries).
- SafeUser + ToSafeUser: expose both new fields.
- user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods.
- user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram
(registered before /:id to avoid path capture).
- UpdateInput/CreateInput: accept TelegramID + TelegramName.
== Settings expansion (8 new fields, snake_case) ==
- schedule: cron expr or @daily/@every 6h for periodic reports (default @daily)
- attach_backup: include DB backup zip in periodic report
- language: bot message language zh/en (default zh)
- enabled_events: comma-sep event list (default 'login,cpu,crash')
Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic
- expiry_warn_days: remind N days before expiry (0=off)
- traffic_warn_gb: remind when remaining traffic < N GB (0=off)
- proxy_url: socks5:// or http:// proxy for Telegram API
- api_server: custom Bot API server (empty=official)
- EventEnabled(name) helper for per-event gating.
== Client enhancements ==
- Proxy support: http(s):// via http.Transport.Proxy; socks5:// via
golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback.
- Custom API server (apiBase() replaces hardcoded URL).
- SendDocument: multipart sendDocument for backup file attachment.
- GetMe + SetMyCommands: for bot-info + set-my-commands endpoints.
- sendWithKeyboard: sendMessage with reply_markup (inline keyboards).
- answerCallbackQuery: clear callback loading spinner.
== Bot commands + inline menus ==
- /id: reply with sender's Telegram numeric ID.
- /usage: admin → search users; bound user → self-query traffic/expiry/sub URL.
- /start + /help: send inline keyboard menu (admin menu for admin chats,
user menu for bound users, plain text for unbound).
- Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/
backup/restart) in 4 rows.
- User menu: my_usage + my_sub buttons.
- callback_query handling: answerCallbackQuery + dispatch on callback_data.
- Access control: admin chats always pass; non-admin chats pass only when
FromID matches a ProxyUser.TelegramID.
- Bot struct: added userSvc field for GetByTelegramID lookups.
- NewBot signature: NewBot(db, mihomoSvc, userSvc).
== Cron scheduler (new telegram/scheduler.go) ==
- Periodic report goroutine driven by Settings.Schedule.
- Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron.
- Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted
counts.
- Optional backup: AttachBackup → system.WriteZip → SendDocument.
- Settings reload on every tick (no restart needed for schedule changes).
- NotifyEvent(event, details): generic event emitter for one-shot alerts.
== Events layer ==
- login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure).
Failure path added to auth/api.go Login handler. Both gated by
EventEnabled('login') — admins can mute success spam yet keep failure alerts.
- memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as
shared 'resource warn %' threshold. 1-hour cooldown dedup.
- crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash.
Fires on non-zero exit while desired==true (unexpected crash, not admin stop).
Wired in app/container.go.
- Dual thresholds: expiry (hours + days), traffic (percent + GB) with
separate dedup keys so neither suppresses the other.
== API endpoints ==
- POST /telegram/set-my-commands: registers 12-command menu with Telegram.
- GET /telegram/bot-info: returns bot username/first_name/id.
== Frontend ==
- telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands
+ fetchTelegramBotInfo API functions.
- Settings.tsx: 8 new form controls (schedule Input, language Select,
enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb
InputNumber, attach_backup Switch, proxy_url Input, api_server Input).
Added 'Set bot commands' button calling setTelegramCommands.
- i18n: 11 new keys (zh + en) for the new settings labels.
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : all 15 packages PASS
- npm run build (tsc + vite) : PASS, 3241 modules
- gofmt : clean
feat(telegram): full bot enhancement with inline menus, cron reports, events
Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/
Field naming follows existing 3m-ui snake_case convention (not sanaei's
tg* prefix) per project maintainer's request.
== Data layer ==
- ProxyUser: add TelegramID (indexed) + TelegramName fields for linking
proxy users to their Telegram accounts (self-service queries).
- SafeUser + ToSafeUser: expose both new fields.
- user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods.
- user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram
(registered before /:id to avoid path capture).
- UpdateInput/CreateInput: accept TelegramID + TelegramName.
== Settings expansion (8 new fields, snake_case) ==
- schedule: cron expr or @daily/@every 6h for periodic reports (default @daily)
- attach_backup: include DB backup zip in periodic report
- language: bot message language zh/en (default zh)
- enabled_events: comma-sep event list (default 'login,cpu,crash')
Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic
- expiry_warn_days: remind N days before expiry (0=off)
- traffic_warn_gb: remind when remaining traffic < N GB (0=off)
- proxy_url: socks5:// or http:// proxy for Telegram API
- api_server: custom Bot API server (empty=official)
- EventEnabled(name) helper for per-event gating.
== Client enhancements ==
- Proxy support: http(s):// via http.Transport.Proxy; socks5:// via
golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback.
- Custom API server (apiBase() replaces hardcoded URL).
- SendDocument: multipart sendDocument for backup file attachment.
- GetMe + SetMyCommands: for bot-info + set-my-commands endpoints.
- sendWithKeyboard: sendMessage with reply_markup (inline keyboards).
- answerCallbackQuery: clear callback loading spinner.
== Bot commands + inline menus ==
- /id: reply with sender's Telegram numeric ID.
- /usage: admin → search users; bound user → self-query traffic/expiry/sub URL.
- /start + /help: send inline keyboard menu (admin menu for admin chats,
user menu for bound users, plain text for unbound).
- Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/
backup/restart) in 4 rows.
- User menu: my_usage + my_sub buttons.
- callback_query handling: answerCallbackQuery + dispatch on callback_data.
- Access control: admin chats always pass; non-admin chats pass only when
FromID matches a ProxyUser.TelegramID.
- Bot struct: added userSvc field for GetByTelegramID lookups.
- NewBot signature: NewBot(db, mihomoSvc, userSvc).
== Cron scheduler (new telegram/scheduler.go) ==
- Periodic report goroutine driven by Settings.Schedule.
- Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron.
- Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted
counts.
- Optional backup: AttachBackup → system.WriteZip → SendDocument.
- Settings reload on every tick (no restart needed for schedule changes).
- NotifyEvent(event, details): generic event emitter for one-shot alerts.
== Events layer ==
- login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure).
Failure path added to auth/api.go Login handler. Both gated by
EventEnabled('login') — admins can mute success spam yet keep failure alerts.
- memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as
shared 'resource warn %' threshold. 1-hour cooldown dedup.
- crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash.
Fires on non-zero exit while desired==true (unexpected crash, not admin stop).
Wired in app/container.go.
- Dual thresholds: expiry (hours + days), traffic (percent + GB) with
separate dedup keys so neither suppresses the other.
== API endpoints ==
- POST /telegram/set-my-commands: registers 12-command menu with Telegram.
- GET /telegram/bot-info: returns bot username/first_name/id.
== Frontend ==
- telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands
+ fetchTelegramBotInfo API functions.
- Settings.tsx: 8 new form controls (schedule Input, language Select,
enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb
InputNumber, attach_backup Switch, proxy_url Input, api_server Input).
Added 'Set bot commands' button calling setTelegramCommands.
- i18n: 11 new keys (zh + en) for the new settings labels.
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : all 15 packages PASS
- npm run build (tsc + vite) : PASS, 3241 modules
- gofmt : clean
feat(telegram): full bot enhancement with inline menus, cron reports, events
Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/
Field naming follows existing 3m-ui snake_case convention (not sanaei's
tg* prefix) per project maintainer's request.
== Data layer ==
- ProxyUser: add TelegramID (indexed) + TelegramName fields for linking
proxy users to their Telegram accounts (self-service queries).
- SafeUser + ToSafeUser: expose both new fields.
- user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods.
- user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram
(registered before /:id to avoid path capture).
- UpdateInput/CreateInput: accept TelegramID + TelegramName.
== Settings expansion (8 new fields, snake_case) ==
- schedule: cron expr or @daily/@every 6h for periodic reports (default @daily)
- attach_backup: include DB backup zip in periodic report
- language: bot message language zh/en (default zh)
- enabled_events: comma-sep event list (default 'login,cpu,crash')
Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic
- expiry_warn_days: remind N days before expiry (0=off)
- traffic_warn_gb: remind when remaining traffic < N GB (0=off)
- proxy_url: socks5:// or http:// proxy for Telegram API
- api_server: custom Bot API server (empty=official)
- EventEnabled(name) helper for per-event gating.
== Client enhancements ==
- Proxy support: http(s):// via http.Transport.Proxy; socks5:// via
golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback.
- Custom API server (apiBase() replaces hardcoded URL).
- SendDocument: multipart sendDocument for backup file attachment.
- GetMe + SetMyCommands: for bot-info + set-my-commands endpoints.
- sendWithKeyboard: sendMessage with reply_markup (inline keyboards).
- answerCallbackQuery: clear callback loading spinner.
== Bot commands + inline menus ==
- /id: reply with sender's Telegram numeric ID.
- /usage: admin → search users; bound user → self-query traffic/expiry/sub URL.
- /start + /help: send inline keyboard menu (admin menu for admin chats,
user menu for bound users, plain text for unbound).
- Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/
backup/restart) in 4 rows.
- User menu: my_usage + my_sub buttons.
- callback_query handling: answerCallbackQuery + dispatch on callback_data.
- Access control: admin chats always pass; non-admin chats pass only when
FromID matches a ProxyUser.TelegramID.
- Bot struct: added userSvc field for GetByTelegramID lookups.
- NewBot signature: NewBot(db, mihomoSvc, userSvc).
== Cron scheduler (new telegram/scheduler.go) ==
- Periodic report goroutine driven by Settings.Schedule.
- Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron.
- Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted
counts.
- Optional backup: AttachBackup → system.WriteZip → SendDocument.
- Settings reload on every tick (no restart needed for schedule changes).
- NotifyEvent(event, details): generic event emitter for one-shot alerts.
== Events layer ==
- login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure).
Failure path added to auth/api.go Login handler. Both gated by
EventEnabled('login') — admins can mute success spam yet keep failure alerts.
- memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as
shared 'resource warn %' threshold. 1-hour cooldown dedup.
- crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash.
Fires on non-zero exit while desired==true (unexpected crash, not admin stop).
Wired in app/container.go.
- Dual thresholds: expiry (hours + days), traffic (percent + GB) with
separate dedup keys so neither suppresses the other.
== API endpoints ==
- POST /telegram/set-my-commands: registers 12-command menu with Telegram.
- GET /telegram/bot-info: returns bot username/first_name/id.
== Frontend ==
- telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands
+ fetchTelegramBotInfo API functions.
- Settings.tsx: 8 new form controls (schedule Input, language Select,
enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb
InputNumber, attach_backup Switch, proxy_url Input, api_server Input).
Added 'Set bot commands' button calling setTelegramCommands.
- i18n: 11 new keys (zh + en) for the new settings labels.
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : all 15 packages PASS
- npm run build (tsc + vite) : PASS, 3241 modules
- gofmt : clean
feat(telegram): full bot enhancement with inline menus, cron reports, events
Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/
Field naming follows existing 3m-ui snake_case convention (not sanaei's
tg* prefix) per project maintainer's request.
== Data layer ==
- ProxyUser: add TelegramID (indexed) + TelegramName fields for linking
proxy users to their Telegram accounts (self-service queries).
- SafeUser + ToSafeUser: expose both new fields.
- user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods.
- user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram
(registered before /:id to avoid path capture).
- UpdateInput/CreateInput: accept TelegramID + TelegramName.
== Settings expansion (8 new fields, snake_case) ==
- schedule: cron expr or @daily/@every 6h for periodic reports (default @daily)
- attach_backup: include DB backup zip in periodic report
- language: bot message language zh/en (default zh)
- enabled_events: comma-sep event list (default 'login,cpu,crash')
Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic
- expiry_warn_days: remind N days before expiry (0=off)
- traffic_warn_gb: remind when remaining traffic < N GB (0=off)
- proxy_url: socks5:// or http:// proxy for Telegram API
- api_server: custom Bot API server (empty=official)
- EventEnabled(name) helper for per-event gating.
== Client enhancements ==
- Proxy support: http(s):// via http.Transport.Proxy; socks5:// via
golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback.
- Custom API server (apiBase() replaces hardcoded URL).
- SendDocument: multipart sendDocument for backup file attachment.
- GetMe + SetMyCommands: for bot-info + set-my-commands endpoints.
- sendWithKeyboard: sendMessage with reply_markup (inline keyboards).
- answerCallbackQuery: clear callback loading spinner.
== Bot commands + inline menus ==
- /id: reply with sender's Telegram numeric ID.
- /usage: admin → search users; bound user → self-query traffic/expiry/sub URL.
- /start + /help: send inline keyboard menu (admin menu for admin chats,
user menu for bound users, plain text for unbound).
- Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/
backup/restart) in 4 rows.
- User menu: my_usage + my_sub buttons.
- callback_query handling: answerCallbackQuery + dispatch on callback_data.
- Access control: admin chats always pass; non-admin chats pass only when
FromID matches a ProxyUser.TelegramID.
- Bot struct: added userSvc field for GetByTelegramID lookups.
- NewBot signature: NewBot(db, mihomoSvc, userSvc).
== Cron scheduler (new telegram/scheduler.go) ==
- Periodic report goroutine driven by Settings.Schedule.
- Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron.
- Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted
counts.
- Optional backup: AttachBackup → system.WriteZip → SendDocument.
- Settings reload on every tick (no restart needed for schedule changes).
- NotifyEvent(event, details): generic event emitter for one-shot alerts.
== Events layer ==
- login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure).
Failure path added to auth/api.go Login handler. Both gated by
EventEnabled('login') — admins can mute success spam yet keep failure alerts.
- memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as
shared 'resource warn %' threshold. 1-hour cooldown dedup.
- crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash.
Fires on non-zero exit while desired==true (unexpected crash, not admin stop).
Wired in app/container.go.
- Dual thresholds: expiry (hours + days), traffic (percent + GB) with
separate dedup keys so neither suppresses the other.
== API endpoints ==
- POST /telegram/set-my-commands: registers 12-command menu with Telegram.
- GET /telegram/bot-info: returns bot username/first_name/id.
== Frontend ==
- telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands
+ fetchTelegramBotInfo API functions.
- Settings.tsx: 8 new form controls (schedule Input, language Select,
enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb
InputNumber, attach_backup Switch, proxy_url Input, api_server Input).
Added 'Set bot commands' button calling setTelegramCommands.
- i18n: 11 new keys (zh + en) for the new settings labels.
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : all 15 packages PASS
- npm run build (tsc + vite) : PASS, 3241 modules
- gofmt : clean
feat(telegram): full bot enhancement with inline menus, cron reports, events
Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/
Field naming follows existing 3m-ui snake_case convention (not sanaei's
tg* prefix) per project maintainer's request.
== Data layer ==
- ProxyUser: add TelegramID (indexed) + TelegramName fields for linking
proxy users to their Telegram accounts (self-service queries).
- SafeUser + ToSafeUser: expose both new fields.
- user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods.
- user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram
(registered before /:id to avoid path capture).
- UpdateInput/CreateInput: accept TelegramID + TelegramName.
== Settings expansion (8 new fields, snake_case) ==
- schedule: cron expr or @daily/@every 6h for periodic reports (default @daily)
- attach_backup: include DB backup zip in periodic report
- language: bot message language zh/en (default zh)
- enabled_events: comma-sep event list (default 'login,cpu,crash')
Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic
- expiry_warn_days: remind N days before expiry (0=off)
- traffic_warn_gb: remind when remaining traffic < N GB (0=off)
- proxy_url: socks5:// or http:// proxy for Telegram API
- api_server: custom Bot API server (empty=official)
- EventEnabled(name) helper for per-event gating.
== Client enhancements ==
- Proxy support: http(s):// via http.Transport.Proxy; socks5:// via
golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback.
- Custom API server (apiBase() replaces hardcoded URL).
- SendDocument: multipart sendDocument for backup file attachment.
- GetMe + SetMyCommands: for bot-info + set-my-commands endpoints.
- sendWithKeyboard: sendMessage with reply_markup (inline keyboards).
- answerCallbackQuery: clear callback loading spinner.
== Bot commands + inline menus ==
- /id: reply with sender's Telegram numeric ID.
- /usage: admin → search users; bound user → self-query traffic/expiry/sub URL.
- /start + /help: send inline keyboard menu (admin menu for admin chats,
user menu for bound users, plain text for unbound).
- Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/
backup/restart) in 4 rows.
- User menu: my_usage + my_sub buttons.
- callback_query handling: answerCallbackQuery + dispatch on callback_data.
- Access control: admin chats always pass; non-admin chats pass only when
FromID matches a ProxyUser.TelegramID.
- Bot struct: added userSvc field for GetByTelegramID lookups.
- NewBot signature: NewBot(db, mihomoSvc, userSvc).
== Cron scheduler (new telegram/scheduler.go) ==
- Periodic report goroutine driven by Settings.Schedule.
- Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron.
- Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted
counts.
- Optional backup: AttachBackup → system.WriteZip → SendDocument.
- Settings reload on every tick (no restart needed for schedule changes).
- NotifyEvent(event, details): generic event emitter for one-shot alerts.
== Events layer ==
- login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure).
Failure path added to auth/api.go Login handler. Both gated by
EventEnabled('login') — admins can mute success spam yet keep failure alerts.
- memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as
shared 'resource warn %' threshold. 1-hour cooldown dedup.
- crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash.
Fires on non-zero exit while desired==true (unexpected crash, not admin stop).
Wired in app/container.go.
- Dual thresholds: expiry (hours + days), traffic (percent + GB) with
separate dedup keys so neither suppresses the other.
== API endpoints ==
- POST /telegram/set-my-commands: registers 12-command menu with Telegram.
- GET /telegram/bot-info: returns bot username/first_name/id.
== Frontend ==
- telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands
+ fetchTelegramBotInfo API functions.
- Settings.tsx: 8 new form controls (schedule Input, language Select,
enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb
InputNumber, attach_backup Switch, proxy_url Input, api_server Input).
Added 'Set bot commands' button calling setTelegramCommands.
- i18n: 11 new keys (zh + en) for the new settings labels.
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : all 15 packages PASS
- npm run build (tsc + vite) : PASS, 3241 modules
- gofmt : clean
feat(telegram): full bot enhancement with inline menus, cron reports, events
Reference: https://docs.sanaei.dev/zh/docs/operations/telegram-bot/
Field naming follows existing 3m-ui snake_case convention (not sanaei's
tg* prefix) per project maintainer's request.
== Data layer ==
- ProxyUser: add TelegramID (indexed) + TelegramName fields for linking
proxy users to their Telegram accounts (self-service queries).
- SafeUser + ToSafeUser: expose both new fields.
- user.Service: BindTelegram / UnbindTelegram / GetByTelegramID methods.
- user API: GET /by-telegram/:tgid, PUT /:id/telegram, DELETE /:id/telegram
(registered before /:id to avoid path capture).
- UpdateInput/CreateInput: accept TelegramID + TelegramName.
== Settings expansion (8 new fields, snake_case) ==
- schedule: cron expr or @daily/@every 6h for periodic reports (default @daily)
- attach_backup: include DB backup zip in periodic report
- language: bot message language zh/en (default zh)
- enabled_events: comma-sep event list (default 'login,cpu,crash')
Supports: login,cpu,memory,crash,node_down,node_up,block,unblock,expiry,traffic
- expiry_warn_days: remind N days before expiry (0=off)
- traffic_warn_gb: remind when remaining traffic < N GB (0=off)
- proxy_url: socks5:// or http:// proxy for Telegram API
- api_server: custom Bot API server (empty=official)
- EventEnabled(name) helper for per-event gating.
== Client enhancements ==
- Proxy support: http(s):// via http.Transport.Proxy; socks5:// via
golang.org/x/net/proxy SOCKS5 dialer. Parse failure → direct fallback.
- Custom API server (apiBase() replaces hardcoded URL).
- SendDocument: multipart sendDocument for backup file attachment.
- GetMe + SetMyCommands: for bot-info + set-my-commands endpoints.
- sendWithKeyboard: sendMessage with reply_markup (inline keyboards).
- answerCallbackQuery: clear callback loading spinner.
== Bot commands + inline menus ==
- /id: reply with sender's Telegram numeric ID.
- /usage: admin → search users; bound user → self-query traffic/expiry/sub URL.
- /start + /help: send inline keyboard menu (admin menu for admin chats,
user menu for bound users, plain text for unbound).
- Admin menu: 8 buttons (status/users/traffic/online/listeners/deldepleted/
backup/restart) in 4 rows.
- User menu: my_usage + my_sub buttons.
- callback_query handling: answerCallbackQuery + dispatch on callback_data.
- Access control: admin chats always pass; non-admin chats pass only when
FromID matches a ProxyUser.TelegramID.
- Bot struct: added userSvc field for GetByTelegramID lookups.
- NewBot signature: NewBot(db, mihomoSvc, userSvc).
== Cron scheduler (new telegram/scheduler.go) ==
- Periodic report goroutine driven by Settings.Schedule.
- Supports @hourly/@daily/@weekly/@monthly/@every <dur>/5-field cron.
- Report: host, version, uptime, CPU/mem/disk, user stats, expiring+depleted
counts.
- Optional backup: AttachBackup → system.WriteZip → SendDocument.
- Settings reload on every tick (no restart needed for schedule changes).
- NotifyEvent(event, details): generic event emitter for one-shot alerts.
== Events layer ==
- login.attempt: NotifyLogin (success) + NotifyLoginFailed (failure).
Failure path added to auth/api.go Login handler. Both gated by
EventEnabled('login') — admins can mute success spam yet keep failure alerts.
- memory.high: emitMemoryWarning via gopsutil/v4/mem. Reuses CPUWarnPct as
shared 'resource warn %' threshold. 1-hour cooldown dedup.
- crash: mihomo ProcessManager.SetCrashHandler → telegram.NotifyCrash.
Fires on non-zero exit while desired==true (unexpected crash, not admin stop).
Wired in app/container.go.
- Dual thresholds: expiry (hours + days), traffic (percent + GB) with
separate dedup keys so neither suppresses the other.
== API endpoints ==
- POST /telegram/set-my-commands: registers 12-command menu with Telegram.
- GET /telegram/bot-info: returns bot username/first_name/id.
== Frontend ==
- telegram.ts: 8 new fields in TelegramSettings interface + setTelegramCommands
+ fetchTelegramBotInfo API functions.
- Settings.tsx: 8 new form controls (schedule Input, language Select,
enabled_events multi-Select with 10 options, expiry_warn_days + traffic_warn_gb
InputNumber, attach_backup Switch, proxy_url Input, api_server Input).
Added 'Set bot commands' button calling setTelegramCommands.
- i18n: 11 new keys (zh + en) for the new settings labels.
== Verification ==
- go build ./... : PASS
- go vet ./... : PASS
- go test ./... : all 15 packages PASS
- npm run build (tsc + vite) : PASS, 3241 modules
- gofmt : clean
2026-08-29 12:19:46 +00:00
..