Switch to Listmonk public subscription API for double opt-in

The admin API creates subscribers but doesn't trigger opt-in emails.
Use /api/public/subscription instead — no auth needed, triggers
confirmation email automatically. Removes API token from env vars.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-04-03 13:11:27 -07:00
parent 9c82616d0f
commit a9e79c6f91
2 changed files with 7 additions and 17 deletions

View File

@ -23,9 +23,7 @@ services:
- SMTP_PASS=rMailRelay2026!svc - SMTP_PASS=rMailRelay2026!svc
- SMTP_FROM=orders@katheryntrenshaw.com - SMTP_FROM=orders@katheryntrenshaw.com
- LISTMONK_API_URL=https://newsletter.jeffemmett.com - LISTMONK_API_URL=https://newsletter.jeffemmett.com
- LISTMONK_API_USER=api-frontend - LISTMONK_LIST_UUID=19f972ad-7286-49c2-952d-36f52718b58a
- LISTMONK_API_TOKEN=a875fb47eeb4b7fa973725eb8fca8f7b6590f917d910e26bf06e3e1c9386f710
- LISTMONK_LIST_ID=3
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
# Staging # Staging

View File

@ -2,9 +2,7 @@ import { NextRequest, NextResponse } from 'next/server';
import { sendSubscribeNotification } from '@/lib/email'; import { sendSubscribeNotification } from '@/lib/email';
const LISTMONK_API_URL = process.env.LISTMONK_API_URL; const LISTMONK_API_URL = process.env.LISTMONK_API_URL;
const LISTMONK_API_USER = process.env.LISTMONK_API_USER; const LISTMONK_LIST_UUID = process.env.LISTMONK_LIST_UUID;
const LISTMONK_API_TOKEN = process.env.LISTMONK_API_TOKEN;
const LISTMONK_LIST_ID = parseInt(process.env.LISTMONK_LIST_ID || '3');
export async function POST(request: NextRequest) { export async function POST(request: NextRequest) {
try { try {
@ -15,20 +13,14 @@ export async function POST(request: NextRequest) {
return NextResponse.json({ error: 'Email is required' }, { status: 400 }); return NextResponse.json({ error: 'Email is required' }, { status: 400 });
} }
// If Listmonk is configured, add subscriber there // If Listmonk is configured, use public subscription API (triggers double opt-in)
if (LISTMONK_API_URL && LISTMONK_API_USER && LISTMONK_API_TOKEN) { if (LISTMONK_API_URL && LISTMONK_LIST_UUID) {
const res = await fetch(`${LISTMONK_API_URL}/api/subscribers`, { const res = await fetch(`${LISTMONK_API_URL}/api/public/subscription`, {
method: 'POST', method: 'POST',
headers: { headers: { 'Content-Type': 'application/json' },
'Content-Type': 'application/json',
'Authorization': `token ${LISTMONK_API_USER}:${LISTMONK_API_TOKEN}`,
},
body: JSON.stringify({ body: JSON.stringify({
email, email,
name: '', list_uuids: [LISTMONK_LIST_UUID],
lists: [LISTMONK_LIST_ID],
status: 'enabled',
preconfirm_subscriptions: false,
}), }),
}); });