Telegram: echo payouts into a shared cross-program topic
telegramOnEvent now builds the line once per target: the existing proof feed (telegramChatId) and a new echo target (telegramEchoChatId + telegramEchoTopicId, telegramEchoEvents). AwardPaid events are now posted too. Echo lines carry an InstantAdPay prefix since RM Circle shares the topic. Admin labels added. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -485,7 +485,7 @@
|
||||
}));
|
||||
|
||||
// site settings: key / value rows; booleans as checkboxes, numbers stay numbers
|
||||
const SITE_META = { siteName: 'Site name', tagline: 'Tagline', rehearsal: 'Testnet rehearsal banner', defaultSponsorId: 'Fallback sponsor (member #)', walletConnectProjectId: 'WalletConnect project id', moonpayPublicKey: 'MoonPay public key', telegramBotToken: 'Telegram proof feed: bot token', telegramChatId: 'Telegram proof feed: chat id', telegramTopicId: 'Telegram proof feed: topic id (optional)', telegramEvents: 'Telegram proof feed: events (payouts | payouts+purchases | all)', telegramCtaUrl: 'Telegram proof feed: join link under each post', pnlFixedMonthlyUsd: 'P&L: fixed monthly cost (USD)' };
|
||||
const SITE_META = { siteName: 'Site name', tagline: 'Tagline', rehearsal: 'Testnet rehearsal banner', defaultSponsorId: 'Fallback sponsor (member #)', walletConnectProjectId: 'WalletConnect project id', moonpayPublicKey: 'MoonPay public key', telegramBotToken: 'Telegram proof feed: bot token', telegramChatId: 'Telegram proof feed: chat id', telegramTopicId: 'Telegram proof feed: topic id (optional)', telegramEvents: 'Telegram proof feed: events (payouts | payouts+purchases | all)', telegramCtaUrl: 'Telegram proof feed: join link under each post', telegramEchoChatId: 'Telegram echo (shared payments topic): chat id', telegramEchoTopicId: 'Telegram echo: topic id', telegramEchoEvents: 'Telegram echo: events (payouts | payouts+purchases | all)', pnlFixedMonthlyUsd: 'P&L: fixed monthly cost (USD)' };
|
||||
function drawSite() {
|
||||
const wrap = $('siteForm');
|
||||
wrap.innerHTML = Object.entries(siteObj).map(([k, v]) => '<div class="kv-row"><span class="k" title="' + esc(k) + '">' + esc(SITE_META[k] || humanize(k)) + '</span>'
|
||||
|
||||
@@ -339,6 +339,7 @@ function siteConfig() {
|
||||
rehearsal: true, // shows the testnet banner; flipped off at mainnet launch
|
||||
// payment-proof Telegram feed (blank = off) and the P&L pane's fixed monthly cost
|
||||
telegramBotToken: '', telegramChatId: '', telegramTopicId: '', telegramEvents: 'payouts', telegramCtaUrl: 'https://instantadpay.com/',
|
||||
telegramEchoChatId: '', telegramEchoTopicId: '', telegramEchoEvents: 'payouts', // shared cross-program payments topic
|
||||
telegramAdminChatId: '', // private chat for admin alerts (sign-up guard bursts); falls back to ADMIN_EMAIL
|
||||
launchAt: '', // public launch moment, ISO 8601 with offset (e.g. 2026-09-18T19:00:00-05:00): countdown on /launch + dashboard mark
|
||||
geoTier1: '', // comma-separated ISO country codes; empty = built-in default (US, CA, GB, AU, NZ, IE, DE, FR, NL, SE, NO, DK, FI, CH, AT, BE)
|
||||
@@ -526,22 +527,29 @@ async function emailOnEvent(ev) {
|
||||
// payment-proof Telegram feed (same pattern as the RM Circle proof channel): one compact
|
||||
// line per event, admin-configured under Settings > Site (telegramBotToken, telegramChatId,
|
||||
// optional telegramTopicId, telegramEvents = payouts | payouts+purchases | all, telegramCtaUrl)
|
||||
// A second target, telegramEchoChatId + telegramEchoTopicId (+ telegramEchoEvents), echoes
|
||||
// the same lines into a shared cross-program payments topic that RM Circle also posts to,
|
||||
// so every line there carries the program name.
|
||||
async function telegramOnEvent(ev) {
|
||||
const sc = siteConfig();
|
||||
if (!sc.telegramBotToken || !sc.telegramChatId || !ev) return;
|
||||
const mode = String(sc.telegramEvents || 'payouts');
|
||||
if (!sc.telegramBotToken || !ev) return;
|
||||
if (!sc.telegramChatId && !sc.telegramEchoChatId) return;
|
||||
const names = await accounts.namesForMembers([ev.recipientId, ev.buyerId, ev.sponsorId, ev.newBuyerId, ev.id].filter(Boolean)).catch(() => ({}));
|
||||
const who = id => '#' + id + (names[id] ? ' @' + names[id] : '');
|
||||
const cc = chain.getConfig();
|
||||
const tx = (cc.explorer ? cc.explorer.replace(/\/+$/, '') : 'https://polygonscan.com') + '/tx/' + ev.tx;
|
||||
const build = (mode) => {
|
||||
let line = null;
|
||||
if (ev.type === 'TierPaid') line = '\u{1F4B8} Level ' + ev.tier + ' payout: <b>' + weiToPol(ev.amountWei) + ' POL</b> \u2192 ' + who(ev.recipientId);
|
||||
else if (ev.type === 'BuyerCounted' && mode !== 'payouts') line = '\u2B50 ' + who(ev.sponsorId) + ' now has <b>' + ev.newCount + '</b> qualifying buyer' + (ev.newCount === 1 ? '' : 's') + (ev.newCount === 2 ? ' \u00b7 level 2 open' : ev.newCount === 5 ? ' \u00b7 level 3 open' : '');
|
||||
else if (ev.type === 'Purchase' && mode !== 'payouts') line = '\u{1F9FE} ' + who(ev.buyerId) + ' bought a $' + Math.round(ev.priceCents / 100) + ' package';
|
||||
else if (ev.type === 'AwardPaid') line = '\u{1F4B8} Award payout: <b>' + weiToPol(ev.amountWei) + ' POL</b> \u2192 ' + who(ev.toId);
|
||||
else if (ev.type === 'MemberActivated' && mode === 'all') line = '\u{1F91D} ' + who(ev.id) + ' switched on payouts';
|
||||
if (!line) return;
|
||||
const text = line + ' \u00b7 <a href="' + tx + '">verify</a>' + (sc.telegramCtaUrl ? '\n<a href="' + sc.telegramCtaUrl + '">Join free</a>' : '');
|
||||
await telegramSend(sc.telegramChatId, text, sc.telegramTopicId);
|
||||
if (!line) return null;
|
||||
return line + ' \u00b7 <a href="' + tx + '">verify</a>' + (sc.telegramCtaUrl ? '\n<a href="' + sc.telegramCtaUrl + '">Join free</a>' : '');
|
||||
};
|
||||
if (sc.telegramChatId) { const t = build(String(sc.telegramEvents || 'payouts')); if (t) await telegramSend(sc.telegramChatId, t, sc.telegramTopicId); }
|
||||
if (sc.telegramEchoChatId) { const t = build(String(sc.telegramEchoEvents || 'payouts')); if (t) await telegramSend(sc.telegramEchoChatId, '\u{1F7E0} <b>InstantAdPay</b> \u00b7 ' + t, sc.telegramEchoTopicId); }
|
||||
}
|
||||
// one sendMessage call; never throws, never logs the token
|
||||
async function telegramSend(chatId, text, threadId) {
|
||||
|
||||
Reference in New Issue
Block a user