7.9 KiB

Newsletter Integration (Listmonk)

The Newsletter Integration provides automated synchronization between Changemaker Lite and Listmonk newsletter platform. Campaign participants, volunteers, and locations can be automatically synced to Listmonk lists for targeted email campaigns.

Overview

The Listmonk integration provides:

  • Opt-in Sync - Controlled by LISTMONK_SYNC_ENABLED flag
  • Automatic Subscriber Creation - Campaign participants → subscribers
  • List Management - Campaigns → lists, Locations → lists
  • User Role Sync - User roles → list assignment
  • Bi-directional Updates - Keep data synchronized
  • Admin Interface - Manual sync controls and monitoring

Features

Subscriber Sync

Automatically sync users to Listmonk:

  • Campaign Participants - Email senders become subscribers
  • Shift Signups - Volunteers added to lists
  • Response Submitters - Response wall participants
  • Manual Users - User role-based list assignment

List Management

Auto-create and manage lists:

  • Campaign Lists - One list per campaign
  • Location Lists - One list per geographic area
  • Role Lists - Lists for each user role
  • Custom Lists - Admin-defined lists

Sync Triggers

Automatic sync on:

  • Campaign email sent
  • Shift signup
  • Response submission
  • User registration
  • Manual admin trigger

Admin Controls

  • View sync status
  • Manual sync buttons
  • Test connection
  • List statistics
  • Reinitialize lists

Architecture

Backend Components

Listmonk Client:

  • api/src/services/listmonk.client.ts - Typed HTTP client (native fetch)
  • Basic auth integration
  • Full REST API coverage

Listmonk Sync Service:

  • api/src/services/listmonk-sync.service.ts - Sync orchestration
  • Participant → subscriber mapping
  • List creation and management
  • Error handling and logging

Admin Module:

  • api/src/modules/listmonk/listmonk.routes.ts - Admin endpoints
  • Status, stats, sync controls

Database:

  • No new tables (uses existing User, Campaign, Location)
  • Listmonk IDs stored in Prisma models (future)

Frontend Components

Admin Page:

  • admin/src/pages/ListmonkPage.tsx - Newsletter management
  • Connection status display
  • Sync controls
  • List statistics table

Configuration

Environment Variables

# Enable Listmonk sync (opt-in)
LISTMONK_SYNC_ENABLED=true

# Listmonk connection
LISTMONK_API_URL=http://listmonk:9000
LISTMONK_API_USER=api_user
LISTMONK_API_TOKEN=your_api_token

# Web admin credentials (for setup)
LISTMONK_WEB_ADMIN_USER=admin
LISTMONK_WEB_ADMIN_PASSWORD=password

Docker Setup

Listmonk runs as a service in docker-compose.yml:

listmonk:
  image: listmonk/listmonk:latest
  ports:
    - "9001:9000"
  depends_on:
    - listmonk-db
  environment:
    LISTMONK_app__admin_username: ${LISTMONK_WEB_ADMIN_USER}
    LISTMONK_app__admin_password: ${LISTMONK_WEB_ADMIN_PASSWORD}

Initialization

Auto-create API user via listmonk-init container:

INSERT INTO users (email, name, password, type, status, created_at, updated_at)
VALUES (
  '${LISTMONK_API_USER}',
  'API User',
  '${LISTMONK_API_TOKEN}',  -- Plaintext (Listmonk API tokens)
  'api',
  'enabled',
  NOW(),
  NOW()
);

Sync Process

Campaign Participant Sync

  1. Email Sent - Campaign email sent via API
  2. Create Subscriber - POST /api/subscribers
    • Email, name from user
    • Status: enabled
  3. Get/Create List - GET/POST /api/lists
    • List name: Campaign name
    • Type: public or private
  4. Subscribe to List - PUT /api/subscribers/:id/lists
    • Add subscriber to campaign list

Location Sync

  1. Location Created - New location added
  2. Get/Create List - List name: Location name/city
  3. Sync Users - All users in location → list

