Telegram Mini App v1: initData auth bridge into the existing site
- POST /api/public/tg-webapp-auth: HMAC-verifies WebApp initData against the companion bot token (12h freshness, timing-safe), maps chat -> member via tg-links.json, mints a message session -> linked members land on /my/<id> with zero login - /app entry page (vendored telegram-web-app.js keeps CSP script-src 'self'); unlinked users get the one-time wallet-link instructions - tg-app.js on all pages: no-op in browsers; inside the webview lazy-loads the SDK, expands, themes header/background #071421, wires native BackButton - Bot menu button set programmatically to open /app; /start + help mention it - Synced chat.js canned answer + AI system prompt (Mini App facts) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
// Telegram Mini App entry: verify initData server-side, then land the linked
|
||||
// member on THEIR dashboard with a minted session — zero login. Unlinked
|
||||
// users get the one-time wallet-link instructions instead.
|
||||
(function () {
|
||||
'use strict';
|
||||
var tg = window.Telegram && window.Telegram.WebApp;
|
||||
function show(id) {
|
||||
['st-loading', 'st-unlinked', 'st-error', 'st-notg'].forEach(function (x) {
|
||||
var el = document.getElementById(x); if (el) el.style.display = x === id ? '' : 'none';
|
||||
});
|
||||
}
|
||||
function on(id, fn) { var el = document.getElementById(id); if (el) el.addEventListener('click', fn); }
|
||||
on('btn-open-site', function () {
|
||||
var url = location.origin + '/my';
|
||||
if (tg && tg.openLink) tg.openLink(url); else location.href = url;
|
||||
});
|
||||
on('btn-browse', function () { location.href = '/start'; });
|
||||
on('btn-retry', function () { location.reload(); });
|
||||
|
||||
if (!tg || !tg.initData) { show('st-notg'); return; }
|
||||
// Flag the webview session so tg-app.js activates on every page after this one.
|
||||
try { sessionStorage.setItem('rmcTg', '1'); } catch (e) {}
|
||||
tg.ready();
|
||||
try { tg.expand(); } catch (e) {}
|
||||
try { tg.setHeaderColor('#071421'); tg.setBackgroundColor('#071421'); } catch (e) {}
|
||||
|
||||
fetch('/api/public/tg-webapp-auth', {
|
||||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ initData: tg.initData })
|
||||
}).then(function (r) { return r.json(); }).then(function (d) {
|
||||
if (d && d.ok && d.linked) { location.replace('/my/' + d.id); return; }
|
||||
if (d && d.ok) { show('st-unlinked'); return; }
|
||||
var el = document.getElementById('err-detail');
|
||||
if (el && d && d.error) el.textContent = d.error;
|
||||
show('st-error');
|
||||
}).catch(function () { show('st-error'); });
|
||||
})();
|
||||
Reference in New Issue
Block a user