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_FROM=orders@katheryntrenshaw.com
- LISTMONK_API_URL=https://newsletter.jeffemmett.com
- LISTMONK_API_USER=api-frontend
- LISTMONK_API_TOKEN=a875fb47eeb4b7fa973725eb8fca8f7b6590f917d910e26bf06e3e1c9386f710
- LISTMONK_LIST_ID=3
- LISTMONK_LIST_UUID=19f972ad-7286-49c2-952d-36f52718b58a
labels:
- "traefik.enable=true"
# Staging

View File

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