Skip to main content

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 SENDING when the queue dispatch begins.

Architecture & Services

CampaignService

Responsible for campaign lifecycle and coordination:

Creating a campaign

  • Maps request data to Campaign entity using CampaignMapper.
  • Generates CampaignRecipient entities with unique tracking IDs.
  • Appends tracking pixels to HTML content for each recipient.
  • Sets campaign status:
    • DRAFT (default)
    • SCHEDULED (if scheduledAt is set)
  • Schedules the campaign using CampaignScheduler.

Launching a campaign

  • Checks for scheduled time.
  • Uses MailCowApiClient to 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 MailRequest objects into RabbitMQ queues.
  • Supports delayed delivery for retry and load balancing.
  • Works together with CampaignService to manage bulk sending efficiently.

SmtpCredentials

  • Stores SMTP username, encrypted password, host, and port for each mailbox.
  • Used by MailCowApiClient to authenticate outgoing emails.

Workflow Example: Campaign Sending

  1. Admin/User creates campaign

    • Assign project, domain, mailbox.
    • Add recipients.
    • HTML content is appended with tracking pixel per recipient.
  2. Campaign is scheduled or sent immediately

    • Scheduled campaigns use CampaignScheduler.
    • Immediate campaigns use MailCowApiClient.sendCampaignWithQueue.
  3. Queue-based sending

    • Each recipient email is sent via RabbitMQ queue.
    • Delays prevent server overload.
    • Retry mechanism ensures reliability.
  4. 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:

  • CampaignCampaignRecipientClients
  • CampaignProjectUser
  • CampaignDomain
  • CampaignMailboxSmtpCredentials

Mailing Service ERD