Member updates: closing text after the notes (sign-off placement)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
+3
-2
@@ -33,12 +33,13 @@ async function recipients(kind) {
|
||||
}
|
||||
async function counts() { const o = {}; for (const k of Object.keys(AUDIENCES)) o[k] = (await recipients(k)).length; return o; }
|
||||
|
||||
function compose({ subject, intro, noteIds }, acct) {
|
||||
function compose({ subject, intro, noteIds, closing }, acct) {
|
||||
const notes = R.releases.notes().filter(n => noteIds.includes(n.id));
|
||||
const name = acct && acct.username ? '@' + acct.username : 'there';
|
||||
const parts = ['Hi ' + name + ','];
|
||||
if (intro && intro.trim()) parts.push(intro.trim());
|
||||
for (const n of notes) parts.push(n.title.toUpperCase() + (n.date ? ' (' + n.date + ')' : '') + '\n' + String(n.body || '').trim());
|
||||
if (closing && closing.trim()) parts.push(closing.trim()); // sign-off AFTER the notes (Marty, 2026-09-14)
|
||||
parts.push('Every release note and what is being built next: ' + SITE + '/whats-new');
|
||||
parts.push('Sign in: ' + SITE + '/my');
|
||||
parts.push('InstantAdPay\nAdvertise and earn instantly. Locked in code, not promises.\nNo income is guaranteed; results depend on your effort. Cryptocurrency carries risk.');
|
||||
@@ -82,7 +83,7 @@ async function send(input, opts) {
|
||||
// one saved draft (subject, intro, noteIds, audience): the admin card loads it, Save draft writes it
|
||||
const DRAFT = () => path.join(R.dataDir, 'updates-draft.json');
|
||||
function draft() { try { return JSON.parse(fs.readFileSync(DRAFT(), 'utf8')); } catch (e) { return null; } }
|
||||
function saveDraft(d) { const v = { subject: String(d.subject || '').slice(0, 150), intro: String(d.intro || '').slice(0, 8000), noteIds: (d.noteIds || []).map(String).slice(0, 40), audience: AUDIENCES[d.audience] ? d.audience : 'optin', savedAt: Date.now() }; try { fs.writeFileSync(DRAFT(), JSON.stringify(v)); } catch (e) {} return v; }
|
||||
function saveDraft(d) { const v = { subject: String(d.subject || '').slice(0, 150), intro: String(d.intro || '').slice(0, 8000), closing: String(d.closing || '').slice(0, 2000), noteIds: (d.noteIds || []).map(String).slice(0, 40), audience: AUDIENCES[d.audience] ? d.audience : 'optin', savedAt: Date.now() }; try { fs.writeFileSync(DRAFT(), JSON.stringify(v)); } catch (e) {} return v; }
|
||||
function status() { const l = log(); if (running) { const k = l.sends.find(x => x.id === running.id); if (k) Object.assign(k, running); } return { sends: l.sends.slice(0, 12), running: !!running }; }
|
||||
function lastSentAt() { const l = log(); const d = l.sends.find(x => x.status === 'done'); return d ? d.ts : 0; }
|
||||
module.exports = { init, AUDIENCES, counts, compose, send, status, lastSentAt, draft, saveDraft };
|
||||
|
||||
Reference in New Issue
Block a user