feat: add telegram_diagnose backend command and connection test button

Backend: telegram_diagnose returns JSON with 8 checks (token, admin_ids,
sing-box, port, DNS with FakeIP support, direct API, proxy API, send
test message). Registered in CLI dispatcher.

Frontend: Test Connection button in Telegram settings calls
telegram_diagnose and renders results with check/cross icons.

DNS check accepts sing-box FakeIP range (198.18.x.x/198.19.x.x).
This commit is contained in:
Dushnilin
2026-08-20 22:17:09 +03:00
parent 66ffb50a1a
commit 83e1a82e71
5 changed files with 341 additions and 313 deletions
@@ -2330,167 +2330,43 @@ function createTelegramContent(section) {
result.style.color = "";
result.textContent = _("Running diagnostics…");
var token = uci.get(UCI_PACKAGE, "telegram", "bot_token") || "";
var checks = [];
function addCheck(icon, text, ok) {
checks.push(icon + " " + text);
result.textContent = checks.join("\n");
}
function runSequential(tasks, done) {
var i = 0;
function next() {
if (i >= tasks.length) {
done();
return;
fs.exec("/usr/bin/tachyon", ["telegram_diagnose"])
.then(function (res) {
var data;
try {
data = JSON.parse(res.stdout || "{}");
} catch (e) {
data = null;
}
var fn = tasks[i];
i++;
fn(next);
}
next();
}
runSequential([
// 1. Token check
function (next) {
if (!token) {
addCheck("\u274C", _("bot_token is empty — set token first"), false);
if (!data || !data.checks) {
result.textContent =
"\u274C " + _("Failed to run diagnostics — is the tachyon binary installed?");
btn.disabled = false;
btn.textContent = "\uD83D\uDD0C " + _("Test Connection");
return;
}
addCheck("\u2705", _("bot_token is set"), true);
next();
},
// 2. sing-box running
function (next) {
fs.exec("/bin/pidof", ["sing-box"])
.then(function (res) {
if (res.code === 0) {
addCheck("\u2705", _("sing-box is running"), true);
} else {
addCheck("\u274C", _("sing-box is NOT running — bot cannot route through proxy"), false);
}
next();
})
.catch(function () {
addCheck("\u274C", _("Cannot check sing-box status"), false);
next();
});
},
// 3. Mixed proxy port
function (next) {
fs.exec("/bin/sh", ["-c", "netstat -tlnp 2>/dev/null | grep ':4534 '"])
.then(function (res) {
if (res.code === 0 && res.stdout && res.stdout.trim()) {
addCheck("\u2705", _("Mixed proxy port 4534 is listening"), true);
} else {
addCheck("\u26A0\uFE0F", _("Port 4534 not listening — proxy may not be available"), false);
}
next();
})
.catch(function () {
addCheck("\u26A0\uFE0F", _("Cannot check port 4534"), false);
next();
});
},
// 4. DNS resolution
function (next) {
fs.exec("/bin/sh", ["-c", "nslookup api.telegram.org 2>/dev/null | head -5"])
.then(function (res) {
var out = (res.stdout || "").trim();
if (out && out.indexOf("Address") !== -1 && out.indexOf("149.154") !== -1) {
addCheck("\u2705", _("DNS resolves api.telegram.org"), true);
} else {
addCheck("\u274C", _("DNS cannot resolve api.telegram.org — check DNS settings"), false);
}
next();
})
.catch(function () {
addCheck("\u26A0\uFE0F", _("Cannot check DNS"), false);
next();
});
},
// 5. Direct API test (IPv4)
function (next) {
fs.exec("/usr/bin/curl", [
"-s", "-4", "--connect-timeout", "5", "--max-time", "8",
"https://api.telegram.org/bot" + token + "/getMe",
])
.then(function (res) {
var out = (res.stdout || "").trim();
if (res.code === 0 && out.indexOf('"ok":true') !== -1) {
addCheck("\u2705", _("Direct IPv4 to Telegram API works"), true);
} else if (out.indexOf('"ok":false') !== -1) {
addCheck("\u274C", _("API returned error — token may be invalid"), false);
} else {
addCheck("\u274C", _("Cannot reach Telegram API directly (IPv4 blocked by ISP?)"), false);
}
next();
})
.catch(function () {
addCheck("\u274C", _("Direct API connection failed"), false);
next();
});
},
// 6. Proxy API test
function (next) {
fs.exec("/usr/bin/curl", [
"-s", "-4", "--connect-timeout", "5", "--max-time", "8",
"--proxy", "http://127.0.0.1:4534",
"https://api.telegram.org/bot" + token + "/getMe",
])
.then(function (res) {
var out = (res.stdout || "").trim();
if (res.code === 0 && out.indexOf('"ok":true') !== -1) {
addCheck("\u2705", _("Proxy route to Telegram API works"), true);
} else {
addCheck("\u274C", _("Proxy route to Telegram API failed — check proxy outbound config"), false);
}
next();
})
.catch(function () {
addCheck("\u274C", _("Proxy API connection failed"), false);
next();
});
},
// 7. Send test message
function (next) {
var adminId = (uci.get(UCI_PACKAGE, "telegram", "admin_ids") || "").split(",")[0] || "";
if (!adminId) {
addCheck("\u26A0\uFE0F", _("No admin_ids set — cannot send test message"), false);
btn.disabled = false;
btn.textContent = "\uD83D\uDD0C " + _("Test Connection");
return;
var lines = [];
for (var i = 0; i < data.checks.length; i++) {
var c = data.checks[i];
lines.push((c.ok ? "\u2705" : "\u274C") + " " + c.message);
}
fs.exec("/usr/bin/curl", [
"-s", "-m", "10", "--connect-timeout", "5",
"--proxy", "http://127.0.0.1:4534",
"-X", "POST",
"-H", "Content-Type: application/json",
"-d", '{"chat_id":' + adminId + ',"text":"\u2705 Tachyon connection test passed"}',
"https://api.telegram.org/bot" + token + "/sendMessage",
])
.then(function (res) {
var out = (res.stdout || "").trim();
if (res.code === 0 && out.indexOf('"ok":true') !== -1) {
addCheck("\u2705", _("Test message sent to chat ") + adminId, true);
} else {
addCheck("\u274C", _("Failed to send test message — check admin_ids and bot permissions"), false);
}
next();
})
.catch(function () {
addCheck("\u274C", _("Failed to send test message"), false);
next();
});
},
], function () {
btn.disabled = false;
btn.textContent = "\uD83D\uDD0C " + _("Test Connection");
});
if (data.ok) {
lines.push("");
lines.push("\u2705 " + _("All checks passed — Telegram bot should work correctly"));
}
result.textContent = lines.join("\n");
result.style.color = data.ok ? "" : "#e53935";
btn.disabled = false;
btn.textContent = "\uD83D\uDD0C " + _("Test Connection");
})
.catch(function () {
result.textContent =
"\u274C " + _("Failed to run diagnostics — is the tachyon binary installed?");
btn.disabled = false;
btn.textContent = "\uD83D\uDD0C " + _("Test Connection");
});
});
return wrapper;
+74 -68
View File
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: TACHYON\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-08-20 21:52+0300\n"
"PO-Revision-Date: 2026-08-20 21:52+0300\n"
"POT-Creation-Date: 2026-08-20 22:16+0300\n"
"PO-Revision-Date: 2026-08-20 22:16+0300\n"
"Last-Translator: Dushnilin\n"
"Language-Team: none\n"
"Language: ru\n"
@@ -209,6 +209,9 @@ msgstr "Настройки AI Watchdog сохранены. Перезапуст
msgid "All"
msgstr "Все"
msgid "All checks passed — Telegram bot should work correctly"
msgstr ""
msgid "All devices"
msgstr "Все устройства"
@@ -281,9 +284,6 @@ msgstr "Другое действие уже выполняется"
msgid "API Key for OpenAI (sk-...) or DeepSeek (optional for Ollama / LM Studio)"
msgstr "API-ключ для OpenAI (sk-...) или DeepSeek (опционально для Ollama / LM Studio)"
msgid "API returned error — token may be invalid"
msgstr ""
msgid "Apply rules of this section only to selected protocols."
msgstr "Применять правила этой секции только к выбранным протоколам."
@@ -398,12 +398,6 @@ msgstr "Bootstrap DNS-серверы"
msgid "Bot Status"
msgstr "Статус бота"
msgid "bot_token is empty — set token first"
msgstr ""
msgid "bot_token is set"
msgstr ""
msgid "Browser FakeIP check could not be completed"
msgstr "Не удалось выполнить проверку FakeIP в браузере"
@@ -476,18 +470,6 @@ msgstr "Путь к файлу кэша не может быть пустым"
msgid "Cancel"
msgstr "Отмена"
msgid "Cannot check DNS"
msgstr ""
msgid "Cannot check port 4534"
msgstr ""
msgid "Cannot check sing-box status"
msgstr ""
msgid "Cannot reach Telegram API directly (IPv4 blocked by ISP?)"
msgstr ""
msgid "Cannot receive checks result"
msgstr "Не удалось получить результаты проверки"
@@ -851,18 +833,12 @@ msgstr "Напрямую"
msgid "Direct (Default)"
msgstr "Прямое (по умолчанию)"
msgid "Direct API connection failed"
msgstr ""
msgid "Direct Bypass"
msgstr "Прямой WAN"
msgid "Direct connection"
msgstr "Прямое подключение"
msgid "Direct IPv4 to Telegram API works"
msgstr ""
msgid "Direct WAN"
msgstr "Прямой WAN"
@@ -887,9 +863,6 @@ msgstr "Отображаемое имя"
msgid "DNS"
msgstr "DNS"
msgid "DNS cannot resolve api.telegram.org — check DNS settings"
msgstr ""
msgid "DNS Check Interval"
msgstr "Интервал проверки DNS"
@@ -923,9 +896,6 @@ msgstr "Протокол DNS, используемый резолвером"
msgid "DNS requests through section"
msgstr "DNS-запросы через секцию"
msgid "DNS resolves api.telegram.org"
msgstr ""
msgid "DNS Rewrite TTL"
msgstr "TTL DNS-записей"
@@ -1337,6 +1307,9 @@ msgstr "Не удалось восстановить прямой интерне
msgid "Failed to restore snapshot"
msgstr "Не удалось восстановить снапшот"
msgid "Failed to run diagnostics — is the tachyon binary installed?"
msgstr ""
msgid "Failed to save AI Watchdog settings"
msgstr "Ошибка сохранения настроек AI Watchdog"
@@ -1352,12 +1325,6 @@ msgstr "Ошибка сохранения настроек Smart Detect"
msgid "Failed to save snapshot"
msgstr "Не удалось сохранить снапшот"
msgid "Failed to send test message"
msgstr ""
msgid "Failed to send test message — check admin_ids and bot permissions"
msgstr ""
msgid "Failed to start bot"
msgstr "Не удалось запустить бота"
@@ -2219,9 +2186,6 @@ msgstr "Пароль смешанного прокси"
msgid "Mixed Proxy Port"
msgstr "Порт смешанного прокси"
msgid "Mixed proxy port 4534 is listening"
msgstr ""
msgid "Mixed Proxy Username"
msgstr "Имя пользователя смешанного прокси"
@@ -2324,9 +2288,6 @@ msgstr "Активные устройства в локальной сети н
msgid "No active routing sections found."
msgstr "Активные секции маршрутизации не найдены."
msgid "No admin_ids set — cannot send test message"
msgstr ""
msgid "No closed connections"
msgstr "Нет закрытых подключений"
@@ -2645,9 +2606,6 @@ msgstr "Интервал опроса (секунды)"
msgid "Polling interval must be at least 1 second"
msgstr "Интервал опроса должен быть не менее 1 секунды"
msgid "Port 4534 not listening — proxy may not be available"
msgstr ""
msgid "Port cannot be empty"
msgstr "Порт не может быть пустым"
@@ -2732,9 +2690,6 @@ msgstr "Протокол"
msgid "Proxy / DPI"
msgstr "Прокси / DPI"
msgid "Proxy API connection failed"
msgstr ""
msgid "Proxy Fail Threshold"
msgstr "Порог ошибок прокси"
@@ -2747,12 +2702,6 @@ msgstr "URL проверки здоровья прокси"
msgid "Proxy link is unavailable"
msgstr "Ссылка прокси недоступна"
msgid "Proxy route to Telegram API failed — check proxy outbound config"
msgstr ""
msgid "Proxy route to Telegram API works"
msgstr ""
msgid "Proxy Section for Bot"
msgstr "Секция прокси для бота"
@@ -3359,12 +3308,6 @@ msgstr "FakeIP DNS sing-box работает"
msgid "Sing-box installed"
msgstr "Sing-box установлен"
msgid "sing-box is NOT running — bot cannot route through proxy"
msgstr ""
msgid "sing-box is running"
msgstr ""
msgid "Sing-box listening ports"
msgstr "Sing-box слушает порты"
@@ -3674,9 +3617,6 @@ msgstr ""
msgid "Test latency"
msgstr "Тестирование задержки"
msgid "Test message sent to chat"
msgstr ""
msgid "Test only selected servers."
msgstr "Тестировать только выбранные серверы."
@@ -4250,6 +4190,72 @@ msgstr "sing-box outbound для Zapret2 настроен"
msgid "Zapret2 sing-box outbound is not configured"
msgstr "sing-box outbound для Zapret2 не настроен"
msgid "API returned error — token may be invalid"
msgstr ""
msgid "bot_token is empty — set token first"
msgstr ""
msgid "bot_token is set"
msgstr ""
msgid "Cannot check DNS"
msgstr ""
msgid "Cannot check port 4534"
msgstr ""
msgid "Cannot check sing-box status"
msgstr ""
msgid "Cannot reach Telegram API directly (IPv4 blocked by ISP?)"
msgstr ""
msgid "Direct API connection failed"
msgstr ""
msgid "Direct IPv4 to Telegram API works"
msgstr ""
msgid "DNS cannot resolve api.telegram.org — check DNS settings"
msgstr ""
msgid "DNS resolves api.telegram.org"
msgstr ""
msgid "Failed to send test message"
msgstr ""
msgid "Failed to send test message — check admin_ids and bot permissions"
msgstr ""
msgid "Mixed proxy port 4534 is listening"
msgstr ""
msgid "No admin_ids set — cannot send test message"
msgstr ""
msgid "Port 4534 not listening — proxy may not be available"
msgstr ""
msgid "Proxy API connection failed"
msgstr ""
msgid "Proxy route to Telegram API failed — check proxy outbound config"
msgstr ""
msgid "Proxy route to Telegram API works"
msgstr ""
msgid "sing-box is NOT running — bot cannot route through proxy"
msgstr ""
msgid "sing-box is running"
msgstr ""
msgid "Test message sent to chat"
msgstr ""
msgid "Device / IP"
msgstr "Устройство / IP"
+118 -90
View File
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: TACHYON\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-08-20 16:44+0300\n"
"PO-Revision-Date: 2026-08-20 16:44+0300\n"
"POT-Creation-Date: 2026-08-20 19:16+0300\n"
"PO-Revision-Date: 2026-08-20 19:16+0300\n"
"Last-Translator: Dushnilin <dushnilin@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
@@ -323,6 +323,10 @@ msgstr ""
msgid "All"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:2357
msgid "All checks passed — Telegram bot should work correctly"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/parental.js:139
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/parental.js:159
msgid "All devices"
@@ -418,8 +422,8 @@ msgstr ""
msgid "Anonymized support report copied to clipboard"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16898
#: src/tachyon/tabs/updates/initController.ts:864
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16916
#: src/tachyon/tabs/updates/initController.ts:873
msgid "Another component action is already running"
msgstr ""
@@ -755,8 +759,8 @@ msgid "Certificate pin is unavailable. Apply or restart the server to generate t
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16152
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16625
#: src/tachyon/tabs/updates/initController.ts:501
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16643
#: src/tachyon/tabs/updates/initController.ts:510
#: src/tachyon/tabs/updates/partials/renderUpdateProgressModal.ts:321
msgid "Check completed!"
msgstr ""
@@ -784,8 +788,8 @@ msgstr ""
msgid "Check timeout after which the server is considered dead"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16956
#: src/tachyon/tabs/updates/initController.ts:933
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16974
#: src/tachyon/tabs/updates/initController.ts:942
msgid "Check update"
msgstr ""
@@ -857,17 +861,17 @@ msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8845
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9323
#: src/tachyon/tabs/diagnostic/helpers/getMeta.ts:26
#: src/tachyon/tabs/diagnostic/checks/getCheckItemsMeta.ts:10
#: src/tachyon/tabs/diagnostic/helpers/getMeta.ts:26
msgid "Checks failed"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8834
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9280
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9334
#: src/tachyon/tabs/diagnostic/helpers/getMeta.ts:13
#: src/tachyon/tabs/diagnostic/checks/getCheckItemsMeta.ts:23
#: src/tachyon/tabs/diagnostic/checks/runFakeIPCheck.ts:43
#: src/tachyon/tabs/diagnostic/helpers/getMeta.ts:13
msgid "Checks passed"
msgstr ""
@@ -968,19 +972,19 @@ msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:13038
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:14584
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:14624
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16238
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16273
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16247
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16282
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:3660
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:10239
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/server.js:1803
#: src/partials/modal/renderModal.ts:263
#: src/tachyon/tabs/diagnostic/initController.ts:1542
#: src/tachyon/tabs/dashboard/initController.ts:1262
#: src/tachyon/tabs/monitoring/initController.ts:884
#: src/tachyon/tabs/monitoring/initController.ts:934
#: src/tachyon/tabs/diagnostic/initController.ts:1542
#: src/tachyon/tabs/diagnostic/partials/renderAiChatModal.ts:213
#: src/tachyon/tabs/updates/partials/renderUpdateProgressModal.ts:431
#: src/tachyon/tabs/updates/partials/renderUpdateProgressModal.ts:477
#: src/tachyon/tabs/updates/partials/renderUpdateProgressModal.ts:439
#: src/tachyon/tabs/updates/partials/renderUpdateProgressModal.ts:485
msgid "Close"
msgstr ""
@@ -1075,8 +1079,8 @@ msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:4919
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:11522
#: src/tachyon/methods/custom/getDashboardSections.ts:1646
#: src/tachyon/tabs/dashboard/partials/renderSections.ts:616
#: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:141
#: src/tachyon/tabs/dashboard/partials/renderSections.ts:616
msgid "Conflict"
msgstr ""
@@ -2004,16 +2008,16 @@ msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:3226
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:3229
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16710
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16710
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16768
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16939
#: src/tachyon/tabs/updates/initController.ts:622
#: src/tachyon/tabs/updates/initController.ts:623
#: src/tachyon/tabs/updates/initController.ts:698
#: src/tachyon/tabs/updates/initController.ts:911
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16728
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16728
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16786
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16957
#: src/tachyon/methods/shell/index.ts:172
#: src/tachyon/methods/shell/index.ts:179
#: src/tachyon/tabs/updates/initController.ts:631
#: src/tachyon/tabs/updates/initController.ts:632
#: src/tachyon/tabs/updates/initController.ts:707
#: src/tachyon/tabs/updates/initController.ts:920
msgid "Failed to execute"
msgstr ""
@@ -2064,6 +2068,11 @@ msgstr ""
msgid "Failed to restore snapshot"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:2344
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:2366
msgid "Failed to run diagnostics — is the tachyon binary installed?"
msgstr ""
#: src/tachyon/tabs/dashboard/partials/renderAdvancedSettings.ts:421
msgid "Failed to save AI Watchdog settings"
msgstr ""
@@ -2635,27 +2644,27 @@ msgstr ""
msgid "Init timeout (Itime)"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16228
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16965
#: src/tachyon/tabs/updates/initController.ts:947
#: src/tachyon/tabs/updates/partials/renderUpdateProgressModal.ts:420
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16237
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16983
#: src/tachyon/tabs/updates/initController.ts:956
#: src/tachyon/tabs/updates/partials/renderUpdateProgressModal.ts:428
msgid "Install"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17367
#: src/tachyon/tabs/updates/initController.ts:1435
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17385
#: src/tachyon/tabs/updates/initController.ts:1444
msgid "Install another build:"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17247
#: src/tachyon/tabs/updates/initController.ts:1296
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17265
#: src/tachyon/tabs/updates/initController.ts:1305
msgid "Installed build → Available build"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16507
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17255
#: src/tachyon/tabs/updates/initController.ts:341
#: src/tachyon/tabs/updates/initController.ts:1304
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16525
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17273
#: src/tachyon/tabs/updates/initController.ts:350
#: src/tachyon/tabs/updates/initController.ts:1313
msgid "Installed version is newer than release"
msgstr ""
@@ -3077,8 +3086,8 @@ msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:8840
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9329
#: src/tachyon/tabs/diagnostic/helpers/getMeta.ts:20
#: src/tachyon/tabs/diagnostic/checks/getCheckItemsMeta.ts:17
#: src/tachyon/tabs/diagnostic/helpers/getMeta.ts:20
msgid "Issues detected"
msgstr ""
@@ -3223,15 +3232,15 @@ msgstr ""
msgid "Latency test URL"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16509
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17253
#: src/tachyon/tabs/updates/initController.ts:344
#: src/tachyon/tabs/updates/initController.ts:1302
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16527
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17271
#: src/tachyon/tabs/updates/initController.ts:353
#: src/tachyon/tabs/updates/initController.ts:1311
msgid "Latest version is installed"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17255
#: src/tachyon/tabs/updates/initController.ts:1304
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17273
#: src/tachyon/tabs/updates/initController.ts:1313
msgid "Latest version:"
msgstr ""
@@ -3314,16 +3323,16 @@ msgstr ""
msgid "Loading connections"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17129
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17142
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17152
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17162
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17172
#: src/tachyon/tabs/updates/initController.ts:1148
#: src/tachyon/tabs/updates/initController.ts:1163
#: src/tachyon/tabs/updates/initController.ts:1181
#: src/tachyon/tabs/updates/initController.ts:1195
#: src/tachyon/tabs/updates/initController.ts:1209
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17147
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17160
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17170
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17180
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17190
#: src/tachyon/tabs/updates/initController.ts:1157
#: src/tachyon/tabs/updates/initController.ts:1172
#: src/tachyon/tabs/updates/initController.ts:1190
#: src/tachyon/tabs/updates/initController.ts:1204
#: src/tachyon/tabs/updates/initController.ts:1218
msgid "Loading..."
msgstr ""
@@ -3701,9 +3710,9 @@ msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9031
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:11533
#: src/tachyon/methods/custom/getDashboardSections.ts:1649
#: src/tachyon/tabs/dashboard/partials/renderSections.ts:619
#: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:46
#: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:152
#: src/tachyon/tabs/dashboard/partials/renderSections.ts:619
msgid "Not configured"
msgstr ""
@@ -3728,14 +3737,14 @@ msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:5653
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:5658
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17152
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17162
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17172
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17170
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17180
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17190
#: src/tachyon/helpers/singBoxVariant.ts:38
#: src/tachyon/helpers/singBoxVariant.ts:46
#: src/tachyon/tabs/updates/initController.ts:1184
#: src/tachyon/tabs/updates/initController.ts:1198
#: src/tachyon/tabs/updates/initController.ts:1212
#: src/tachyon/tabs/updates/initController.ts:1193
#: src/tachyon/tabs/updates/initController.ts:1207
#: src/tachyon/tabs/updates/initController.ts:1221
msgid "Not installed"
msgstr ""
@@ -3868,10 +3877,10 @@ msgstr ""
msgid "Only the specified servers."
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17230
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17267
#: src/tachyon/tabs/updates/initController.ts:1278
#: src/tachyon/tabs/updates/initController.ts:1317
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17248
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17285
#: src/tachyon/tabs/updates/initController.ts:1287
#: src/tachyon/tabs/updates/initController.ts:1326
msgid "Open"
msgstr ""
@@ -3889,8 +3898,8 @@ msgstr ""
msgid "Operation completed successfully!"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16269
#: src/tachyon/tabs/updates/partials/renderUpdateProgressModal.ts:472
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16278
#: src/tachyon/tabs/updates/partials/renderUpdateProgressModal.ts:480
msgid "Operation failed"
msgstr ""
@@ -4335,8 +4344,8 @@ msgstr ""
msgid "Rebuild firewall rules"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17249
#: src/tachyon/tabs/updates/initController.ts:1298
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17267
#: src/tachyon/tabs/updates/initController.ts:1307
msgid "Rebuilt release"
msgstr ""
@@ -4385,8 +4394,8 @@ msgstr ""
msgid "Regular expression must not contain spaces or commas"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17046
#: src/tachyon/tabs/updates/initController.ts:1061
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17064
#: src/tachyon/tabs/updates/initController.ts:1070
msgid "Reinstall"
msgstr ""
@@ -4409,9 +4418,9 @@ msgstr ""
msgid "Removal completed successfully!"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17014
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17032
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:7927
#: src/tachyon/tabs/updates/initController.ts:1017
#: src/tachyon/tabs/updates/initController.ts:1026
msgid "Remove"
msgstr ""
@@ -4713,11 +4722,15 @@ msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:2027
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:2028
#: src/tachyon/methods/custom/getDashboardSections.ts:1644
#: src/tachyon/tabs/dashboard/partials/renderSections.ts:614
#: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:135
#: src/tachyon/tabs/dashboard/partials/renderSections.ts:614
msgid "Running"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:2331
msgid "Running diagnostics…"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:9246
msgid "Russia (ru)"
msgstr ""
@@ -5087,9 +5100,9 @@ msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:3410
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:3429
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:12323
#: src/tachyon/tabs/diagnostic/initController.ts:604
#: src/tachyon/methods/shell/index.ts:422
#: src/tachyon/methods/shell/index.ts:443
#: src/tachyon/tabs/diagnostic/initController.ts:604
msgid "Service action failed"
msgstr ""
@@ -5116,8 +5129,8 @@ msgstr ""
msgid "Services info"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16217
#: src/tachyon/tabs/updates/partials/renderUpdateProgressModal.ts:407
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16226
#: src/tachyon/tabs/updates/partials/renderUpdateProgressModal.ts:415
msgid "Services restarted. Click to reload page."
msgstr ""
@@ -5421,8 +5434,8 @@ msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:307
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:2033
#: src/tachyon/methods/custom/getDashboardSections.ts:1648
#: src/tachyon/tabs/dashboard/partials/renderSections.ts:618
#: src/tachyon/tabs/diagnostic/checks/runSectionsCheck.ts:147
#: src/tachyon/tabs/dashboard/partials/renderSections.ts:618
msgid "Stopped"
msgstr ""
@@ -5662,6 +5675,13 @@ msgstr ""
msgid "Telegram Bot Token"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:2317
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:2346
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:2362
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:2368
msgid "Test Connection"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2104
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2108
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:2606
@@ -5695,11 +5715,19 @@ msgstr ""
msgid "Test servers whose names match the expression."
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:2304
msgid "Test Telegram Connection"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:7445
#: src/tachyon/tabs/dashboard/initController.ts:1287
msgid "Testing URL"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:2328
msgid "Testing…"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:5654
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/section.js:6099
msgid "The desync fwmark is managed by Tachyon for loop prevention and must not be overridden here."
@@ -5890,8 +5918,8 @@ msgstr ""
msgid "Traffic will go through the default route (Direct/Default)."
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16913
#: src/tachyon/tabs/updates/initController.ts:880
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16931
#: src/tachyon/tabs/updates/initController.ts:889
msgid "Transient connection error"
msgstr ""
@@ -6058,8 +6086,7 @@ msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9612
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9615
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:9616
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16536
#: src/tachyon/helpers/singBoxVariant.ts:37
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16554
#: src/tachyon/services/systemInfo.service.ts:10
#: src/tachyon/services/systemInfo.service.ts:12
#: src/tachyon/services/systemInfo.service.ts:13
@@ -6069,7 +6096,8 @@ msgstr ""
#: src/tachyon/services/systemInfo.service.ts:25
#: src/tachyon/services/systemInfo.service.ts:28
#: src/tachyon/services/systemInfo.service.ts:29
#: src/tachyon/tabs/updates/initController.ts:382
#: src/tachyon/helpers/singBoxVariant.ts:37
#: src/tachyon/tabs/updates/initController.ts:391
#: src/tachyon/tabs/diagnostic/checks/runInboundsCheck.ts:25
msgid "unknown"
msgstr ""
@@ -6130,23 +6158,23 @@ msgstr ""
msgid "Up to 10 snapshots are kept; the oldest ones are removed automatically."
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16965
#: src/tachyon/tabs/updates/initController.ts:947
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16983
#: src/tachyon/tabs/updates/initController.ts:956
msgid "Update"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16504
#: src/tachyon/tabs/updates/initController.ts:337
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:16522
#: src/tachyon/tabs/updates/initController.ts:346
msgid "Update is available"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17237
#: src/tachyon/tabs/updates/initController.ts:1285
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17255
#: src/tachyon/tabs/updates/initController.ts:1294
msgid "Update is available for current release"
msgstr ""
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17218
#: src/tachyon/tabs/updates/initController.ts:1264
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/main.js:17236
#: src/tachyon/tabs/updates/initController.ts:1273
msgid "Update is available:"
msgstr ""
+2
View File
@@ -145,6 +145,7 @@ function show_help() {
print(" mcp MCP server: JSON-RPC 2.0 over stdio (Model Context Protocol)\n");
print(" watchdog Manage watchdog daemon (start-runtime|stop-runtime|status)\n");
print(" telegram_status Get Telegram bot running status\n");
print(" telegram_diagnose Run Telegram connection diagnostics (JSON)\n");
print(" telegram_start Start Telegram bot\n");
print(" telegram_stop Stop Telegram bot\n");
print(" snapshot_list List saved config snapshots (JSON)\n");
@@ -249,6 +250,7 @@ function command_spec(command) {
telegram_status: [ "service/telegram.uc", "status", 0 ],
telegram_start: [ "service/telegram.uc", "start-runtime", 0 ],
telegram_stop: [ "service/telegram.uc", "stop-runtime", 0 ],
telegram_diagnose: [ "service/telegram.uc", "diagnose", 0 ],
validate_nfqws_strategy_json: [ "diagnostics/runtime.uc", "validate-nfqws-strategy-json", 1 ],
validate_nfqws2_strategy_json: [ "diagnostics/runtime.uc", "validate-nfqws2-strategy-json", 1 ],
validate_byedpi_strategy_json: [ "providers/byedpi/validator.uc", "validate-json", 1 ],
+117 -1
View File
@@ -2889,6 +2889,120 @@ function in_quiet_hours(cfg) {
}
}
function diagnose() {
let cfg = settings();
let checks = [];
let ok = true;
// 1. bot_token
if (cfg.bot_token) {
push(checks, { name: "bot_token", ok: true, message: "bot_token is set" });
} else {
push(checks, { name: "bot_token", ok: false, message: "bot_token is empty — set token first" });
ok = false;
}
// 2. admin_ids
if (cfg.admin_ids && trim(cfg.admin_ids) !== "") {
push(checks, { name: "admin_ids", ok: true, message: "admin_ids is set: " + cfg.admin_ids });
} else {
push(checks, { name: "admin_ids", ok: false, message: "admin_ids is empty — cannot send messages" });
ok = false;
}
// 3. sing-box running
let sb_running = command_success_from_args(["pidof", "sing-box"]);
push(checks, {
name: "sing_box",
ok: sb_running,
message: sb_running ? "sing-box is running" : "sing-box is NOT running — bot cannot route through proxy"
});
if (!sb_running) ok = false;
// 4. Mixed proxy port 4534
let port_check = command_capture("netstat -tlnp 2>/dev/null | grep ':4534 '");
let port_ok = port_check && port_check.status === 0 && trim(port_check.output || "") !== "";
push(checks, {
name: "proxy_port",
ok: port_ok,
message: port_ok ? "Mixed proxy port 4534 is listening" : "Port 4534 not listening — proxy may not be available"
});
// 5. DNS resolution
let dns_check = command_capture("nslookup api.telegram.org 2>/dev/null");
let dns_out = (dns_check && dns_check.output) || "";
// Accept real IPs (149.154/91.108) or sing-box FakeIP range (198.18.x.x/198.19.x.x)
let dns_ok = dns_check && dns_check.status === 0 && index(dns_out, "Address") >= 0
&& (index(dns_out, "149.154") >= 0 || index(dns_out, "91.108") >= 0
|| index(dns_out, "198.18.") >= 0 || index(dns_out, "198.19.") >= 0);
push(checks, {
name: "dns",
ok: dns_ok,
message: dns_ok ? "DNS resolves api.telegram.org" : "DNS cannot resolve api.telegram.org — check DNS settings"
});
// 6. Direct API test (IPv4)
if (cfg.bot_token) {
let direct = command_capture(command_from_args([
"curl", "-s", "-4", "--connect-timeout", "5", "--max-time", "8",
"https://api.telegram.org/bot" + cfg.bot_token + "/getMe"
]));
let d_out = (direct && direct.output) || "";
let d_ok = direct && direct.status === 0 && index(d_out, '"ok":true') >= 0;
let d_msg = d_ok
? "Direct IPv4 to Telegram API works"
: (index(d_out, '"ok":false') >= 0
? "API returned error — token may be invalid"
: "Cannot reach Telegram API directly (IPv4 may be blocked by ISP)");
push(checks, { name: "direct_api", ok: d_ok, message: d_msg });
if (!d_ok) ok = false;
}
// 7. Proxy API test
if (cfg.bot_token && sb_running) {
let proxied = command_capture(command_from_args([
"curl", "-s", "-4", "--connect-timeout", "5", "--max-time", "8",
"--proxy", "http://127.0.0.1:4534",
"https://api.telegram.org/bot" + cfg.bot_token + "/getMe"
]));
let p_out = (proxied && proxied.output) || "";
let p_ok = proxied && proxied.status === 0 && index(p_out, '"ok":true') >= 0;
push(checks, {
name: "proxy_api",
ok: p_ok,
message: p_ok ? "Proxy route to Telegram API works" : "Proxy route failed — check sing-box outbound for Telegram"
});
if (!p_ok) ok = false;
}
// 8. Send test message
if (cfg.bot_token && cfg.admin_ids) {
let first_admin = trim(split(cfg.admin_ids, /,/)[0] || "");
if (first_admin !== "") {
let send_res = command_capture(command_from_args([
"curl", "-s", "-m", "10", "--connect-timeout", "5",
"--proxy", "http://127.0.0.1:4534",
"-X", "POST", "-H", "Content-Type: application/json",
"-d", sprintf("%J", { chat_id: int(first_admin), text: "\u2705 Tachyon connection test passed" }),
"https://api.telegram.org/bot" + cfg.bot_token + "/sendMessage"
]));
let s_out = (send_res && send_res.output) || "";
let s_ok = send_res && send_res.status === 0 && index(s_out, '"ok":true') >= 0;
push(checks, {
name: "send_message",
ok: s_ok,
message: s_ok
? "Test message sent to chat " + first_admin
: "Failed to send test message — check admin_ids and bot permissions"
});
if (!s_ok) ok = false;
}
}
print(sprintf("%J", { ok: ok, checks: checks }));
return ok ? 0 : 1;
}
function send_api(message) {
let cfg = settings();
if (cfg.enabled != "1" || !cfg.bot_token || !cfg.admin_ids) return 1;
@@ -2915,6 +3029,8 @@ else if (mode == "worker")
exit(worker());
else if (mode == "status")
exit(get_status());
else if (mode == "diagnose")
exit(diagnose());
else if (mode == "send") {
// Collect remaining args after "send" as the message text
let msg_parts = [];
@@ -2925,6 +3041,6 @@ else if (mode == "send") {
exit(send_api(message));
}
else {
warn("Usage: service/telegram.uc <start-runtime|stop-runtime|worker|status|send ...> ...\n");
warn("Usage: service/telegram.uc <start-runtime|stop-runtime|worker|status|diagnose|send ...> ...\n");
exit(1);
}