Newsletter opt-in: silent Sendy subscribe on join

Pre-checked "InstantAdPay newsletter" opt-in on the join screen (read by both the
email-code and password signup paths). On new-account creation only, the server
silently subscribes them to the Sendy "InstantAdPay Newsletter" list
(boolean=true, opt-out always wins). New sendy.js helper reads the API key from
SENDY_API_KEY env or DATA_DIR/sendy.key on the volume (same pattern as
sendgrid.key); subscribe is fire-and-forget and never blocks signup.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
martbost
2026-09-08 07:13:50 -05:00
parent 8ec6286ff7
commit 8d9f56f68a
4 changed files with 48 additions and 3 deletions
+3
View File
@@ -10,6 +10,7 @@ const dns = require('dns');
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const sendy = require('./sendy');
const { URL } = require('url');
const chain = require('./chain');
const auth = require('./auth');
@@ -408,6 +409,7 @@ const server = http.createServer(async (req, res) => {
const r = await accounts.signup(b.email, b.password, ref);
if (r.error) return json(res, 400, r);
nudgeReferrer(ref).catch(() => {});
if (b.newsletter) sendy.subscribe(r.account.email, r.account.username || '').catch(() => {}); // pre-checked opt-in, silent
const token = await auth.mintSession({ email: r.account.email });
return json(res, 200, { ok: true, account: r.account }, { 'Set-Cookie': auth.sessionCookie(token) });
}
@@ -453,6 +455,7 @@ const server = http.createServer(async (req, res) => {
const r = await accounts.ensure(e, ref); // first touch wins; existing accounts unchanged
if (r.error) return json(res, 400, r);
if (r.created) { nudgeReferrer(ref).catch(() => {}); sendWelcome(e, ref).catch(() => {}); }
if (r.created && b.newsletter) sendy.subscribe(r.account.email, r.account.username || '').catch(() => {}); // pre-checked opt-in, silent, new joins only
let memberId = 0;
if (r.account.address) { try { memberId = await chain.memberIdByAccount(r.account.address); } catch (err) {} }
const token = await auth.mintSession({ email: r.account.email, address: r.account.address, memberId });