Close the conversion loop: member ID submission with Hermes Telegram notify
- Start page step 6 is now a bold gold-highlighted "Submit your NEW RM Circle ID" form with larger step numbers throughout; captures the sponsor the visitor was shown at join time. - POST /api/public/submit-id: validates numeric ID, dedupes, stores on the volume, records a per-source "purchase" analytics event, fires a BeMob postback (txid=purchase-<clickid>) to close paid campaigns, and posts the new ID + sponsor + source to the configured Telegram chat (MB Hermes pattern). Rate-limited. - Admin: Member ID Submissions table, "Confirmed joins" tile, and Telegram bot token / chat ID settings. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+18
-1
@@ -23,7 +23,24 @@ async function load(){
|
||||
document.getElementById('copyButton').classList.add('hidden');
|
||||
}
|
||||
}
|
||||
document.getElementById('joinButton').addEventListener('click',()=>{fetch('/api/public/join-click',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({source:window.ctbGetSource?window.ctbGetSource():'(direct)',clickid:window.ctbGetClickId?window.ctbGetClickId():''})}).catch(()=>{})});
|
||||
document.getElementById('joinButton').addEventListener('click',()=>{try{if(currentSponsor)sessionStorage.setItem('ctb.joinedSponsor',currentSponsor.id)}catch(e){};fetch('/api/public/join-click',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({source:window.ctbGetSource?window.ctbGetSource():'(direct)',clickid:window.ctbGetClickId?window.ctbGetClickId():''})}).catch(()=>{})});
|
||||
document.getElementById('idSubmitForm').addEventListener('submit',async e=>{
|
||||
e.preventDefault();
|
||||
const form=e.currentTarget,input=form.elements.newId,msg=document.getElementById('idSubmitMsg');
|
||||
const newId=input.value.trim();
|
||||
if(!/^[0-9]{1,10}$/.test(newId)){msg.style.color='var(--danger)';msg.textContent='Numbers only — the ID shown by the RM Circle dApp.';return}
|
||||
let joinedSponsor='';try{joinedSponsor=sessionStorage.getItem('ctb.joinedSponsor')||''}catch(e){}
|
||||
const sponsorId=joinedSponsor||(currentSponsor?currentSponsor.id:'?');
|
||||
msg.style.color='var(--muted)';msg.textContent='Submitting…';
|
||||
try{
|
||||
const r=await fetch('/api/public/submit-id',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({newId,sponsorId,source:window.ctbGetSource?window.ctbGetSource():'(direct)',clickid:window.ctbGetClickId?window.ctbGetClickId():''})});
|
||||
const d=await r.json();
|
||||
if(!r.ok)throw new Error(d.error||'Submission failed');
|
||||
form.classList.add('hidden');
|
||||
msg.style.color='var(--ok)';
|
||||
msg.innerHTML=d.duplicate?`✓ ID <strong>${newId}</strong> was already submitted — you're on the list.`:`✓ Got it! ID <strong>${newId}</strong> is submitted under sponsor ID <strong>${sponsorId}</strong>. The team has been notified and you'll be added to the rotation.`;
|
||||
}catch(x){msg.style.color='var(--danger)';msg.textContent=x.message}
|
||||
});
|
||||
document.getElementById('copyButton').addEventListener('click',async()=>{
|
||||
if(!currentSponsor)return; await navigator.clipboard.writeText(currentSponsor.id); const b=document.getElementById('copyButton'); const old=b.textContent;b.textContent='Copied ✓';setTimeout(()=>b.textContent=old,1400)
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user