diff --git a/web/service/tgbot.go b/web/service/tgbot.go index 3d737c70..179c082f 100644 --- a/web/service/tgbot.go +++ b/web/service/tgbot.go @@ -1398,6 +1398,25 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool return } + t.addClient(callbackQuery.Message.GetChat().ID, message_text, messageId) + t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation")) + case "add_client_set_flow": + if dataArray[1] == "none" { + client_Flow = "" + } else { + client_Flow = dataArray[1] + } + messageId := callbackQuery.Message.GetMessageID() + inbound, err := t.inboundService.GetInbound(receiver_inbound_ID) + if err != nil { + t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error()) + return + } + message_text, err := t.BuildInboundClientDataMessage(inbound.Remark, inbound.Protocol) + if err != nil { + t.sendCallbackAnswerTgBot(callbackQuery.ID, err.Error()) + return + } t.addClient(callbackQuery.Message.GetChat().ID, message_text, messageId) t.sendCallbackAnswerTgBot(callbackQuery.ID, t.I18nBot("tgbot.answers.successfulOperation")) case "add_client_ip_limit_in": @@ -1865,6 +1884,22 @@ func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool ), ) t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard) + case "add_client_ch_default_flow": + inlineKeyboard := tu.InlineKeyboard( + tu.InlineKeyboardRow( + tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.cancel")).WithCallbackData(t.encodeQuery("add_client_default_traffic_exp")), + ), + tu.InlineKeyboardRow( + tu.InlineKeyboardButton("None").WithCallbackData(t.encodeQuery("add_client_set_flow none")), + ), + tu.InlineKeyboardRow( + tu.InlineKeyboardButton("xtls-rprx-vision").WithCallbackData(t.encodeQuery("add_client_set_flow xtls-rprx-vision")), + ), + tu.InlineKeyboardRow( + tu.InlineKeyboardButton("xtls-rprx-vision-udp443").WithCallbackData(t.encodeQuery("add_client_set_flow xtls-rprx-vision-udp443")), + ), + ) + t.editMessageCallbackTgBot(chatId, callbackQuery.Message.GetMessageID(), inlineKeyboard) case "add_client_ch_default_ip_limit": inlineKeyboard := tu.InlineKeyboard( tu.InlineKeyboardRow( @@ -3345,6 +3380,25 @@ func (t *Tgbot) getCommonClientButtons() [][]telego.InlineKeyboardButton { } } +// inboundCanEnableTlsFlow mirrors Inbound.canEnableTlsFlow() from the frontend +// model: xtls-rprx-vision is only valid on VLESS-over-TCP with TLS or Reality. +func inboundCanEnableTlsFlow(ib *model.Inbound) bool { + if ib == nil || ib.Protocol != model.VLESS { + return false + } + var stream struct { + Network string `json:"network"` + Security string `json:"security"` + } + if err := json.Unmarshal([]byte(ib.StreamSettings), &stream); err != nil { + return false + } + if stream.Network != "tcp" { + return false + } + return stream.Security == "tls" || stream.Security == "reality" +} + // addClient handles the process of adding a new client to an inbound. func (t *Tgbot) addClient(chatId int64, msg string, messageID ...int) { inbound, err := t.inboundService.GetInbound(receiver_inbound_ID) @@ -3357,13 +3411,31 @@ func (t *Tgbot) addClient(chatId int64, msg string, messageID ...int) { var protocolRows [][]telego.InlineKeyboardButton switch protocol { - case model.VMESS, model.VLESS: + case model.VMESS: protocolRows = [][]telego.InlineKeyboardButton{ tu.InlineKeyboardRow( tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.change_email")).WithCallbackData("add_client_ch_default_email"), tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.change_id")).WithCallbackData("add_client_ch_default_id"), ), } + case model.VLESS: + protocolRows = [][]telego.InlineKeyboardButton{ + tu.InlineKeyboardRow( + tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.change_email")).WithCallbackData("add_client_ch_default_email"), + tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.change_id")).WithCallbackData("add_client_ch_default_id"), + ), + } + if inboundCanEnableTlsFlow(inbound) { + flowLabel := t.I18nBot("tgbot.buttons.change_flow") + if client_Flow != "" { + flowLabel = flowLabel + ": " + client_Flow + } + protocolRows = append(protocolRows, tu.InlineKeyboardRow( + tu.InlineKeyboardButton(flowLabel).WithCallbackData("add_client_ch_default_flow"), + )) + } else if client_Flow != "" { + client_Flow = "" + } case model.Trojan: protocolRows = [][]telego.InlineKeyboardButton{ tu.InlineKeyboardRow( diff --git a/web/translation/ar-EG.json b/web/translation/ar-EG.json index 663e81f3..ecf1c19d 100644 --- a/web/translation/ar-EG.json +++ b/web/translation/ar-EG.json @@ -952,6 +952,7 @@ "change_password": "⚙️🔑 كلمة السر", "change_email": "⚙️📧 البريد الإلكتروني", "change_comment": "⚙️💬 تعليق", + "change_flow": "⚙️🚦 التدفق", "ResetAllTraffics": "إعادة ضبط جميع الترافيك", "SortedTrafficUsageReport": "تقرير استخدام الترافيك المرتب" }, diff --git a/web/translation/en-US.json b/web/translation/en-US.json index 5cf1f7c0..eedd3454 100644 --- a/web/translation/en-US.json +++ b/web/translation/en-US.json @@ -952,6 +952,7 @@ "change_password": "⚙️🔑 Password", "change_email": "⚙️📧 Email", "change_comment": "⚙️💬 Comment", + "change_flow": "⚙️🚦 Flow", "ResetAllTraffics": "Reset All Traffics", "SortedTrafficUsageReport": "Sorted Traffic Usage Report" }, diff --git a/web/translation/es-ES.json b/web/translation/es-ES.json index 9b6a5e87..34af89ca 100644 --- a/web/translation/es-ES.json +++ b/web/translation/es-ES.json @@ -952,6 +952,7 @@ "change_password": "⚙️🔑 Contraseña", "change_email": "⚙️📧 Correo electrónico", "change_comment": "⚙️💬 Comentario", + "change_flow": "⚙️🚦 Flujo", "ResetAllTraffics": "Reiniciar todo el tráfico", "SortedTrafficUsageReport": "Informe de uso de tráfico ordenado" }, diff --git a/web/translation/fa-IR.json b/web/translation/fa-IR.json index 1295e400..fd948788 100644 --- a/web/translation/fa-IR.json +++ b/web/translation/fa-IR.json @@ -952,6 +952,7 @@ "change_password": "⚙️🔑 گذرواژه", "change_email": "⚙️📧 ایمیل", "change_comment": "⚙️💬 نظر", + "change_flow": "⚙️🚦 جریان", "ResetAllTraffics": "بازنشانی همه ترافیک‌ها", "SortedTrafficUsageReport": "گزارش استفاده از ترافیک مرتب‌شده" }, diff --git a/web/translation/id-ID.json b/web/translation/id-ID.json index 84769a3b..b8f44ac6 100644 --- a/web/translation/id-ID.json +++ b/web/translation/id-ID.json @@ -952,6 +952,7 @@ "change_password": "⚙️🔑 Kata Sandi", "change_email": "⚙️📧 Email", "change_comment": "⚙️💬 Komentar", + "change_flow": "⚙️🚦 Flow", "ResetAllTraffics": "Reset Semua Lalu Lintas", "SortedTrafficUsageReport": "Laporan Penggunaan Lalu Lintas yang Terurut" }, diff --git a/web/translation/ja-JP.json b/web/translation/ja-JP.json index 913ef5e5..630f5623 100644 --- a/web/translation/ja-JP.json +++ b/web/translation/ja-JP.json @@ -952,6 +952,7 @@ "change_password": "⚙️🔑 パスワード", "change_email": "⚙️📧 メールアドレス", "change_comment": "⚙️💬 コメント", + "change_flow": "⚙️🚦 フロー", "ResetAllTraffics": "すべてのトラフィックをリセット", "SortedTrafficUsageReport": "ソートされたトラフィック使用レポート" }, diff --git a/web/translation/pt-BR.json b/web/translation/pt-BR.json index 74cd6ba7..9f1b67d7 100644 --- a/web/translation/pt-BR.json +++ b/web/translation/pt-BR.json @@ -952,6 +952,7 @@ "change_password": "⚙️🔑 Senha", "change_email": "⚙️📧 E-mail", "change_comment": "⚙️💬 Comentário", + "change_flow": "⚙️🚦 Fluxo", "ResetAllTraffics": "Redefinir Todo o Tráfego", "SortedTrafficUsageReport": "Relatório de Uso de Tráfego Ordenado" }, diff --git a/web/translation/ru-RU.json b/web/translation/ru-RU.json index 3c16ede8..f7ddafa6 100644 --- a/web/translation/ru-RU.json +++ b/web/translation/ru-RU.json @@ -952,6 +952,7 @@ "change_password": "⚙️🔑 Пароль", "change_email": "⚙️📧 Email", "change_comment": "⚙️💬 Комментарий", + "change_flow": "⚙️🚦 Поток", "ResetAllTraffics": "Сбросить весь трафик", "SortedTrafficUsageReport": "Отсортированный отчет об использовании трафика" }, diff --git a/web/translation/tr-TR.json b/web/translation/tr-TR.json index 7895c1b6..a8dc2c3c 100644 --- a/web/translation/tr-TR.json +++ b/web/translation/tr-TR.json @@ -952,6 +952,7 @@ "change_password": "⚙️🔑 Şifre", "change_email": "⚙️📧 E-posta", "change_comment": "⚙️💬 Yorum", + "change_flow": "⚙️🚦 Akış", "ResetAllTraffics": "Tüm Trafikleri Sıfırla", "SortedTrafficUsageReport": "Sıralı Trafik Kullanım Raporu" }, diff --git a/web/translation/uk-UA.json b/web/translation/uk-UA.json index 6ed76eb0..417866d1 100644 --- a/web/translation/uk-UA.json +++ b/web/translation/uk-UA.json @@ -952,6 +952,7 @@ "change_password": "⚙️🔑 Пароль", "change_email": "⚙️📧 Електронна пошта", "change_comment": "⚙️💬 Коментар", + "change_flow": "⚙️🚦 Потік", "ResetAllTraffics": "Скинути весь трафік", "SortedTrafficUsageReport": "Відсортований звіт про використання трафіку" }, diff --git a/web/translation/vi-VN.json b/web/translation/vi-VN.json index 09e8d8b2..b292c058 100644 --- a/web/translation/vi-VN.json +++ b/web/translation/vi-VN.json @@ -952,6 +952,7 @@ "change_password": "⚙️🔑 Mật Khẩu", "change_email": "⚙️📧 Email", "change_comment": "⚙️💬 Bình Luận", + "change_flow": "⚙️🚦 Flow", "ResetAllTraffics": "Đặt lại tất cả lưu lượng", "SortedTrafficUsageReport": "Báo cáo sử dụng lưu lượng đã sắp xếp" }, diff --git a/web/translation/zh-CN.json b/web/translation/zh-CN.json index 0d65cb53..3f648cb2 100644 --- a/web/translation/zh-CN.json +++ b/web/translation/zh-CN.json @@ -952,6 +952,7 @@ "change_password": "⚙️🔑 密码", "change_email": "⚙️📧 邮箱", "change_comment": "⚙️💬 评论", + "change_flow": "⚙️🚦 流控", "ResetAllTraffics": "重置所有流量", "SortedTrafficUsageReport": "排序的流量使用报告" }, diff --git a/web/translation/zh-TW.json b/web/translation/zh-TW.json index 56a0c075..a28c0e0f 100644 --- a/web/translation/zh-TW.json +++ b/web/translation/zh-TW.json @@ -952,6 +952,7 @@ "change_password": "⚙️🔑 密碼", "change_email": "⚙️📧 電子郵件", "change_comment": "⚙️💬 評論", + "change_flow": "⚙️🚦 流控", "ResetAllTraffics": "重設所有流量", "SortedTrafficUsageReport": "排序過的流量使用報告" },