P9(5): restore upstream Telegram bot (settings, backup, notifications)
Per user decision 2026-10-21 (reverses the 2026-10-20 drop-Telegram call): port the upstream 3x-ui v3.7.0-generation Telegram bot wholesale instead of rewriting a minimal set, adapted to this fork. - new internal/web/service/tgbot package (telego): bot lifecycle, commands, reports, callback router, send helpers; token validation via telego; custom API server URL passes the fork's SSRF sanitizer (loopback/private bases fall back to the default endpoint, logged) - settings: full upstream key set (tgBotEnable/Token/Proxy/APIServer/ ChatId, tgRunTime, tgBotBackup, tgCpu/tgMemory, tgLang, tgEnabledEvents) with getters/setters; settings page gains a Telegram tab + sidebar entry; token shown masked, clearTgBotToken honored - wiring (web.go): stats-notify cron registered from tgRunTime when the bot is enabled; CheckHashStorage job; CPU/memory alarm jobs gated on tgEnabledEvents + thresholds; login notifications via event bus; POST /panel/api/setting/testTgBot and /panel/api/backuptotgbot - lite adaptation: StatsNotifyJob no longer gates on a local Xray core (this panel never runs one) so the periodic report and the scheduled DB backup (sendDocument) can actually fire - translations: upstream TG keys restored across all locales End-to-end smoke (real binary + fake Telegram API over HTTPS at a public-looking address, browser form wire format): bot starts on settings change (getMe), testTgBot delivers, panel restart re-arms the bot, tgRunTime='@every 1m' cron really fires sendDocument carrying the panel SQLite DB (magic verified) plus the report sendMessage, login notification delivered, dead-endpoint failure is logged not silent. 13/13 PASS — see P9-REPORT.md.
This commit is contained in:
@@ -88,7 +88,8 @@
|
||||
"unlimited": "نامحدود",
|
||||
"noExpiry": "بدون انقضا",
|
||||
"copyAllConfigs": "کپی همه کانفیگها",
|
||||
"copyAllConfigsCopied": "همه کانفیگها کپی شدند"
|
||||
"copyAllConfigsCopied": "همه کانفیگها کپی شدند",
|
||||
"individualLinks": "لینکهای تکی"
|
||||
},
|
||||
"menu": {
|
||||
"theme": "تم",
|
||||
@@ -1168,7 +1169,44 @@
|
||||
"httpMethodDesc": "متد استفادهشده برای درخواستهای probe.",
|
||||
"note": "موزانکنندههای leastPing/leastLoad همیشه burstObservatory دارند. این کلید پارامترهای probe آن را سفارشی میکند — آن را خاموش کنید تا از پیشفرضهای داخلی استفاده شود. تغییرات پس از راهاندازی مجدد پنل اعمال میشوند."
|
||||
}
|
||||
}
|
||||
},
|
||||
"TGBotSettings": "ربات تلگرام",
|
||||
"notifications": "اعلانها",
|
||||
"notifyTime": {
|
||||
"custom": "سفارشی (crontab)",
|
||||
"daily": "@daily — هر روز ساعت ۰۰:۰۰",
|
||||
"every": "@every — تکرار در یک بازه",
|
||||
"hourly": "@hourly — هر ساعت",
|
||||
"hours": "ساعت",
|
||||
"interval": "بازه زمانی",
|
||||
"minutes": "دقیقه",
|
||||
"monthly": "@monthly — هر ماه",
|
||||
"seconds": "ثانیه",
|
||||
"unit": "واحد",
|
||||
"weekly": "@weekly — هر هفته"
|
||||
},
|
||||
"telegramAPIServer": "سرور API تلگرام",
|
||||
"telegramAPIServerDesc": "API سرور تلگرام برای اتصال را تغییر میدهد. برای استفاده از سرور پیش فرض خالی بگذارید",
|
||||
"telegramBotEnable": "فعالسازی ربات تلگرام",
|
||||
"telegramBotEnableDesc": "ربات تلگرام را فعال میکند",
|
||||
"telegramBotLanguage": "زبان ربات تلگرام",
|
||||
"telegramChatId": "آیدی چت مدیر",
|
||||
"telegramChatIdDesc": "دریافت کنید ('/id'یا (دستور ({'@'}userinfobot) آیدی(های) چت تلگرام مدیر، از",
|
||||
"telegramNotifyTime": "زمان نوتیفیکیشن",
|
||||
"telegramNotifyTimeDesc": "هر چند وقت یکبار ربات تلگرام گزارش دورهای بفرستد. یک بازهٔ آماده انتخاب کنید یا گزینهٔ سفارشی را بزنید تا عبارت crontab وارد کنید.",
|
||||
"telegramToken": "توکن تلگرام",
|
||||
"telegramTokenConfigured": "پیکربندی شده؛ برای حفظ توکن فعلی خالی بگذارید.",
|
||||
"telegramTokenDesc": "دریافت کنید {'@'}botfather توکن را میتوانید از",
|
||||
"telegramTokenPlaceholder": "پیکربندی شده - برای جایگزینی، توکن جدید وارد کنید",
|
||||
"testTgBot": "ارسال پیام آزمایشی",
|
||||
"tgBotNotEnabled": "ربات تلگرام فعال نیست",
|
||||
"tgBotNotRunning": "ربات تلگرام در حال اجرا نیست",
|
||||
"tgEventBusNotify": "اعلانهای رویداد تلگرام",
|
||||
"tgEventBusNotifyDesc": "انتخاب کنید کدام رویدادها اعلان تلگرام را فعال میکنند",
|
||||
"tgNotifyBackup": "پشتیبانگیری از دیتابیس",
|
||||
"tgNotifyBackupDesc": "فایل پشتیباندیتابیس را بههمراه گزارش ارسال میکند",
|
||||
"tgTestFailed": "آزمایش تلگرام ناموفق بود",
|
||||
"tgTestSuccess": "پیام آزمایشی به تلگرام ارسال شد"
|
||||
},
|
||||
"xray": {
|
||||
"save": "ذخیره",
|
||||
@@ -1657,7 +1695,182 @@
|
||||
}
|
||||
},
|
||||
"tgbot": {
|
||||
"noIpRecord": "❗ رکورد آی پی وجود ندارد!"
|
||||
"noIpRecord": "❗ رکورد آی پی وجود ندارد!",
|
||||
"keyboardClosed": "❌ صفحه کلید بسته شد!",
|
||||
"noResult": "❗ نتیجه ای یافت نشد!",
|
||||
"noQuery": "❌ درخواست یافت نشد! لطفا دوباره تلاش کنید!",
|
||||
"wentWrong": "❌ مشکلی پیش آمد!",
|
||||
"noInbounds": "❗ هیچ ورودی یافت نشد!",
|
||||
"unlimited": "♾ نامحدود(ریست)",
|
||||
"add": "افزودن",
|
||||
"month": "ماه",
|
||||
"months": "ماه",
|
||||
"days": "روز",
|
||||
"hours": "ساعت",
|
||||
"minutes": "دقیقه",
|
||||
"unknown": "نامشخص",
|
||||
"inbounds": "ورودیها",
|
||||
"clients": "کاربران",
|
||||
"offline": "🔴 آفلاین",
|
||||
"online": "🟢 آنلاین",
|
||||
"commands": {
|
||||
"unknown": "❗ دستور ناشناخته",
|
||||
"pleaseChoose": "👇 لطفاً انتخاب کنید:\r\n",
|
||||
"help": "🤖 به این ربات خوش آمدید! این ربات برای ارائه دادههای خاص از سرور طراحی شده است و به شما امکان تغییرات لازم را میدهد.\r\n\r\n",
|
||||
"start": "👋 سلام <i>{{ .Firstname }}</i>.\r\n",
|
||||
"welcome": "🤖 به ربات مدیریت <b>{{ .Hostname }}</b> خوش آمدید.\r\n",
|
||||
"status": "✅ ربات در حالت عادی است!",
|
||||
"usage": "❗ لطفاً یک متن برای جستجو وارد کنید!",
|
||||
"getID": "🆔 شناسه شما: <code>{{ .ID }}</code>",
|
||||
"helpAdminCommands": "برای راهاندازی مجدد Xray Core:\r\n<code>/restart</code>\r\n\r\nبرای جستجوی ایمیل مشتری:\r\n<code>/usage [ایمیل]</code>\r\n\r\nبرای جستجوی ورودیها (با آمار مشتری):\r\n<code>/inbound [توضیحات]</code>\r\n\r\nشناسه گفتگوی تلگرام:\r\n<code>/id</code>",
|
||||
"helpClientCommands": "برای جستجوی آمار، از دستور زیر استفاده کنید:\r\n<code>/usage [ایمیل]</code>\r\n\r\nشناسه گفتگوی تلگرام:\r\n<code>/id</code>",
|
||||
"restartUsage": "\r\n\r\n<code>/restart</code>",
|
||||
"restartSuccess": "✅ عملیات با موفقیت انجام شد!",
|
||||
"restartFailed": "❗ خطا در عملیات.\r\n\r\n<code>خطا: {{ .Error }}</code>.",
|
||||
"xrayNotRunning": "❗ Xray Core در حال اجرا نیست.",
|
||||
"startDesc": "نمایش منوی اصلی",
|
||||
"helpDesc": "راهنمای ربات",
|
||||
"statusDesc": "بررسی وضعیت ربات",
|
||||
"idDesc": "نمایش شناسه تلگرام شما",
|
||||
"usageDesc": "مشاهده مصرف کاربر: /usage ایمیل",
|
||||
"inboundDesc": "جستجوی ورودیها: /inbound نام (مدیر)",
|
||||
"restartDesc": "راهاندازی مجدد هسته Xray (مدیر)",
|
||||
"clearallDesc": "صفر کردن ترافیک همه کاربران (مدیر)"
|
||||
},
|
||||
"messages": {
|
||||
"cpuThreshold": "بار پردازنده {{ .Percent }}% بیشتر از آستانه است {{ .Threshold }}%",
|
||||
"selectUserFailed": "❌ خطا در انتخاب کاربر!",
|
||||
"userSaved": "✅ کاربر تلگرام ذخیره شد.",
|
||||
"loginSuccess": "✅ با موفقیت به پنل وارد شدید.\r\n",
|
||||
"loginFailed": "❗️ ورود به پنل ناموفقبود \r\n",
|
||||
"report": "🕰 گزارشاتزمانبندیشده: {{ .RunTime }}\r\n",
|
||||
"datetime": "⏰ تاریخوزمان: {{ .DateTime }}\r\n",
|
||||
"hostname": "💻 میزبان: {{ .Hostname }}\r\n",
|
||||
"version": "🚀 نسخهپنل: {{ .Version }}\r\n",
|
||||
"xrayVersion": "📡 نسخههسته: {{ .XrayVersion }}\r\n",
|
||||
"ipv6": "🌐 IPv6: {{ .IPv6 }}\r\n",
|
||||
"ipv4": "🌐 IPv4: {{ .IPv4 }}\r\n",
|
||||
"ip": "🌐 IP: {{ .IP }}\r\n",
|
||||
"ips": "🔢 IPها:\r\n{{ .IPs }}\r\n",
|
||||
"serverUpTime": "⏳ مدتکارکردسیستم: {{ .UpTime }} {{ .Unit }}\r\n",
|
||||
"serverLoad": "📈 بارسیستم: {{ .Load1 }}, {{ .Load2 }}, {{ .Load3 }}\r\n",
|
||||
"serverMemory": "📋 RAM: {{ .Current }}/{{ .Total }}\r\n",
|
||||
"tcpCount": "🔹 TCP: {{ .Count }}\r\n",
|
||||
"udpCount": "🔸 UDP: {{ .Count }}\r\n",
|
||||
"traffic": "🚦 ترافیک: {{ .Total }} (↑{{ .Upload }},↓{{ .Download }})\r\n",
|
||||
"xrayStatus": "ℹ️ وضعیت: {{ .State }}\r\n",
|
||||
"username": "👤 نامکاربری: {{ .Username }}\r\n",
|
||||
"reason": "❗️ دلیل: {{ .Reason }}\r\n",
|
||||
"time": "⏰ زمان: {{ .Time }}\r\n",
|
||||
"inbound": "📍 ورودی: {{ .Remark }}\r\n",
|
||||
"port": "🔌 پورت: {{ .Port }}\r\n",
|
||||
"expire": "📅 تاریخانقضا: {{ .Time }}\r\n\r\n",
|
||||
"expireIn": "📅 باقی مانده تا انقضا: {{ .Time }}\r\n\r\n",
|
||||
"active": "💡 فعال: {{ .Enable }}\r\n",
|
||||
"enabled": "🚨 وضعیت: {{ .Enable }}\r\n",
|
||||
"online": "🌐 وضعیت اتصال: {{ .Status }}\r\n",
|
||||
"lastOnline": "🔙 آخرین فعالیت: {{ .Time }}\r\n",
|
||||
"email": "📧 ایمیل: {{ .Email }}\r\n",
|
||||
"upload": "🔼 آپلود: ↑{{ .Upload }}\r\n",
|
||||
"download": "🔽 دانلود: ↓{{ .Download }}\r\n",
|
||||
"total": "📊 کل: ↑↓{{ .UpDown }} / {{ .Total }}\r\n",
|
||||
"TGUser": "👤 کاربر تلگرام: {{ .TelegramID }}\r\n",
|
||||
"exhaustedCount": "🚨 تعداد {{ .Type }} بهاتمامرسیدهاست:\r\n",
|
||||
"onlinesCount": "🌐 کاربرانآنلاین: {{ .Count }}\r\n",
|
||||
"disabled": "🛑 غیرفعال: {{ .Disabled }}\r\n",
|
||||
"depleteSoon": "🔜 بهزودیبهپایانخواهدرسید: {{ .Deplete }}\r\n\r\n",
|
||||
"backupTime": "🗄 زمانپشتیبانگیری: {{ .Time }}\r\n",
|
||||
"refreshedOn": "\r\n📋🔄 تازهسازی شده در: {{ .Time }}\r\n\r\n",
|
||||
"yes": "✅ بله",
|
||||
"no": "❌ خیر",
|
||||
"received_email": "📧📥 ایمیل بهروزرسانی شد.",
|
||||
"received_comment": "💬📥 نظر بهروزرسانی شد.",
|
||||
"email_prompt": "📧 ایمیل پیشفرض: {{ .ClientEmail }}\n\nایمیل خود را وارد کنید.",
|
||||
"comment_prompt": "💬 نظر پیشفرض: {{ .ClientComment }}\n\nنظر خود را وارد کنید.",
|
||||
"cancel": "❌ فرآیند لغو شد! \n\nمیتوانید هر زمان که خواستید /start را دوباره اجرا کنید. 🔄",
|
||||
"error_add_client": "⚠️ خطا:\n\n {{ .error }}",
|
||||
"using_default_value": "باشه، از مقدار پیشفرض استفاده میکنم. 😊",
|
||||
"incorrect_input": "ورودی شما معتبر نیست.\nعبارتها باید بدون فاصله باشند.\nمثال صحیح: aaaaaa\nمثال نادرست: aaa aaa 🚫",
|
||||
"AreYouSure": "مطمئنی؟ 🤔",
|
||||
"SuccessResetTraffic": "📧 ایمیل: {{ .ClientEmail }}\n🏁 نتیجه: ✅ موفقیتآمیز",
|
||||
"FailedResetTraffic": "📧 ایمیل: {{ .ClientEmail }}\n🏁 نتیجه: ❌ ناموفق \n\n🛠️ خطا: [ {{ .ErrorMessage }} ]",
|
||||
"FinishProcess": "🔚 فرآیند بازنشانی ترافیک برای همه مشتریان به پایان رسید.",
|
||||
"eventOutboundDown": "خروجی {{ .Tag }} قطع است",
|
||||
"eventOutboundUp": "خروجی {{ .Tag }} وصل است",
|
||||
"eventErrorDetail": "خطا: {{ .Error }}",
|
||||
"eventDelayDetail": "تأخیر: {{ .Delay }} میلیثانیه",
|
||||
"eventXrayCrash": "Xray کرش کرد",
|
||||
"eventXrayCrashError": "خطا: {{ .Error }}",
|
||||
"eventNodeDown": "نود {{ .Name }} قطع است",
|
||||
"eventNodeUp": "نود {{ .Name }} وصل است",
|
||||
"eventLoginFallback": "ورود ناموفق از {{ .Source }}",
|
||||
"memoryThreshold": "مصرف حافظه {{ .Percent }}% از حد آستانه {{ .Threshold }}% فراتر رفته است"
|
||||
},
|
||||
"buttons": {
|
||||
"closeKeyboard": "❌ بستن کیبورد",
|
||||
"cancel": "❌ لغو",
|
||||
"cancelReset": "❌ لغو تنظیم مجدد",
|
||||
"cancelIpLimit": "❌ لغو محدودیت آیپی",
|
||||
"confirmResetTraffic": "✅ تأیید تنظیم مجدد ترافیک؟",
|
||||
"confirmClearIps": "✅ تأیید پاکسازی آدرسهای آیپی؟",
|
||||
"confirmRemoveTGUser": "✅ تأیید حذف کاربر تلگرام؟",
|
||||
"confirmToggle": "✅ تایید فعال/غیرفعال کردن کاربر؟",
|
||||
"dbBackup": "دریافت پشتیبان",
|
||||
"serverUsage": "استفاده از سیستم",
|
||||
"getInbounds": "دریافت ورودیها",
|
||||
"depleteSoon": "بهزودی به پایان خواهد رسید",
|
||||
"clientUsage": "دریافت آمار کاربر",
|
||||
"onlines": "کاربران آنلاین",
|
||||
"commands": "دستورات",
|
||||
"refresh": "🔄 تازهسازی",
|
||||
"clearIPs": "❌ پاکسازی آدرسها",
|
||||
"removeTGUser": "❌ حذف کاربر تلگرام",
|
||||
"selectTGUser": "👤 انتخاب کاربر تلگرام",
|
||||
"selectOneTGUser": "👤 یک کاربر تلگرام را انتخاب کنید:",
|
||||
"resetTraffic": "📈 تنظیم مجدد ترافیک",
|
||||
"resetExpire": "📅 تنظیم مجدد تاریخ انقضا",
|
||||
"ipLog": "🔢 لاگ آدرسهای IP",
|
||||
"ipLimit": "🔢 محدودیت IP",
|
||||
"setTGUser": "👤 تنظیم کاربر تلگرام",
|
||||
"toggle": "🔘 فعال / غیرفعال",
|
||||
"custom": "🔢 سفارشی",
|
||||
"confirmNumber": "✅ تایید: {{ .Num }}",
|
||||
"confirmNumberAdd": "✅ تایید اضافه کردن: {{ .Num }}",
|
||||
"limitTraffic": "🚧 محدودیت ترافیک",
|
||||
"getBanLogs": "گزارش های بلوک را دریافت کنید",
|
||||
"allClients": "همه مشتریان",
|
||||
"addClient": "افزودن مشتری",
|
||||
"submitDisable": "ارسال به عنوان غیرفعال ☑️",
|
||||
"submitEnable": "ارسال به عنوان فعال ✅",
|
||||
"use_default": "🏷️ استفاده از پیشفرض",
|
||||
"change_email": "⚙️📧 ایمیل",
|
||||
"change_comment": "⚙️💬 نظر",
|
||||
"ResetAllTraffics": "بازنشانی همه ترافیکها",
|
||||
"SortedTrafficUsageReport": "گزارش استفاده از ترافیک مرتبشده"
|
||||
},
|
||||
"answers": {
|
||||
"successfulOperation": "✅ انجام شد!",
|
||||
"errorOperation": "❗ خطا در عملیات.",
|
||||
"getInboundsFailed": "❌ دریافت ورودیها با خطا مواجه شد.",
|
||||
"getClientsFailed": "❌ دریافت مشتریان با شکست مواجه شد.",
|
||||
"canceled": "❌ {{ .Email }} : عملیات لغو شد.",
|
||||
"clientRefreshSuccess": "✅ {{ .Email }} : کلاینت با موفقیت تازهسازی شد.",
|
||||
"IpRefreshSuccess": "✅ {{ .Email }} : آدرسها با موفقیت تازهسازی شدند.",
|
||||
"TGIdRefreshSuccess": "✅ {{ .Email }} : کاربر تلگرام کلاینت با موفقیت تازهسازی شد.",
|
||||
"resetTrafficSuccess": "✅ {{ .Email }} : ترافیک با موفقیت تنظیم مجدد شد.",
|
||||
"setTrafficLimitSuccess": "✅ {{ .Email }} : محدودیت ترافیک با موفقیت ذخیره شد.",
|
||||
"expireResetSuccess": "✅ {{ .Email }} : تاریخ انقضا با موفقیت تنظیم مجدد شد.",
|
||||
"resetIpSuccess": "✅ {{ .Email }} : محدودیت آدرس IP {{ .Count }} با موفقیت ذخیره شد.",
|
||||
"clearIpSuccess": "✅ {{ .Email }} : آدرسها با موفقیت پاکسازی شدند.",
|
||||
"getIpLog": "✅ {{ .Email }} : دریافت لاگ آدرسهای IP.",
|
||||
"getUserInfo": "✅ {{ .Email }} : دریافت اطلاعات کاربر تلگرام.",
|
||||
"removedTGUserSuccess": "✅ {{ .Email }} : کاربر تلگرام با موفقیت حذف شد.",
|
||||
"enableSuccess": "✅ {{ .Email }} : با موفقیت فعال شد.",
|
||||
"disableSuccess": "✅ {{ .Email }} : با موفقیت غیرفعال شد.",
|
||||
"askToAddUserId": "پیکربندی شما یافت نشد!\r\nلطفاً از مدیر خود بخواهید که شناسه کاربر تلگرام خود را در پیکربندی (های) خود استفاده کند.\r\n\r\nشناسه کاربری شما: <code>{{ .TgUserID }}</code>",
|
||||
"chooseClient": "یک مشتری برای ورودی {{ .Inbound }} انتخاب کنید",
|
||||
"chooseInbound": "یک ورودی انتخاب کنید"
|
||||
}
|
||||
},
|
||||
"email": {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user