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_ENABLEDflag - 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¶
- Email Sent - Campaign email sent via API
- Create Subscriber - POST
/api/subscribers - Email, name from user
- Status:
enabled - Get/Create List - GET/POST
/api/lists - List name: Campaign name
- Type:
publicorprivate - Subscribe to List - PUT
/api/subscribers/:id/lists - Add subscriber to campaign list
Location Sync¶
- Location Created - New location added
- Get/Create List - List name: Location name/city
- Sync Users - All users in location → list
User Role Sync¶
- User Registration - New user account
- Get Role List -
SUPER_ADMIN,INFLUENCE_ADMIN, etc. - 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¶
- Check
LISTMONK_SYNC_ENABLED=true - Verify
LISTMONK_API_URLreachable - Confirm API user created
- Test credentials with curl
Sync Failures¶
- Check logs for errors
- Verify Listmonk database
- Test API connection
- Reinitialize if needed