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" = "設定"