From 671aa0e277d65a46389cc0c4e12555a6b932fa76 Mon Sep 17 00:00:00 2001 From: sergeev_ms Date: Sat, 8 Mar 2025 17:27:06 +0300 Subject: [PATCH] Tgbot menu commands --- web/service/tgbot.go | 83 +++++++++++++++++----------- web/translation/translate.en_US.toml | 6 ++ web/translation/translate.es_ES.toml | 6 ++ web/translation/translate.fa_IR.toml | 6 ++ web/translation/translate.id_ID.toml | 6 ++ web/translation/translate.ja_JP.toml | 6 ++ web/translation/translate.pt_BR.toml | 6 ++ web/translation/translate.ru_RU.toml | 6 ++ web/translation/translate.tr_TR.toml | 6 ++ web/translation/translate.uk_UA.toml | 6 ++ web/translation/translate.vi_VN.toml | 6 ++ web/translation/translate.zh_CN.toml | 6 ++ web/translation/translate.zh_TW.toml | 6 ++ 13 files changed, 122 insertions(+), 33 deletions(-) diff --git a/web/service/tgbot.go b/web/service/tgbot.go index 7c6780d8..9841a1a2 100644 --- a/web/service/tgbot.go +++ b/web/service/tgbot.go @@ -20,7 +20,7 @@ import ( "x-ui/web/locale" "x-ui/xray" - "github.com/mymmrac/telego" + tg "github.com/mymmrac/telego" th "github.com/mymmrac/telego/telegohandler" tu "github.com/mymmrac/telego/telegoutil" "github.com/valyala/fasthttp" @@ -28,7 +28,7 @@ import ( ) var ( - bot *telego.Bot + bot *tg.Bot botHandler *th.BotHandler adminIds []int64 isRunning bool @@ -121,6 +121,11 @@ func (t *Tgbot) Start(i18nFS embed.FS) error { return err } + err = bot.SetMyCommands(t.getMenuCommands()) + if err != nil { + logger.Warning("Failed to set menu commands:", err) + } + // Start receiving Telegram bot messages if !isRunning { logger.Info("Telegram bot receiver started") @@ -131,40 +136,52 @@ func (t *Tgbot) Start(i18nFS embed.FS) error { return nil } -func (t *Tgbot) NewBot(token string, proxyUrl string, apiServerUrl string) (*telego.Bot, error) { +func (t *Tgbot) getMenuCommands() *tg.SetMyCommandsParams { + //commands, err := bot.GetMyCommands(nil) + commandsParams := tg.SetMyCommandsParams{} + commands := []tg.BotCommand{ + {"help", t.I18nBot("tgbot.menu.help")}, + {"status", t.I18nBot("tgbot.menu.status")}, + {"restart", t.I18nBot("tgbot.menu.restart")}, + {"id", t.I18nBot("tgbot.menu.tgChatId")}, + } + return commandsParams.WithCommands(commands...) +} + +func (t *Tgbot) NewBot(token string, proxyUrl string, apiServerUrl string) (*tg.Bot, error) { if proxyUrl == "" && apiServerUrl == "" { - return telego.NewBot(token) + return tg.NewBot(token) } if proxyUrl != "" { if !strings.HasPrefix(proxyUrl, "socks5://") { logger.Warning("Invalid socks5 URL, using default") - return telego.NewBot(token) + return tg.NewBot(token) } _, err := url.Parse(proxyUrl) if err != nil { logger.Warningf("Can't parse proxy URL, using default instance for tgbot: %v", err) - return telego.NewBot(token) + return tg.NewBot(token) } - return telego.NewBot(token, telego.WithFastHTTPClient(&fasthttp.Client{ + return tg.NewBot(token, tg.WithFastHTTPClient(&fasthttp.Client{ Dial: fasthttpproxy.FasthttpSocksDialer(proxyUrl), })) } if !strings.HasPrefix(apiServerUrl, "http") { logger.Warning("Invalid http(s) URL, using default") - return telego.NewBot(token) + return tg.NewBot(token) } _, err := url.Parse(apiServerUrl) if err != nil { logger.Warningf("Can't parse API server URL, using default instance for tgbot: %v", err) - return telego.NewBot(token) + return tg.NewBot(token) } - return telego.NewBot(token, telego.WithAPIServer(apiServerUrl)) + return tg.NewBot(token, tg.WithAPIServer(apiServerUrl)) } func (t *Tgbot) IsRunning() bool { @@ -212,7 +229,7 @@ func (t *Tgbot) decodeQuery(query string) (string, error) { } func (t *Tgbot) OnReceive() { - params := telego.GetUpdatesParams{ + params := tg.GetUpdatesParams{ Timeout: 10, } @@ -220,19 +237,19 @@ func (t *Tgbot) OnReceive() { botHandler, _ = th.NewBotHandler(bot, updates) - botHandler.HandleMessage(func(_ *telego.Bot, message telego.Message) { + botHandler.HandleMessage(func(_ *tg.Bot, message tg.Message) { t.SendMsgToTgbot(message.Chat.ID, t.I18nBot("tgbot.keyboardClosed"), tu.ReplyKeyboardRemove()) }, th.TextEqual(t.I18nBot("tgbot.buttons.closeKeyboard"))) - botHandler.HandleMessage(func(_ *telego.Bot, message telego.Message) { + botHandler.HandleMessage(func(_ *tg.Bot, message tg.Message) { t.answerCommand(&message, message.Chat.ID, checkAdmin(message.From.ID)) }, th.AnyCommand()) - botHandler.HandleCallbackQuery(func(_ *telego.Bot, query telego.CallbackQuery) { + botHandler.HandleCallbackQuery(func(_ *tg.Bot, query tg.CallbackQuery) { t.answerCallback(&query, checkAdmin(query.From.ID)) }, th.AnyCallbackQueryWithMessage()) - botHandler.HandleMessage(func(_ *telego.Bot, message telego.Message) { + botHandler.HandleMessage(func(_ *tg.Bot, message tg.Message) { if message.UsersShared != nil { if checkAdmin(message.From.ID) { for _, sharedUser := range message.UsersShared.Users { @@ -258,7 +275,7 @@ func (t *Tgbot) OnReceive() { botHandler.Start() } -func (t *Tgbot) answerCommand(message *telego.Message, chatId int64, isAdmin bool) { +func (t *Tgbot) answerCommand(message *tg.Message, chatId int64, isAdmin bool) { msg, onlyMessage := "", false command, _, commandArgs := tu.ParseCommand(message.Text) @@ -344,7 +361,7 @@ func (t *Tgbot) sendResponse(chatId int64, msg string, onlyMessage, isAdmin bool } } -func (t *Tgbot) answerCallback(callbackQuery *telego.CallbackQuery, isAdmin bool) { +func (t *Tgbot) answerCallback(callbackQuery *tg.CallbackQuery, isAdmin bool) { chatId := callbackQuery.Message.GetChat().ID if isAdmin { @@ -931,7 +948,7 @@ func (t *Tgbot) SendAnswer(chatId int64, msg string, isAdmin bool) { ), ) - var ReplyMarkup telego.ReplyMarkup + var ReplyMarkup tg.ReplyMarkup if isAdmin { ReplyMarkup = numericKeyboard } else { @@ -940,7 +957,7 @@ func (t *Tgbot) SendAnswer(chatId int64, msg string, isAdmin bool) { t.SendMsgToTgbot(chatId, msg, ReplyMarkup) } -func (t *Tgbot) SendMsgToTgbot(chatId int64, msg string, replyMarkup ...telego.ReplyMarkup) { +func (t *Tgbot) SendMsgToTgbot(chatId int64, msg string, replyMarkup ...tg.ReplyMarkup) { if !isRunning { return } @@ -973,7 +990,7 @@ func (t *Tgbot) SendMsgToTgbot(chatId int64, msg string, replyMarkup ...telego.R allMessages = append(allMessages, msg) } for n, message := range allMessages { - params := telego.SendMessageParams{ + params := tg.SendMessageParams{ ChatID: tu.ID(chatId), Text: message, ParseMode: "HTML", @@ -990,7 +1007,7 @@ func (t *Tgbot) SendMsgToTgbot(chatId int64, msg string, replyMarkup ...telego.R } } -func (t *Tgbot) SendMsgToTgbotAdmins(msg string, replyMarkup ...telego.ReplyMarkup) { +func (t *Tgbot) SendMsgToTgbotAdmins(msg string, replyMarkup ...tg.ReplyMarkup) { if len(replyMarkup) > 0 { for _, adminId := range adminIds { t.SendMsgToTgbot(adminId, msg, replyMarkup[0]) @@ -1167,9 +1184,9 @@ func (t *Tgbot) getInboundUsages() string { return info } -func (t *Tgbot) getInbounds() (*telego.InlineKeyboardMarkup, error) { +func (t *Tgbot) getInbounds() (*tg.InlineKeyboardMarkup, error) { inbounds, err := t.inboundService.GetAllInbounds() - var buttons []telego.InlineKeyboardButton + var buttons []tg.InlineKeyboardButton if err != nil { logger.Warning("GetAllInbounds run failed:", err) @@ -1199,14 +1216,14 @@ func (t *Tgbot) getInbounds() (*telego.InlineKeyboardMarkup, error) { return keyboard, nil } -func (t *Tgbot) getInboundClients(id int) (*telego.InlineKeyboardMarkup, error) { +func (t *Tgbot) getInboundClients(id int) (*tg.InlineKeyboardMarkup, error) { inbound, err := t.inboundService.GetInbound(id) if err != nil { logger.Warning("getIboundClients run failed:", err) return nil, errors.New(t.I18nBot("tgbot.answers.getInboundsFailed")) } clients, err := t.inboundService.GetClients(inbound) - var buttons []telego.InlineKeyboardButton + var buttons []tg.InlineKeyboardButton if err != nil { logger.Warning("GetInboundClients run failed:", err) @@ -1428,7 +1445,7 @@ func (t *Tgbot) clientTelegramUserInfo(chatId int64, email string, messageID ... t.editMessageTgBot(chatId, messageID[0], output, inlineKeyboard) } else { t.SendMsgToTgbot(chatId, output, inlineKeyboard) - requestUser := telego.KeyboardButtonRequestUsers{ + requestUser := tg.KeyboardButtonRequestUsers{ RequestID: int32(traffic.Id), UserIsBot: new(bool), } @@ -1601,7 +1618,7 @@ func (t *Tgbot) getExhausted(chatId int64) { if exhaustedCC > 0 { output += t.I18nBot("tgbot.messages.depleteSoon", "Deplete=="+t.I18nBot("tgbot.clients")) - var buttons []telego.InlineKeyboardButton + var buttons []tg.InlineKeyboardButton for _, traffic := range exhaustedClients { output += t.clientInfoMsg(&traffic, true, false, false, true, true, false) output += "\r\n" @@ -1714,7 +1731,7 @@ func (t *Tgbot) onlineClients(chatId int64, messageID ...int) { tu.InlineKeyboardButton(t.I18nBot("tgbot.buttons.refresh")).WithCallbackData(t.encodeQuery("onlines_refresh")))) if onlinesCount > 0 { - var buttons []telego.InlineKeyboardButton + var buttons []tg.InlineKeyboardButton for _, online := range onlines { buttons = append(buttons, tu.InlineKeyboardButton(online).WithCallbackData(t.encodeQuery("client_get_usage "+online))) } @@ -1825,7 +1842,7 @@ func (t *Tgbot) sendBanLogs(chatId int64, dt bool) { } func (t *Tgbot) sendCallbackAnswerTgBot(id string, message string) { - params := telego.AnswerCallbackQueryParams{ + params := tg.AnswerCallbackQueryParams{ CallbackQueryID: id, Text: message, } @@ -1834,8 +1851,8 @@ func (t *Tgbot) sendCallbackAnswerTgBot(id string, message string) { } } -func (t *Tgbot) editMessageCallbackTgBot(chatId int64, messageID int, inlineKeyboard *telego.InlineKeyboardMarkup) { - params := telego.EditMessageReplyMarkupParams{ +func (t *Tgbot) editMessageCallbackTgBot(chatId int64, messageID int, inlineKeyboard *tg.InlineKeyboardMarkup) { + params := tg.EditMessageReplyMarkupParams{ ChatID: tu.ID(chatId), MessageID: messageID, ReplyMarkup: inlineKeyboard, @@ -1845,8 +1862,8 @@ func (t *Tgbot) editMessageCallbackTgBot(chatId int64, messageID int, inlineKeyb } } -func (t *Tgbot) editMessageTgBot(chatId int64, messageID int, text string, inlineKeyboard ...*telego.InlineKeyboardMarkup) { - params := telego.EditMessageTextParams{ +func (t *Tgbot) editMessageTgBot(chatId int64, messageID int, text string, inlineKeyboard ...*tg.InlineKeyboardMarkup) { + params := tg.EditMessageTextParams{ ChatID: tu.ID(chatId), MessageID: messageID, Text: text, diff --git a/web/translation/translate.en_US.toml b/web/translation/translate.en_US.toml index 58c86ad1..182245b2 100644 --- a/web/translation/translate.en_US.toml +++ b/web/translation/translate.en_US.toml @@ -628,3 +628,9 @@ "askToAddUserId" = "Your configuration is not found!\r\nPlease ask your admin to use your Telegram ChatID in your configuration(s).\r\n\r\nYour ChatID: {{ .TgUserID }}" "chooseClient" = "Choose a Client for Inbound {{ .Inbound }}" "chooseInbound" = "Choose an Inbound" + +[tgbot.menu] +"restart" = "To restart Xray Core" +"tgChatId" = "Telegram Chat ID" +"status" = "Bot status" +"help" = "Get available actions" \ No newline at end of file diff --git a/web/translation/translate.es_ES.toml b/web/translation/translate.es_ES.toml index e1e04882..6eae1d73 100644 --- a/web/translation/translate.es_ES.toml +++ b/web/translation/translate.es_ES.toml @@ -628,3 +628,9 @@ "askToAddUserId" = "¡No se encuentra su configuración!\r\nPor favor, pídale a su administrador que use su ChatID de usuario de Telegram en su(s) configuración(es).\r\n\r\nSu ChatID de usuario: {{ .TgUserID }}" "chooseClient" = "Elige un Cliente para Inbound {{ .Inbound }}" "chooseInbound" = "Elige un Inbound" + +[tgbot.menu] +"restart" = "To restart Xray Core" +"tgChatId" = "Telegram Chat ID" +"status" = "Bot status" +"help" = "Get available actions" diff --git a/web/translation/translate.fa_IR.toml b/web/translation/translate.fa_IR.toml index 4098710f..01ba623f 100644 --- a/web/translation/translate.fa_IR.toml +++ b/web/translation/translate.fa_IR.toml @@ -628,3 +628,9 @@ "askToAddUserId" = "پیکربندی شما یافت نشد!\r\nلطفاً از مدیر خود بخواهید که شناسه کاربر تلگرام خود را در پیکربندی (های) خود استفاده کند.\r\n\r\nشناسه کاربری شما: {{ .TgUserID }}" "chooseClient" = "یک مشتری برای ورودی {{ .Inbound }} انتخاب کنید" "chooseInbound" = "یک ورودی انتخاب کنید" + +[tgbot.menu] +"restart" = "To restart Xray Core" +"tgChatId" = "Telegram Chat ID" +"status" = "Bot status" +"help" = "Get available actions" \ No newline at end of file diff --git a/web/translation/translate.id_ID.toml b/web/translation/translate.id_ID.toml index 6d80ae67..c6844d43 100644 --- a/web/translation/translate.id_ID.toml +++ b/web/translation/translate.id_ID.toml @@ -627,3 +627,9 @@ "askToAddUserId" = "Konfigurasi Anda tidak ditemukan!\r\nSilakan minta admin Anda untuk menggunakan ChatID Telegram Anda dalam konfigurasi Anda.\r\n\r\nChatID Pengguna Anda: {{ .TgUserID }}" "chooseClient" = "Pilih Klien untuk Inbound {{ .Inbound }}" "chooseInbound" = "Pilih Inbound" + +[tgbot.menu] +"restart" = "To restart Xray Core" +"tgChatId" = "Telegram Chat ID" +"status" = "Bot status" +"help" = "Get available actions" \ No newline at end of file diff --git a/web/translation/translate.ja_JP.toml b/web/translation/translate.ja_JP.toml index 85a13b0d..7a05fdb7 100644 --- a/web/translation/translate.ja_JP.toml +++ b/web/translation/translate.ja_JP.toml @@ -628,3 +628,9 @@ "askToAddUserId" = "設定が見つかりませんでした!\r\n管理者に問い合わせて、設定にTelegramユーザーのChatIDを使用してください。\r\n\r\nあなたのユーザーChatID:{{ .TgUserID }}" "chooseClient" = "インバウンド {{ .Inbound }} のクライアントを選択" "chooseInbound" = "インバウンドを選択" + +[tgbot.menu] +"restart" = "To restart Xray Core" +"tgChatId" = "Telegram Chat ID" +"status" = "Bot status" +"help" = "Get available actions" \ No newline at end of file diff --git a/web/translation/translate.pt_BR.toml b/web/translation/translate.pt_BR.toml index 1c333c39..8c2e9e78 100644 --- a/web/translation/translate.pt_BR.toml +++ b/web/translation/translate.pt_BR.toml @@ -628,3 +628,9 @@ "askToAddUserId" = "Sua configuração não foi encontrada!\r\nPeça ao seu administrador para usar seu Telegram ChatID em suas configurações.\r\n\r\nSeu ChatID: {{ .TgUserID }}" "chooseClient" = "Escolha um cliente para Inbound {{ .Inbound }}" "chooseInbound" = "Escolha um Inbound" + +[tgbot.menu] +"restart" = "To restart Xray Core" +"tgChatId" = "Telegram Chat ID" +"status" = "Bot status" +"help" = "Get available actions" \ No newline at end of file diff --git a/web/translation/translate.ru_RU.toml b/web/translation/translate.ru_RU.toml index bc7df7d8..a971d955 100644 --- a/web/translation/translate.ru_RU.toml +++ b/web/translation/translate.ru_RU.toml @@ -628,3 +628,9 @@ "askToAddUserId" = "Ваша конфигурация не найдена!\r\nПожалуйста, попросите администратора использовать ваш идентификатор пользователя Telegram в ваших конфигурациях.\r\n\r\nВаш идентификатор пользователя: {{ .TgUserID }}" "chooseClient" = "Выберите пользователя для подключения {{ .Inbound }}" "chooseInbound" = "Выберите подключение" + +[tgbot.menu] +"restart" = "Перезапуск Xray Core" +"tgChatId" = "ID чата Telegram" +"status" = "Статус бота" +"help" = "Доступные комманды бота" \ No newline at end of file diff --git a/web/translation/translate.tr_TR.toml b/web/translation/translate.tr_TR.toml index 3d14bcf3..7552b762 100644 --- a/web/translation/translate.tr_TR.toml +++ b/web/translation/translate.tr_TR.toml @@ -628,3 +628,9 @@ "askToAddUserId" = "Yapılandırmanız bulunamadı!\r\nLütfen yöneticinizden yapılandırmalarınıza Telegram ChatID'nizi eklemesini isteyin.\r\n\r\nKullanıcı ChatID'niz: {{ .TgUserID }}" "chooseClient" = "Gelen {{ .Inbound }} için bir Müşteri Seçin" "chooseInbound" = "Bir Gelen Seçin" + +[tgbot.menu] +"restart" = "To restart Xray Core" +"tgChatId" = "Telegram Chat ID" +"status" = "Bot status" +"help" = "Get available actions" \ No newline at end of file diff --git a/web/translation/translate.uk_UA.toml b/web/translation/translate.uk_UA.toml index 456924ed..617df974 100644 --- a/web/translation/translate.uk_UA.toml +++ b/web/translation/translate.uk_UA.toml @@ -628,3 +628,9 @@ "askToAddUserId" = "Вашу конфігурацію не знайдено!\r\nБудь ласка, попросіть свого адміністратора використовувати ваш ідентифікатор Telegram у вашій конфігурації.\r\n\r\nВаш ідентифікатор користувача: {{ .TgUserID }}" "chooseClient" = "Виберіть клієнта для Вхідного {{ .Inbound }}" "chooseInbound" = "Виберіть Вхідний" + +[tgbot.menu] +"restart" = "To restart Xray Core" +"tgChatId" = "Telegram Chat ID" +"status" = "Bot status" +"help" = "Get available actions" \ No newline at end of file diff --git a/web/translation/translate.vi_VN.toml b/web/translation/translate.vi_VN.toml index 5b064cbd..d1639d9d 100644 --- a/web/translation/translate.vi_VN.toml +++ b/web/translation/translate.vi_VN.toml @@ -628,3 +628,9 @@ "askToAddUserId" = "Cấu hình của bạn không được tìm thấy!\r\nVui lòng yêu cầu Quản trị viên sử dụng ID người dùng telegram của bạn trong cấu hình của bạn.\r\n\r\nID người dùng của bạn: {{ .TgUserID }}" "chooseClient" = "Chọn một Khách hàng cho Inbound {{ .Inbound }}" "chooseInbound" = "Chọn một Inbound" + +[tgbot.menu] +"restart" = "To restart Xray Core" +"tgChatId" = "Telegram Chat ID" +"status" = "Bot status" +"help" = "Get available actions" \ No newline at end of file diff --git a/web/translation/translate.zh_CN.toml b/web/translation/translate.zh_CN.toml index 36bc12ca..17f112ef 100644 --- a/web/translation/translate.zh_CN.toml +++ b/web/translation/translate.zh_CN.toml @@ -628,3 +628,9 @@ "askToAddUserId" = "未找到您的配置!\r\n请向管理员询问,在您的配置中使用您的 Telegram 用户 ChatID。\r\n\r\n您的用户 ChatID:{{ .TgUserID }}" "chooseClient" = "为入站 {{ .Inbound }} 选择一个客户" "chooseInbound" = "选择一个入站" + +[tgbot.menu] +"restart" = "To restart Xray Core" +"tgChatId" = "Telegram Chat ID" +"status" = "Bot status" +"help" = "Get available actions" \ No newline at end of file diff --git a/web/translation/translate.zh_TW.toml b/web/translation/translate.zh_TW.toml index a0ac4ef3..51da4ef0 100644 --- a/web/translation/translate.zh_TW.toml +++ b/web/translation/translate.zh_TW.toml @@ -628,3 +628,9 @@ "askToAddUserId" = "未找到您的配置!\r\n請向管理員詢問,在您的配置中使用您的 Telegram 使用者 ChatID。\r\n\r\n您的使用者 ChatID:{{ .TgUserID }}" "chooseClient" = "為入站 {{ .Inbound }} 選擇一個客戶" "chooseInbound" = "選擇一個入站" + +[tgbot.menu] +"restart" = "To restart Xray Core" +"tgChatId" = "Telegram Chat ID" +"status" = "Bot status" +"help" = "Get available actions" \ No newline at end of file