User Role Sync

  1. User Registration - New user account
  2. Get Role List - SUPER_ADMIN, INFLUENCE_ADMIN, etc.
  3. Subscribe User - Add to role-based list

API Integration

Listmonk Client Usage

import { listmonkClient } from '../services/listmonk.client';

// Create subscriber
const subscriber = await listmonkClient.createSubscriber({
  email: 'user@example.com',
  name: 'User Name',
  status: 'enabled',
  lists: [listId],
});

// Get/Create list
let list = await listmonkClient.getListByName('Campaign Name');
if (!list) {
  list = await listmonkClient.createList({
    name: 'Campaign Name',
    type: 'public',
    optin: 'double',
  });
}

// Subscribe to list
await listmonkClient.subscribeToList(subscriberId, [listId]);

Sync Service Usage

import { listmonkSyncService } from '../services/listmonk-sync.service';

// Sync campaign participant
await listmonkSyncService.syncCampaignParticipant(
  campaign.id,
  user.email,
  user.name
);

// Sync all participants
await listmonkSyncService.syncAllParticipants(campaign.id);

// Sync location members
await listmonkSyncService.syncLocationMembers(location.id);

Admin Interface

Connection Status

Display:

  • Connected/disconnected status
  • Listmonk version
  • API endpoint
  • Last sync time

Sync Controls

Buttons:

  • Sync All Participants - Sync all campaign participants
  • Sync All Locations - Sync all location members
  • Test Connection - Verify API access
  • Reinitialize - Reset lists and subscribers

List Statistics

Table showing:

  • List name
  • Subscriber count
  • Campaign/location association
  • Last updated time

Security

API Authentication

Listmonk v6+ requires auth on all endpoints:

const headers = {
  'Authorization': `Basic ${btoa(`${apiUser}:${apiToken}`)}`,
  'Content-Type': 'application/json',
};

Token Storage

API tokens stored as plaintext in Listmonk DB:

  • Not bcrypt hashed
  • Direct upsert possible
  • Secure via Redis authentication

Data Privacy

  • Opt-in sync only
  • User consent required (future)
  • Unsubscribe support
  • Data deletion on request

Error Handling

Sync Failures

Handled gracefully:

  • Network errors logged
  • Failed syncs retried
  • Admin notifications
  • Error statistics

Rate Limiting

Respect Listmonk limits:

  • Batch operations
  • Delay between requests
  • Queue large syncs

Listmonk Features

Campaign Management

Listmonk provides:

  • Email campaign creation
  • Template management
  • Scheduling
  • A/B testing
  • Analytics

Subscriber Management

  • Import/export subscribers
  • List segmentation
  • Tags and attributes
  • Bounce handling
  • Unsubscribe management

Analytics

  • Open rates
  • Click rates
  • Bounce rates
  • Unsubscribe rates
  • Campaign reports

API Endpoints

Admin Endpoints

GET    /api/listmonk/status            # Connection status
GET    /api/listmonk/stats             # Sync statistics
POST   /api/listmonk/sync-participants # Sync campaign participants
POST   /api/listmonk/sync-locations    # Sync location members
POST   /api/listmonk/test-connection   # Test API connection
POST   /api/listmonk/reinitialize      # Reset and reinitialize

Limitations

Current Limitations

  • Listmonk v6+ only (auth required on all endpoints)
  • No webhook support (future)
  • Manual sync triggers
  • No bi-directional sync (Listmonk → CM Lite)

Future Enhancements

  • Webhook integration
  • Real-time sync
  • Custom field mapping
  • Advanced segmentation
  • Campaign stats in CM Lite

Troubleshooting

Connection Issues

  1. Check LISTMONK_SYNC_ENABLED=true
  2. Verify LISTMONK_API_URL reachable
  3. Confirm API user created
  4. Test credentials with curl

Sync Failures

  1. Check logs for errors
  2. Verify Listmonk database
  3. Test API connection
  4. Reinitialize if needed