Add a newsletter archive so past issues can be shared and found; v2.3.0
Publish Container / build (push) Successful in 20m51s
Publish Container / build (push) Successful in 20m51s
Web-hosted copies of episode newsletters, published from Resend broadcasts tagged with the "New Episode" topic. Gives Facebook (and anyone else) a proper link to share instead of raw HTML email, and makes issues findable via site search and Google. - Admin "Newsletter Archive" tab lists sent Resend broadcasts, flags ones tagged "New Episode", and publishes them with one click (pulls the HTML straight from Resend's API) - Public /newsletter archive index and /newsletter/:slug issue pages, server-rendered with per-issue Open Graph tags for social previews - Unsubscribe merge-tag stripped from the web copy; archive + subscribe links appended - Issues added to sitemap.xml and the on-site search index Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
60b23b0fba
commit
fe4c09f8a3
11 files changed
+516
-4
No files matched your search
@@ -35,6 +35,7 @@ import {
|
||||
AUDIT_LOG_FILE,
|
||||
WEBHOOKS_FILE,
|
||||
STUDY_SESSIONS_FILE,
|
||||
NEWSLETTER_ISSUES_FILE,
|
||||
EMPTY_HIT_STATS,
|
||||
EMPTY_VISITOR_STATS,
|
||||
DEFAULT_REPLY_TEMPLATES,
|
||||
@@ -1673,3 +1674,27 @@ export function loadQrCodesFromDisk() {
|
||||
state.qrScans = []
|
||||
})
|
||||
}
|
||||
|
||||
// ── Newsletter Issues ────────────────────────────────────────────────────────
|
||||
|
||||
export function queueNewsletterIssuesWrite() {
|
||||
state.newsletterIssuesWritePromise = state.newsletterIssuesWritePromise
|
||||
.then(async () => {
|
||||
await mkdir(DATA_DIR, { recursive: true })
|
||||
await writeFile(NEWSLETTER_ISSUES_FILE, JSON.stringify({ issues: state.newsletterIssues }, null, 2), 'utf8')
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('[newsletter-issues] failed to write:', err)
|
||||
})
|
||||
}
|
||||
|
||||
export function loadNewsletterIssuesFromDisk() {
|
||||
return readFile(NEWSLETTER_ISSUES_FILE, 'utf8')
|
||||
.then(raw => {
|
||||
const parsed = JSON.parse(raw)
|
||||
state.newsletterIssues = Array.isArray(parsed?.issues) ? parsed.issues : []
|
||||
})
|
||||
.catch(() => {
|
||||
state.newsletterIssues = []
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user