Add Telegram notifications
This commit is contained in:
@@ -119,6 +119,7 @@
|
||||
<button class="tab-btn admin-only" data-tab="credentials">AVConnect Credentials</button>
|
||||
<button class="tab-btn" data-tab="stats">Statistics</button>
|
||||
<button class="tab-btn admin-only" data-tab="admins">Admins</button>
|
||||
<button class="tab-btn admin-only" data-tab="telegram">Notifications</button>
|
||||
</nav>
|
||||
|
||||
<div class="tab-content">
|
||||
@@ -286,6 +287,42 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ── Telegram / Notifications pane ────────────────────────────────── -->
|
||||
<div id="tab-telegram" class="tab-pane">
|
||||
<h3 style="margin-bottom:1rem">Telegram Notifications</h3>
|
||||
<div class="card" style="max-width:480px">
|
||||
<p style="color:var(--text-muted);font-size:.9rem;margin-bottom:1.25rem">
|
||||
Send a message to a Telegram group or chat every time a gate is opened.
|
||||
Create a bot via <a href="https://t.me/BotFather" target="_blank" rel="noopener" style="color:var(--primary)">@BotFather</a>,
|
||||
add it to your group, and paste its token and the chat ID below.
|
||||
</p>
|
||||
<form id="telegram-form">
|
||||
<div class="field">
|
||||
<label for="tg-token">Bot Token</label>
|
||||
<input id="tg-token" type="password" autocomplete="off"
|
||||
placeholder="Leave empty to keep current" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="tg-chat-id">Chat / Group ID</label>
|
||||
<input id="tg-chat-id" type="text" autocomplete="off"
|
||||
placeholder="e.g. -1001234567890" required />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label style="display:flex;align-items:center;gap:.75rem;cursor:pointer;margin:0">
|
||||
<input type="checkbox" id="tg-enabled" checked style="width:1.1rem;height:1.1rem;flex-shrink:0;cursor:pointer" />
|
||||
<span style="font-weight:600">Enable notifications</span>
|
||||
</label>
|
||||
</div>
|
||||
<p id="tg-status" style="font-size:.85rem;color:var(--text-muted);margin-bottom:.75rem"></p>
|
||||
<p id="tg-error" class="error-msg hidden"></p>
|
||||
<div style="display:flex;gap:.75rem;flex-wrap:wrap">
|
||||
<button type="submit" class="btn btn-primary">Save</button>
|
||||
<button type="button" id="btn-tg-test" class="btn btn-ghost">Send test message</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div><!-- /.tab-content -->
|
||||
</div><!-- /#admin-view -->
|
||||
|
||||
|
||||
@@ -725,6 +725,52 @@ document.getElementById("chpw-form").addEventListener("submit", async e => {
|
||||
}
|
||||
});
|
||||
|
||||
// ── Telegram / Notifications ──────────────────────────────────────────────────
|
||||
async function loadTelegram() {
|
||||
try {
|
||||
const cfg = await api("GET", "/api/admin/telegram");
|
||||
document.getElementById("tg-chat-id").value = cfg.chat_id || "";
|
||||
document.getElementById("tg-enabled").checked = cfg.enabled;
|
||||
document.getElementById("tg-status").textContent = cfg.configured
|
||||
? "Bot token is saved. Leave the token field empty to keep it."
|
||||
: "Not configured yet. Enter a bot token to get started.";
|
||||
} catch { /* non-admin: tab hidden anyway */ }
|
||||
}
|
||||
|
||||
document.getElementById("telegram-form").addEventListener("submit", async e => {
|
||||
e.preventDefault();
|
||||
const token = document.getElementById("tg-token").value.trim() || null;
|
||||
const chat_id = document.getElementById("tg-chat-id").value.trim();
|
||||
const enabled = document.getElementById("tg-enabled").checked;
|
||||
const errEl = document.getElementById("tg-error");
|
||||
errEl.classList.add("hidden");
|
||||
try {
|
||||
await api("PUT", "/api/admin/telegram", { bot_token: token, chat_id, enabled });
|
||||
document.getElementById("tg-token").value = "";
|
||||
showToast("Telegram settings saved");
|
||||
loadTelegram();
|
||||
} catch (e) {
|
||||
errEl.textContent = e.message;
|
||||
errEl.classList.remove("hidden");
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById("btn-tg-test").addEventListener("click", async () => {
|
||||
const btn = document.getElementById("btn-tg-test");
|
||||
const errEl = document.getElementById("tg-error");
|
||||
btn.disabled = true;
|
||||
errEl.classList.add("hidden");
|
||||
try {
|
||||
await api("POST", "/api/admin/telegram/test");
|
||||
showToast("Test message sent ✓");
|
||||
} catch (e) {
|
||||
errEl.textContent = e.message;
|
||||
errEl.classList.remove("hidden");
|
||||
} finally {
|
||||
btn.disabled = false;
|
||||
}
|
||||
});
|
||||
|
||||
// ── Load all data ─────────────────────────────────────────────────────────────
|
||||
function loadAllData() {
|
||||
const isAdmin = _tokenPayload().scope === "admin";
|
||||
@@ -734,6 +780,7 @@ function loadAllData() {
|
||||
if (isAdmin) {
|
||||
loadCredentials();
|
||||
loadAdmins();
|
||||
loadTelegram();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user