From 88aad3106c271d68eb4bfba441a3fd286752e789 Mon Sep 17 00:00:00 2001 From: "planetrenox@protonmail.com" Date: Thu, 8 Oct 2026 02:18:08 +0000 Subject: [PATCH] Feat: Use newsletter.planetrenox.com for sub/unsub (lynchmark pool) Subscribe form now posts to newsletter.planetrenox.com/api/sub with a Turnstile token; unsubscribe posts to /api/unsub. Drops the old Resend Pages functions. Co-Authored-By: Claude Opus 5.5 --- blog/lynchmark-newsletter-experiment.html | 11 ++++++--- functions/api/subscribe.js | 30 ----------------------- functions/api/unsubscribe.js | 27 -------------------- unsubscribe.html | 2 +- 4 files changed, 9 insertions(+), 61 deletions(-) delete mode 100644 functions/api/subscribe.js delete mode 100644 functions/api/unsubscribe.js diff --git a/blog/lynchmark-newsletter-experiment.html b/blog/lynchmark-newsletter-experiment.html index aab145a..72727fc 100644 --- a/blog/lynchmark-newsletter-experiment.html +++ b/blog/lynchmark-newsletter-experiment.html @@ -36,6 +36,7 @@
+
@@ -43,19 +44,23 @@
Public Domain
+ diff --git a/functions/api/subscribe.js b/functions/api/subscribe.js deleted file mode 100644 index e9cef98..0000000 --- a/functions/api/subscribe.js +++ /dev/null @@ -1,30 +0,0 @@ -export async function onRequestPost({ request, env }) { - const { email } = await request.json().catch(() => ({})); - if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) - return new Response('{"error":"Invalid email"}', { status: 400, headers: { 'Content-Type': 'application/json' } }); - - const c = request.cf || {}; - const geo = [c.city, c.region, c.country].filter(Boolean).join(', ') || 'Unknown'; - - const res = await fetch('https://api.resend.com/contacts', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${env.RESEND_TOKEN}` - }, - body: JSON.stringify({ email }) - }); - - if (!res.ok) { - const text = await res.text(); - return new Response(`{"error":"Resend error: ${text}"}`, { status: 500, headers: { 'Content-Type': 'application/json' } }); - } - - await fetch(env.NTFY_URL, { - method: 'POST', - headers: { Priority: '3', Title: `📬 ${geo}` }, - body: email - }); - - return new Response('{"ok":true}', { headers: { 'Content-Type': 'application/json' } }); -} diff --git a/functions/api/unsubscribe.js b/functions/api/unsubscribe.js deleted file mode 100644 index c168af0..0000000 --- a/functions/api/unsubscribe.js +++ /dev/null @@ -1,27 +0,0 @@ -export async function onRequestPost({ request, env }) { - const { email } = await request.json().catch(() => ({})); - if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) - return new Response('{"error":"Invalid email"}', { status: 400, headers: { 'Content-Type': 'application/json' } }); - - const res = await fetch('https://api.resend.com/contacts', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${env.RESEND_TOKEN}` - }, - body: JSON.stringify({ email, unsubscribed: true }) - }); - - if (!res.ok) { - const text = await res.text(); - return new Response(`{"error":"Resend error: ${text}"}`, { status: 500, headers: { 'Content-Type': 'application/json' } }); - } - - await fetch(env.NTFY_URL, { - method: 'POST', - headers: { Priority: '3', Title: `🔕 Unsubscribe` }, - body: email - }); - - return new Response('{"ok":true}', { headers: { 'Content-Type': 'application/json' } }); -} diff --git a/unsubscribe.html b/unsubscribe.html index 46a367f..999bb76 100644 --- a/unsubscribe.html +++ b/unsubscribe.html @@ -41,7 +41,7 @@ msg.textContent='Processing...'; msg.classList.remove('hidden'); try{ - const r=await fetch('/api/unsubscribe',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({email:document.getElementById('email').value})}); + const r=await fetch('https://newsletter.planetrenox.com/api/unsub',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({pool:'lynchmark',email:document.getElementById('email').value})}); const d=await r.json(); if(d.ok){msg.textContent='✓ Unsubscribed';msg.className='text-center text-sm text-green-600';} else{msg.textContent=d.error||'Error';msg.className='text-center text-sm text-red-600';}