diff --git a/web/assets/js/model/setting.js b/web/assets/js/model/setting.js index 8e0105985b..4c15f42005 100644 --- a/web/assets/js/model/setting.js +++ b/web/assets/js/model/setting.js @@ -31,6 +31,8 @@ class AllSetting { this.subPath = "/sub/"; this.subJsonPath = "/json/"; this.subDomain = ""; + this.externalTrafficInformEnable = false; + this.externalTrafficInformURI = ""; this.subCertFile = ""; this.subKeyFile = ""; this.subUpdates = 12; diff --git a/web/entity/entity.go b/web/entity/entity.go index 1220634087..98d26faf8d 100644 --- a/web/entity/entity.go +++ b/web/entity/entity.go @@ -16,47 +16,49 @@ type Msg struct { } type AllSetting struct { - WebListen string `json:"webListen" form:"webListen"` - WebDomain string `json:"webDomain" form:"webDomain"` - WebPort int `json:"webPort" form:"webPort"` - WebCertFile string `json:"webCertFile" form:"webCertFile"` - WebKeyFile string `json:"webKeyFile" form:"webKeyFile"` - WebBasePath string `json:"webBasePath" form:"webBasePath"` - SessionMaxAge int `json:"sessionMaxAge" form:"sessionMaxAge"` - PageSize int `json:"pageSize" form:"pageSize"` - ExpireDiff int `json:"expireDiff" form:"expireDiff"` - TrafficDiff int `json:"trafficDiff" form:"trafficDiff"` - RemarkModel string `json:"remarkModel" form:"remarkModel"` - TgBotEnable bool `json:"tgBotEnable" form:"tgBotEnable"` - TgBotToken string `json:"tgBotToken" form:"tgBotToken"` - TgBotProxy string `json:"tgBotProxy" form:"tgBotProxy"` - TgBotAPIServer string `json:"tgBotAPIServer" form:"tgBotAPIServer"` - TgBotChatId string `json:"tgBotChatId" form:"tgBotChatId"` - TgRunTime string `json:"tgRunTime" form:"tgRunTime"` - TgBotBackup bool `json:"tgBotBackup" form:"tgBotBackup"` - TgBotLoginNotify bool `json:"tgBotLoginNotify" form:"tgBotLoginNotify"` - TgCpu int `json:"tgCpu" form:"tgCpu"` - TgLang string `json:"tgLang" form:"tgLang"` - TimeLocation string `json:"timeLocation" form:"timeLocation"` - SecretEnable bool `json:"secretEnable" form:"secretEnable"` - SubEnable bool `json:"subEnable" form:"subEnable"` - SubListen string `json:"subListen" form:"subListen"` - SubPort int `json:"subPort" form:"subPort"` - SubPath string `json:"subPath" form:"subPath"` - SubDomain string `json:"subDomain" form:"subDomain"` - SubCertFile string `json:"subCertFile" form:"subCertFile"` - SubKeyFile string `json:"subKeyFile" form:"subKeyFile"` - SubUpdates int `json:"subUpdates" form:"subUpdates"` - SubEncrypt bool `json:"subEncrypt" form:"subEncrypt"` - SubShowInfo bool `json:"subShowInfo" form:"subShowInfo"` - SubURI string `json:"subURI" form:"subURI"` - SubJsonPath string `json:"subJsonPath" form:"subJsonPath"` - SubJsonURI string `json:"subJsonURI" form:"subJsonURI"` - SubJsonFragment string `json:"subJsonFragment" form:"subJsonFragment"` - SubJsonNoises string `json:"subJsonNoises" form:"subJsonNoises"` - SubJsonMux string `json:"subJsonMux" form:"subJsonMux"` - SubJsonRules string `json:"subJsonRules" form:"subJsonRules"` - Datepicker string `json:"datepicker" form:"datepicker"` + WebListen string `json:"webListen" form:"webListen"` + WebDomain string `json:"webDomain" form:"webDomain"` + WebPort int `json:"webPort" form:"webPort"` + WebCertFile string `json:"webCertFile" form:"webCertFile"` + WebKeyFile string `json:"webKeyFile" form:"webKeyFile"` + WebBasePath string `json:"webBasePath" form:"webBasePath"` + SessionMaxAge int `json:"sessionMaxAge" form:"sessionMaxAge"` + PageSize int `json:"pageSize" form:"pageSize"` + ExpireDiff int `json:"expireDiff" form:"expireDiff"` + TrafficDiff int `json:"trafficDiff" form:"trafficDiff"` + RemarkModel string `json:"remarkModel" form:"remarkModel"` + TgBotEnable bool `json:"tgBotEnable" form:"tgBotEnable"` + TgBotToken string `json:"tgBotToken" form:"tgBotToken"` + TgBotProxy string `json:"tgBotProxy" form:"tgBotProxy"` + TgBotAPIServer string `json:"tgBotAPIServer" form:"tgBotAPIServer"` + TgBotChatId string `json:"tgBotChatId" form:"tgBotChatId"` + TgRunTime string `json:"tgRunTime" form:"tgRunTime"` + TgBotBackup bool `json:"tgBotBackup" form:"tgBotBackup"` + TgBotLoginNotify bool `json:"tgBotLoginNotify" form:"tgBotLoginNotify"` + TgCpu int `json:"tgCpu" form:"tgCpu"` + TgLang string `json:"tgLang" form:"tgLang"` + TimeLocation string `json:"timeLocation" form:"timeLocation"` + SecretEnable bool `json:"secretEnable" form:"secretEnable"` + SubEnable bool `json:"subEnable" form:"subEnable"` + SubListen string `json:"subListen" form:"subListen"` + SubPort int `json:"subPort" form:"subPort"` + SubPath string `json:"subPath" form:"subPath"` + SubDomain string `json:"subDomain" form:"subDomain"` + SubCertFile string `json:"subCertFile" form:"subCertFile"` + SubKeyFile string `json:"subKeyFile" form:"subKeyFile"` + SubUpdates int `json:"subUpdates" form:"subUpdates"` + ExternalTrafficInformEnable bool `json:"externalTrafficInformEnable" form:"externalTrafficInformEnable"` + ExternalTrafficInformURI string `json:"externalTrafficInformURI" form:"externalTrafficInformURI"` + SubEncrypt bool `json:"subEncrypt" form:"subEncrypt"` + SubShowInfo bool `json:"subShowInfo" form:"subShowInfo"` + SubURI string `json:"subURI" form:"subURI"` + SubJsonPath string `json:"subJsonPath" form:"subJsonPath"` + SubJsonURI string `json:"subJsonURI" form:"subJsonURI"` + SubJsonFragment string `json:"subJsonFragment" form:"subJsonFragment"` + SubJsonNoises string `json:"subJsonNoises" form:"subJsonNoises"` + SubJsonMux string `json:"subJsonMux" form:"subJsonMux"` + SubJsonRules string `json:"subJsonRules" form:"subJsonRules"` + Datepicker string `json:"datepicker" form:"datepicker"` } func (s *AllSetting) CheckValid() error { diff --git a/web/html/xui/settings.html b/web/html/xui/settings.html index 9eff8bec12..de6ed673ba 100644 --- a/web/html/xui/settings.html +++ b/web/html/xui/settings.html @@ -142,6 +142,8 @@ + + diff --git a/web/job/xray_traffic_job.go b/web/job/xray_traffic_job.go index dbbbb05911..12c6409204 100644 --- a/web/job/xray_traffic_job.go +++ b/web/job/xray_traffic_job.go @@ -1,11 +1,16 @@ package job import ( + "encoding/json" "x-ui/logger" "x-ui/web/service" + "x-ui/xray" + + "github.com/valyala/fasthttp" ) type XrayTrafficJob struct { + settingService service.SettingService xrayService service.XrayService inboundService service.InboundService outboundService service.OutboundService @@ -31,7 +36,36 @@ func (j *XrayTrafficJob) Run() { if err != nil { logger.Warning("add outbound traffic failed:", err) } + if ExternalTrafficInformEnable, err := j.settingService.GetExternalTrafficInformEnable(); ExternalTrafficInformEnable { + j.informTrafficToExternalAPI(traffics, clientTraffics) + } else if err != nil { + logger.Warning("get ExternalTrafficInformEnable failed:", err) + } if needRestart0 || needRestart1 { j.xrayService.SetToNeedRestart() } } + +func (j *XrayTrafficJob) informTrafficToExternalAPI(inboundTraffics []*xray.Traffic, clientTraffics []*xray.ClientTraffic) { + informURL, err := j.settingService.GetExternalTrafficInformURI() + if err != nil { + logger.Warning("get ExternalTrafficInformURI failed:", err) + return + } + requestBody, err := json.Marshal(map[string]interface{}{"clientTraffics": clientTraffics, "inboundTraffics": inboundTraffics}) + if err != nil { + logger.Warning("parse client/inbound traffic failed:", err) + return + } + request := fasthttp.AcquireRequest() + defer fasthttp.ReleaseRequest(request) + request.Header.SetMethod("POST") + request.Header.SetContentType("application/json; charset=UTF-8") + request.SetBody([]byte(requestBody)) + request.SetRequestURI(informURL) + response := fasthttp.AcquireResponse() + defer fasthttp.ReleaseResponse(response) + if err := fasthttp.Do(request, response); err != nil { + logger.Warning("POST ExternalTrafficInformURI failed:", err) + } +} diff --git a/web/service/setting.go b/web/service/setting.go index d238c33d80..4fe06517de 100644 --- a/web/service/setting.go +++ b/web/service/setting.go @@ -496,6 +496,22 @@ func (s *SettingService) SetWarp(data string) error { return s.setString("warp", data) } +func (s *SettingService) GetExternalTrafficInformEnable() (bool, error) { + return s.getBool("externalTrafficInformEnable") +} + +func (s *SettingService) SetExternalTrafficInformEnable(value bool) error { + return s.setBool("externalTrafficInformEnable", value) +} + +func (s *SettingService) GetExternalTrafficInformURI() (string, error) { + return s.getString("externalTrafficInformURI") +} + +func (s *SettingService) SetExternalTrafficInformURI(InformURI string) error { + return s.setString("externalTrafficInformURI", InformURI) +} + func (s *SettingService) GetIpLimitEnable() (bool, error) { accessLogPath, err := xray.GetAccessLogPath() if err != nil { diff --git a/web/translation/translate.en_US.toml b/web/translation/translate.en_US.toml index 638d619ec8..6ee1e780da 100644 --- a/web/translation/translate.en_US.toml +++ b/web/translation/translate.en_US.toml @@ -307,6 +307,10 @@ "subShowInfoDesc" = "The remaining traffic and date will be displayed in the client apps." "subURI" = "Reverse Proxy URI" "subURIDesc" = "The URI path of the subscription URL for use behind proxies." +"externalTrafficInformEnable" = "External Traffic Inform" +"externalTrafficInformEnableDesc" = "Inform external API on every traffic update." +"externalTrafficInformURI" = "External Traffic Inform URI" +"externalTrafficInformURIDesc" = "Traffic updates are sent to this URI." "fragment" = "Fragmentation" "fragmentDesc" = "Enable fragmentation for TLS hello packet." "fragmentSett" = "Fragmentation Settings" diff --git a/web/translation/translate.es_ES.toml b/web/translation/translate.es_ES.toml index 62ae984e78..806c076e61 100644 --- a/web/translation/translate.es_ES.toml +++ b/web/translation/translate.es_ES.toml @@ -306,6 +306,10 @@ "subShowInfo" = "Mostrar información de uso" "subShowInfoDesc" = "Mostrar tráfico restante y fecha después del nombre de configuración." "subURI" = "URI de proxy inverso" +"externalTrafficInformEnable" = "Informe de tráfico externo" +"externalTrafficInformEnableDesc" = "Informar a la API externa sobre cada actualización de tráfico." +"externalTrafficInformURI" = "URI de información de tráfico externo" +"externalTrafficInformURIDesc" = "Las actualizaciones de tráfico se envían a este URI." "subURIDesc" = "Cambiar el URI base de la URL de suscripción para usar detrás de los servidores proxy" "fragment" = "Fragmentación" "fragmentDesc" = "Habilitar la fragmentación para el paquete de saludo de TLS" diff --git a/web/translation/translate.fa_IR.toml b/web/translation/translate.fa_IR.toml index 6219996dc0..75833069dd 100644 --- a/web/translation/translate.fa_IR.toml +++ b/web/translation/translate.fa_IR.toml @@ -301,6 +301,10 @@ "subDomainDesc" = "آدرس دامنه برای سرویس سابسکریپشن. برای گوش دادن به تمام دامنه‌ها و آی‌پی‌ها خالی‌بگذارید‌" "subUpdates" = "فاصله بروزرسانی‌ سابسکریپشن" "subUpdatesDesc" = "(فاصله مابین بروزرسانی در برنامه‌های کاربری. (واحد: ساعت" +"externalTrafficInformEnable" = "اطلاع رسانی خارجی مصرف ترافیک" +"externalTrafficInformEnableDesc" = "مصرف ترافیک به سرویس خارجی ارسال می شود" +"externalTrafficInformURI" = "لینک اطلاع رسانی خارجی مصرف ترافیک" +"externalTrafficInformURIDesc" = "ترافیک های مصرفی به این لینک هم ارسال می شود" "subEncrypt" = "کدگذاری" "subEncryptDesc" = "کدگذاری خواهدشد Base64 محتوای برگشتی سرویس سابسکریپشن برپایه" "subShowInfo" = "نمایش اطلاعات مصرف" diff --git a/web/translation/translate.id_ID.toml b/web/translation/translate.id_ID.toml index 6eb6d9b5de..186c82ae33 100644 --- a/web/translation/translate.id_ID.toml +++ b/web/translation/translate.id_ID.toml @@ -306,7 +306,10 @@ "subShowInfo" = "Tampilkan Info Penggunaan" "subShowInfoDesc" = "Sisa traffic dan tanggal akan ditampilkan di aplikasi klien." "subURI" = "URI Proxy Terbalik" -"subURIDesc" = "URI path URL langganan untuk penggunaan di belakang proxy." +"externalTrafficInformEnable" = "Informasikan API eksternal pada setiap pembaruan lalu lintas." +"externalTrafficInformEnableDesc" = "Inform external API on every traffic update." +"externalTrafficInformURI" = "Lalu Lintas Eksternal Menginformasikan URI" +"externalTrafficInformURIDesc" = "Pembaruan lalu lintas dikirim ke URI ini." "fragment" = "Fragmentasi" "fragmentDesc" = "Aktifkan fragmentasi untuk paket hello TLS" "fragmentSett" = "Pengaturan Fragmentasi" diff --git a/web/translation/translate.ja_JP.toml b/web/translation/translate.ja_JP.toml index db024b3e65..f7c94f874f 100644 --- a/web/translation/translate.ja_JP.toml +++ b/web/translation/translate.ja_JP.toml @@ -307,6 +307,10 @@ "subShowInfoDesc" = "クライアントアプリで残りのトラフィックと日付情報を表示する" "subURI" = "リバースプロキシURI" "subURIDesc" = "プロキシ後ろのサブスクリプションURLのURIパスに使用する" +"externalTrafficInformEnable" = "外部トラフィック情報" +"externalTrafficInformEnableDesc" = "トラフィックの更新ごとに外部 API に通知します。" +"externalTrafficInformURI" = "外部トラフィック通知 URI" +"externalTrafficInformURIDesc" = "トラフィックの更新ごとに外部 API に通知します。" "fragment" = "フラグメント" "fragmentDesc" = "TLS helloパケットのフラグメントを有効にする" "fragmentSett" = "設定" diff --git a/web/translation/translate.pt_BR.toml b/web/translation/translate.pt_BR.toml index bc0c617c00..92af236c4b 100644 --- a/web/translation/translate.pt_BR.toml +++ b/web/translation/translate.pt_BR.toml @@ -307,6 +307,10 @@ "subShowInfoDesc" = "O tráfego restante e a data serão exibidos nos aplicativos de cliente." "subURI" = "URI de Proxy Reverso" "subURIDesc" = "O caminho URI da URL de assinatura para uso por trás de proxies." +"externalTrafficInformEnable" = "Informações de tráfego externo" +"externalTrafficInformEnableDesc" = "Informar a API externa sobre cada atualização de tráfego." +"externalTrafficInformURI" = "URI de informação de tráfego externo" +"externalTrafficInformURIDesc" = "As atualizações de tráfego são enviadas para este URI." "fragment" = "Fragmentação" "fragmentDesc" = "Ativa a fragmentação para o pacote TLS hello." "fragmentSett" = "Configurações de Fragmentação" diff --git a/web/translation/translate.ru_RU.toml b/web/translation/translate.ru_RU.toml index e0875226f6..71db65b7dc 100644 --- a/web/translation/translate.ru_RU.toml +++ b/web/translation/translate.ru_RU.toml @@ -307,6 +307,10 @@ "subShowInfoDesc" = "Показывать оставшиеся трафик и дату после имени конфигурации" "subURI" = "URI обратного прокси" "subURIDesc" = "Изменить базовый URI URL-адреса подписки для использования за прокси-серверами" +"externalTrafficInformEnable" = "Информация о внешнем трафике" +"externalTrafficInformEnableDesc" = "Информировать внешний API о каждом обновлении трафика" +"externalTrafficInformURI" = "URI информации о внешнем трафике" +"externalTrafficInformURIDesc" = "Обновления трафика отправляются на этот URI" "fragment" = "Фрагментация" "fragmentDesc" = "Включить фрагментацию для пакета приветствия TLS" "fragmentSett" = "Настройки фрагментации" diff --git a/web/translation/translate.tr_TR.toml b/web/translation/translate.tr_TR.toml index 662c87c3ac..6e8d3811fa 100644 --- a/web/translation/translate.tr_TR.toml +++ b/web/translation/translate.tr_TR.toml @@ -307,6 +307,10 @@ "subShowInfoDesc" = "Kalan trafik ve tarih müşteri uygulamalarında görüntülenir." "subURI" = "Ters Proxy URI" "subURIDesc" = "Proxy arkasında kullanılacak abonelik URL'sinin URI yolu." +"externalTrafficInformEnable" = "Harici Trafik Bilgisi" +"externalTrafficInformEnableDesc" = "Her trafik güncellemesinde harici API'yi bilgilendirin." +"externalTrafficInformURI" = "Harici Trafik Bilgisi URI'si" +"externalTrafficInformURIDesc" = "Trafik güncellemeleri bu URI'ye gönderildi." "fragment" = "Parçalama" "fragmentDesc" = "TLS merhaba paketinin parçalanmasını etkinleştir." "fragmentSett" = "Parçalama Ayarları" diff --git a/web/translation/translate.uk_UA.toml b/web/translation/translate.uk_UA.toml index 1619dda1b0..90ae54bf20 100644 --- a/web/translation/translate.uk_UA.toml +++ b/web/translation/translate.uk_UA.toml @@ -307,6 +307,10 @@ "subShowInfoDesc" = "Залишок трафіку та дата відображатимуться в клієнтських програмах." "subURI" = "URI зворотного проксі" "subURIDesc" = "URI до URL-адреси підписки для використання за проксі." +"externalTrafficInformEnable" = "Інформація про зовнішній трафік" +"externalTrafficInformEnableDesc" = "Інформувати зовнішній API про кожне оновлення трафіку." +"externalTrafficInformURI" = "Інформаційний URI зовнішнього трафіку" +"externalTrafficInformURIDesc" = "Оновлення трафіку надсилаються на цей URI." "fragment" = "Фрагментація" "fragmentDesc" = "Увімкнути фрагментацію для пакету привітання TLS" "fragmentSett" = "Параметри фрагментації" diff --git a/web/translation/translate.vi_VN.toml b/web/translation/translate.vi_VN.toml index 8f6edb32ad..561199dd04 100644 --- a/web/translation/translate.vi_VN.toml +++ b/web/translation/translate.vi_VN.toml @@ -307,6 +307,10 @@ "subShowInfoDesc" = "Hiển thị lưu lượng truy cập còn lại và ngày sau tên cấu hình" "subURI" = "URI proxy trung gian" "subURIDesc" = "Thay đổi URI cơ sở của URL gói đăng ký để sử dụng cho proxy trung gian" +"externalTrafficInformEnable" = "Thông báo giao thông bên ngoài" +"externalTrafficInformEnableDesc" = "Thông báo cho API bên ngoài về mọi cập nhật lưu lượng truy cập." +"externalTrafficInformURI" = "URI thông báo lưu lượng truy cập bên ngoài" +"externalTrafficInformURIDesc" = "Cập nhật lưu lượng truy cập được gửi tới URI này." "fragment" = "Sự phân mảnh" "fragmentDesc" = "Kích hoạt phân mảnh cho gói TLS hello" "fragmentSett" = "Cài đặt phân mảnh" diff --git a/web/translation/translate.zh_CN.toml b/web/translation/translate.zh_CN.toml index 843fee1bae..611776d58e 100644 --- a/web/translation/translate.zh_CN.toml +++ b/web/translation/translate.zh_CN.toml @@ -307,6 +307,10 @@ "subShowInfoDesc" = "客户端应用中将显示剩余流量和日期信息" "subURI" = "反向代理 URI" "subURIDesc" = "用于代理后面的订阅 URL 的 URI 路径" +"externalTrafficInformEnable" = "外部交通通知" +"externalTrafficInformEnableDesc" = "每次流量更新时通知外部 API" +"externalTrafficInformURI" = "外部流量通知 URI" +"externalTrafficInformURIDesc" = "流量更新将发送到此 URI" "fragment" = "分片" "fragmentDesc" = "启用 TLS hello 数据包分片" "fragmentSett" = "设置" diff --git a/web/translation/translate.zh_TW.toml b/web/translation/translate.zh_TW.toml index 3e4dda7ffb..34644589d5 100644 --- a/web/translation/translate.zh_TW.toml +++ b/web/translation/translate.zh_TW.toml @@ -307,6 +307,10 @@ "subShowInfoDesc" = "客戶端應用中將顯示剩餘流量和日期資訊" "subURI" = "反向代理 URI" "subURIDesc" = "用於代理後面的訂閱 URL 的 URI 路徑" +"externalTrafficInformEnable" = "外部交通通知" +"externalTrafficInformEnableDesc" = "每次流量更新時通知外部 API" +"externalTrafficInformURI" = "外部流量通知 URI" +"externalTrafficInformURIDesc" = "流量更新將會傳送到此 URI" "fragment" = "分片" "fragmentDesc" = "啟用 TLS hello 資料包分片" "fragmentSett" = "設定"