Skip to main content

Mailchimp / Mandrill Module

Overview

The Mailchimp module provides transactional email capabilities via Mandrill (Mailchimp's transactional email API). It supports two sending modes:

  • Template emails — Uses pre-built Mandrill templates with dynamic merge variables
  • Plain text emails — Sends raw text content

Architecture

The module follows hexagonal architecture with clear layer separation:

mailchimp/
├── domain/
│ ├── mandrill-email.port.ts # Port interface (MandrillEmailPort)
│ └── mandrill.types.ts # Framework-agnostic types
├── application/
│ └── mandrill.service.ts # Use case orchestration
├── infrastructure/
│ ├── mailchimp.providers.ts # SDK client factory + port binding
│ └── mandrill-email.adapter.ts # SDK implementation of MandrillEmailPort
├── interfaces/
│ └── mandrill-event.handler.ts # Event listener (driving adapter)
└── mailchimp.module.ts # NestJS module definition

Dependency Flow

interfaces/ → application/ → domain/ ← infrastructure/
(events) (service) (port) (SDK adapter)
  • Domain defines the MandrillEmailPort contract and framework-agnostic types
  • Application (MandrillService) orchestrates via the port — no SDK dependency
  • Infrastructure (MandrillEmailAdapter) implements the port using the Mandrill SDK
  • Interfaces (MandrillEventHandler) listens for events and delegates to the service

Integration

Event-Driven (Internal)

Other modules can trigger emails by emitting events:

import { MandrillEvents } from "@flowpos-workspace/global/enums/mailchimp.enums";

// Template email
this.eventEmitter.emit(MandrillEvents.SendTransactionEmailTemplate, {
templateId: "welcome-email",
to: [{ email: "user@example.com", name: "John" }],
subject: "Welcome!",
data: { firstName: "John", businessName: "Acme" },
});

// Plain text email
this.eventEmitter.emit(MandrillEvents.SendTransactionEmailPlain, {
to: [{ email: "user@example.com" }],
subject: "Reset code",
content: "Your code is 123456",
});

Direct Injection

Import MailchimpModule and inject MandrillService:

@Module({ imports: [MailchimpModule] })
export class MyModule {}

@Injectable()
export class MyService {
constructor(private readonly mandrillService: MandrillService) {}

async notify() {
await this.mandrillService.sendTemplateEmail({
templateId: "order-confirmation",
to: [{ email: "customer@example.com" }],
subject: "Order Confirmed",
data: { orderId: "12345" },
});
}
}

Configuration

Environment VariableRequiredDescription
MANDRILL_API_KEYYesMandrill API key for transactional emails

Relationship to Communications Module

The communications module uses SendGrid as the primary email provider via EmailAdapterService. The Mandrill module exists as a separate transactional email channel — it is not part of the multi-channel communications pipeline.

Use Mandrill for:

  • System-level transactional emails (invites, password resets, alerts)
  • Template-driven emails managed in the Mandrill dashboard

Use Communications/SendGrid for:

  • Business-initiated customer communications
  • Multi-channel (email + SMS + WhatsApp) workflows
  • Communications with tracking, queuing, and retry logic