|
|
@@ -65,7 +65,7 @@ Two key ideas that explain most of the complexity:
|
|
|
- Scheduler: **robfig/cron/v3** (seconds-precision) for all background jobs.
|
|
|
- Xray: **xtls/xray-core** vendored as a library; the panel talks to the running core over
|
|
|
its **gRPC API** and also shells out to manage the process.
|
|
|
-- Telegram bot: **mymmrac/telego**. i18n: **nicksnyder/go-i18n**.
|
|
|
+- Bots: Telegram bot (**mymmrac/telego**), Discord bot (Discord REST API v10 + **gorilla/websocket** Gateway v10). i18n: **nicksnyder/go-i18n**.
|
|
|
- Misc: gorilla/websocket, gopsutil (system stats), go-qrcode, gotp (2FA TOTP).
|
|
|
|
|
|
**Frontend (`frontend/`):**
|
|
|
@@ -217,6 +217,7 @@ node heartbeat every 5s, periodic traffic resets (hourly/daily/weekly/monthly).
|
|
|
│ │ │ │ ├── user.go # admin user auth (bcrypt)
|
|
|
│ │ │ │ ├── api_token.go # API token CRUD (SHA-256 hashed)
|
|
|
│ │ │ │ └── websocket.go # WS hub / push service
|
|
|
+│ │ │ ├── discord/ # Discord bot client, Gateway v10, and subscriber
|
|
|
│ │ │ └── tgbot/ # Telegram bot command handlers
|
|
|
│ │ ├── runtime/ # ⭐⭐ The Local/Remote node abstraction (see §5.2)
|
|
|
│ │ │ ├── runtime.go # the Runtime interface (the contract)
|
|
|
@@ -372,27 +373,28 @@ Periodic resets: `job/periodic_traffic_reset_job.go` (keyed off `Inbound.Traffic
|
|
|
|
|
|
All registered in `web.go` → `startTask()`. Each is a struct with a `Run()` method in `internal/web/job/`:
|
|
|
|
|
|
-| Schedule | Job | Purpose / condition |
|
|
|
-| ------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------- |
|
|
|
-| `@every 1s` | `check_xray_running_job` | Restart Xray if it died (2 consecutive down checks) |
|
|
|
-| `@every 30s` | (inline func in `startTask`) | Debounced Xray restart — consumes the "need restart" flag (§5.1) |
|
|
|
-| `@every 5s` | `xray_traffic_job` | Pull traffic stats from Xray (5s start delay) |
|
|
|
-| `@every 5s` | `node_heartbeat_job` | Probe child nodes (online/offline) |
|
|
|
-| `@every 5s` | `node_traffic_sync_job` | Pull + merge node traffic; push reconciliation |
|
|
|
-| `@every 10s` | `check_client_ip_job` | Enforce per-client IP limits |
|
|
|
-| `@every 10s` | `mtproto_job` | Reconcile `mtg` sidecars against enabled MTProto inbounds |
|
|
|
-| `@every 10s` | `amneziawg_job` | Reconcile embedded AmneziaWG interfaces against enabled local inbounds |
|
|
|
-| `@every 5m` | `outbound_subscription_job` | Refresh outbound provider configs |
|
|
|
-| `@every 10m` | `clear_logs_job` (`PruneXrayLogsJob`) | Truncate Xray access/error logs once either exceeds 64 MiB |
|
|
|
-| `@hourly` | `warp_ip_job`, `periodic_traffic_reset_job("hourly")` | WARP IP rotation; traffic resets |
|
|
|
-| `@daily` | `clear_logs_job`, `periodic_traffic_reset_job("daily")`, `periodic_traffic_reset_job("monthly")` | IP-limit and Xray access/error log cleanup; daily resets and due monthly resets |
|
|
|
-| `@weekly` | `periodic_traffic_reset_job("weekly")` | Weekly traffic resets |
|
|
|
-| default `@every 1m` | `ldap_sync_job` | Only if LDAP enabled; schedule configurable |
|
|
|
-| default `@daily` | `stats_notify_job` | Only if TG bot enabled; schedule configurable |
|
|
|
-| `@every 2m` | `check_hash_storage` | Only if TG bot enabled; expires bot callback hashes |
|
|
|
-| `@every 1m` | `check_cpu_usage` | Only if a CPU alarm is configured (TG or email); publishes `cpu.high` |
|
|
|
-| `@every 1m` | `check_memory_usage` | Only if a memory alarm is configured; publishes `memory.high` |
|
|
|
-| configurable | `free_os_memory` | Only if `sys.MemoryReleaseIntervalMinutes() > 0`; returns heap to OS |
|
|
|
+| Schedule | Job | Purpose / condition |
|
|
|
+| ------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------- |
|
|
|
+| `@every 1s` | `check_xray_running_job` | Restart Xray if it died (2 consecutive down checks) |
|
|
|
+| `@every 30s` | (inline func in `startTask`) | Debounced Xray restart — consumes the "need restart" flag (§5.1) |
|
|
|
+| `@every 5s` | `xray_traffic_job` | Pull traffic stats from Xray (5s start delay) |
|
|
|
+| `@every 5s` | `node_heartbeat_job` | Probe child nodes (online/offline) |
|
|
|
+| `@every 5s` | `node_traffic_sync_job` | Pull + merge node traffic; push reconciliation |
|
|
|
+| `@every 10s` | `check_client_ip_job` | Enforce per-client IP limits |
|
|
|
+| `@every 10s` | `mtproto_job` | Reconcile `mtg` sidecars against enabled MTProto inbounds |
|
|
|
+| `@every 10s` | `amneziawg_job` | Reconcile embedded AmneziaWG interfaces against enabled local inbounds |
|
|
|
+| `@every 5m` | `outbound_subscription_job` | Refresh outbound provider configs |
|
|
|
+| `@every 10m` | `clear_logs_job` (`PruneXrayLogsJob`) | Truncate Xray access/error logs once either exceeds 64 MiB |
|
|
|
+| `@hourly` | `warp_ip_job`, `periodic_traffic_reset_job("hourly")` | WARP IP rotation; traffic resets |
|
|
|
+| `@daily` | `clear_logs_job`, `periodic_traffic_reset_job("daily")`, `periodic_traffic_reset_job("monthly")` | IP-limit and Xray access/error log cleanup; daily resets and due monthly resets |
|
|
|
+| `@weekly` | `periodic_traffic_reset_job("weekly")` | Weekly traffic resets |
|
|
|
+| default `@every 1m` | `ldap_sync_job` | Only if LDAP enabled; schedule configurable |
|
|
|
+| default `@daily` | `stats_notify_job` | Only if TG bot enabled; schedule configurable |
|
|
|
+| default `@daily` | `discord_notify_job` | Only if Discord bot enabled; schedule configurable |
|
|
|
+| `@every 2m` | `check_hash_storage` | Only if TG bot enabled; expires bot callback hashes |
|
|
|
+| `@every 1m` | `check_cpu_usage` | Only if a CPU alarm is configured (TG, Discord, or email); publishes `cpu.high` |
|
|
|
+| `@every 1m` | `check_memory_usage` | Only if a memory alarm is configured (TG, Discord, or email); publishes `memory.high` |
|
|
|
+| configurable | `free_os_memory` | Only if `sys.MemoryReleaseIntervalMinutes() > 0`; returns heap to OS |
|
|
|
|
|
|
To change _when_ something runs, edit `startTask()`. To change _what_ it does, edit the job file.
|
|
|
|
|
|
@@ -433,7 +435,7 @@ also has protocol schemas under `frontend/src/schemas/protocols/` and `frontend/
|
|
|
`xray.crash`, `node.down|up`, `cpu.high`, `memory.high`, `login.attempt`, with structured
|
|
|
payloads (OutboundHealthData, NodeHealthData, LoginEventData, SystemMetricData). Producers
|
|
|
include the CPU/memory jobs, node heartbeat, and login handling; consumers include the
|
|
|
-Telegram bot and the email notifier (`service/email/`). Use it for cross-cutting
|
|
|
+Telegram bot, the Discord bot (`service/discord/`), and the email notifier (`service/email/`). Use it for cross-cutting
|
|
|
notifications instead of importing notification services into producers.
|
|
|
|
|
|
### 5.8 Tunnel health monitor
|
|
|
@@ -504,6 +506,7 @@ for AutoMigrate in `internal/database/db.go`.
|
|
|
| **Geo category browser** empty / won't open | `xray/geodata/` (`Store`, `reader.go`), `service/geodata.go` | `controller/xray_setting.go` (`/panel/api/xray/geodata/*`), asset dir = `config.GetBinFolderPath()` |
|
|
|
| **`geosite:`/`geoip:` token** reported unknown in a routing rule | `xray/geodata/token.go`, `service/geodata.go` (`Validate`) | `frontend/src/lib/xray/geoTokens.ts`, `frontend/src/components/geodata/` |
|
|
|
| **Telegram bot** commands | `service/tgbot/` | `job/stats_notify_job.go` |
|
|
|
+| **Discord bot** commands & reports | `service/discord/` | `job/discord_notify_job.go` |
|
|
|
| **Email notifications** | `service/email/` | `internal/eventbus/` (consumers) |
|
|
|
| **CPU / memory alerts** not firing | `job/check_cpu_usage.go`, `job/check_memory_usage.go` | `internal/eventbus/`, notifier settings in `service/setting.go` |
|
|
|
| Xray auto-restart on **dead tunnel** | `internal/tunnelmonitor/` | `XUI_TUNNEL_HEALTH_*` in `internal/config/` |
|
|
|
@@ -539,7 +542,7 @@ for AutoMigrate in `internal/database/db.go`.
|
|
|
8. **Two servers, two concerns.** Admin features go in `internal/web`; anything an _end user_
|
|
|
fetches goes in `internal/sub`. Don't blur them.
|
|
|
9. **Cross-cutting notifications go through `internal/eventbus/`** — publish an event instead
|
|
|
- of importing the Telegram/email services into producers.
|
|
|
+ of importing the Telegram/Discord/email services into producers.
|
|
|
|
|
|
---
|
|
|
|