diff --git a/.env.example b/.env.example index 4573bd6d..ca630513 100644 --- a/.env.example +++ b/.env.example @@ -17,6 +17,9 @@ SESSION_SECRET=change-this-to-a-random-string # Admin email (user with this email gets admin privileges) ADMIN_EMAIL=scott.mccarty@gmail.com +# Newsletter sends (set to false for dev/test to avoid duplicate Buttondown emails) +NEWSLETTER_SEND_ENABLED=false + # Test environment (set automatically by vitest.config.js) # NODE_ENV=test # BYPASS_AUTH=true diff --git a/backend/services/buttondownClient.js b/backend/services/buttondownClient.js index c78e3267..a45a84a5 100644 --- a/backend/services/buttondownClient.js +++ b/backend/services/buttondownClient.js @@ -2,6 +2,10 @@ import axios from 'axios'; const BUTTONDOWN_API_BASE = 'https://api.buttondown.email'; +function isSendEnabled() { + return process.env.NEWSLETTER_SEND_ENABLED !== 'false'; +} + let apiKeyCache = null; async function getApiKey(pool) { @@ -82,6 +86,11 @@ async function retryRequest(requestFn, maxRetries = 3) { } export async function addSubscriber(email, pool = null) { + if (!isSendEnabled()) { + console.log('Newsletter send disabled (NEWSLETTER_SEND_ENABLED=false), skipping addSubscriber'); + return { email, status: 'send_disabled', skipped: true }; + } + const apiKey = await getApiKey(pool); const client = createClient(apiKey); @@ -141,6 +150,11 @@ export async function getSubscriberCount(pool = null) { } export async function sendEmail(subject, htmlBody, pool = null, { existingEmailId, onDraftCreated } = {}) { + if (!isSendEnabled()) { + console.log('Newsletter send disabled (NEWSLETTER_SEND_ENABLED=false), skipping sendEmail'); + return { skipped: true, reason: 'send_disabled' }; + } + const apiKey = await getApiKey(pool); let emailId; @@ -205,6 +219,11 @@ export async function sendEmail(subject, htmlBody, pool = null, { existingEmailI } export async function sendDraftToRecipients(subject, htmlBody, recipients, pool = null) { + if (!isSendEnabled()) { + console.log('Newsletter send disabled (NEWSLETTER_SEND_ENABLED=false), skipping sendDraftToRecipients'); + return { emailId: null, skipped: true, reason: 'send_disabled' }; + } + const apiKey = await getApiKey(pool); const client = createClient(apiKey); diff --git a/run.sh b/run.sh index 8aa63edf..58a25049 100755 --- a/run.sh +++ b/run.sh @@ -37,6 +37,7 @@ ENV_ARGS="" [ -n "$PGUSER" ] && ENV_ARGS="$ENV_ARGS -e PGUSER=$PGUSER" [ -n "$PGPASSWORD" ] && ENV_ARGS="$ENV_ARGS -e PGPASSWORD=$PGPASSWORD" [ -n "$PGDATABASE" ] && ENV_ARGS="$ENV_ARGS -e PGDATABASE=$PGDATABASE" +[ -n "$NEWSLETTER_SEND_ENABLED" ] && ENV_ARGS="$ENV_ARGS -e NEWSLETTER_SEND_ENABLED=$NEWSLETTER_SEND_ENABLED" case "${1:-help}" in build-base) @@ -165,6 +166,7 @@ MCP_ADMIN_TOKEN=$MCP_ADMIN_TOKEN PGUSER=${PGUSER:-postgres} PGPASSWORD=${PGPASSWORD:-rotv} PGDATABASE=${PGDATABASE:-rotv} +NEWSLETTER_SEND_ENABLED=${NEWSLETTER_SEND_ENABLED:-false} ENVFILE fi