Mailing Service
The Mailing Service in Ulmexa is a comprehensive backend system responsible for managing email campaigns, transactional emails, mailbox management, and email tracking. It integrates tightly with Mailcow as the mail provider and leverages a queue system for campaign sending to ensure reliability, retries, and scheduling.
This document explains the architecture, main services, and features of the mailing service.
Core Features
Campaign Management
- Create, update, schedule, and delete email campaigns.
- Assign campaigns to projects, domains, and sending mailboxes.
- Attach a list of recipients (Clients) for each campaign.
- Append a tracking pixel to each recipient’s email for open tracking.
- Support immediate or scheduled sending via
CampaignScheduler.
Mailbox Management
- Create, update, and delete mailboxes.
- Automatically provision mailboxes via Mailcow API.
- Manage per-mailbox SMTP credentials stored in
SmtpCredentials. - Enforce mailbox features like TLS, quotas, and forced password updates.
Domain Management
- Create, update, and delete domains through Mailcow.
- Configure domain attributes such as aliases, quotas, relay settings, and tags.
- Maintain a local repository for domains (
DomainRepository) for internal reference.
SMTP Sending
- Supports sending transactional emails and campaign emails.
- Uses per-mailbox SMTP credentials to send emails directly from user domains.
- Implements a JavaMail session with authentication and STARTTLS for secure email sending.
- Logs delivery attempts and errors for reliability.
Campaign Tracking
- Each campaign recipient gets a unique tracking ID.
- HTML emails are dynamically appended with a tracking pixel via
TrackingService. - Open tracking is recorded per recipient.
Queue-Based Sending
- Integrates with RabbitMQ (via
MailQueueProducer) for queued campaign sending. - Supports delayed retries to prevent server overload (patterns like 2s, 5s, 10s).
- Updates campaign status to
SENDINGwhen the queue dispatch begins.
Architecture & Services
CampaignService
Responsible for campaign lifecycle and coordination:
Creating a campaign
- Maps request data to
Campaignentity usingCampaignMapper. - Generates
CampaignRecipiententities with unique tracking IDs. - Appends tracking pixels to HTML content for each recipient.
- Sets campaign status:
DRAFT(default)SCHEDULED(ifscheduledAtis set)
- Schedules the campaign using
CampaignScheduler.
Launching a campaign
- Checks for scheduled time.
- Uses
MailCowApiClientto send emails directly or through the queue.
Updating a campaign
- Prevents editing sent campaigns.
- Updates recipients and content while resetting the status to
DRAFT.
Deleting a campaign
- Prevents deletion of already sent campaigns.
Retrieving campaigns
- Fetch all campaigns or filter by user.
MailCowApiClient (implements IMailProviderClient)
Handles integration with Mailcow API:
Domain Operations
- Create, update, delete, and fetch domains.
Mailbox Operations
- Create, update, delete, and fetch mailboxes.
- Configure mailbox-specific attributes like TLS, quota, password, and display name.
SMTP Sending
- Retrieves SMTP credentials for a mailbox.
- Uses JavaMail to send transactional or campaign emails.
- Supports HTML email content.
Campaign Sending
sendCampaign: Sends emails to all recipients immediately.sendCampaignWithQueue: Sends emails via queue with delay and retry support.- Updates campaign status and timestamp after sending.
TrackingService
- Generates unique tracking URLs for each recipient.
- Appends tracking pixels to HTML email content.
- Provides insight into email opens per campaign.
CampaignScheduler
- Schedules campaigns for future delivery.
- Integrates with delayed queue sending.
- Ensures campaigns execute at the intended time.
MailQueueProducer
- Pushes
MailRequestobjects into RabbitMQ queues. - Supports delayed delivery for retry and load balancing.
- Works together with
CampaignServiceto manage bulk sending efficiently.
SmtpCredentials
- Stores SMTP username, encrypted password, host, and port for each mailbox.
- Used by
MailCowApiClientto authenticate outgoing emails.
Workflow Example: Campaign Sending
-
Admin/User creates campaign
- Assign project, domain, mailbox.
- Add recipients.
- HTML content is appended with tracking pixel per recipient.
-
Campaign is scheduled or sent immediately
- Scheduled campaigns use
CampaignScheduler. - Immediate campaigns use
MailCowApiClient.sendCampaignWithQueue.
- Scheduled campaigns use
-
Queue-based sending
- Each recipient email is sent via RabbitMQ queue.
- Delays prevent server overload.
- Retry mechanism ensures reliability.
-
Tracking
- Tracking pixels log opens and interactions per recipient.
- Analytics can be retrieved using
trackingService.
Important Notes
Safety checks
- Cannot edit or delete sent campaigns.
- Each client must have a valid email.
Retry logic
- Failed sends can be retried with delays.
- Dead-letter queues can capture permanently failed emails.
Transactional emails
- Example: VPS ready notifications sent via
sendVpsReadyEmail.
Dependencies
- Spring Boot: Service annotations and dependency injection.
- Spring Data JPA: Repositories for Campaign, Mailbox, Domain, Clients, and Users.
- JavaMail API: Email sending.
- RabbitMQ: Queueing and delayed retries.
- Mailcow API: Domain and mailbox provisioning.
- AES Encryption Utility: Secure storage of SMTP credentials.
ERD Overview
The mailing service interacts with the following entities:
Campaign↔CampaignRecipient↔ClientsCampaign↔Project↔UserCampaign↔DomainCampaign↔Mailbox↔SmtpCredentials
