Marketing Campaigns Technical Documentation
This document provides a comprehensive technical overview of the WhatsApp marketing campaigns feature implementation, including the architecture, data flows, and key components.Architecture Overview
The marketing campaigns feature is built on a multi-layered architecture following Domain-Driven Design (DDD) principles:Core Components
1. Domain Entities
TemplateMessage Entity
Located at:src/domain/entities/message/template/template-message.entity.ts
- Represents WhatsApp message templates
- Contains header, body, footer, and buttons configuration
- Manages template status (pending, approved, rejected)
- Stores Dialog API identifiers and WABA ID
MarketingCampaign Entity
Located at:src/domain/entities/marketing-campaign/marketing-campaign.entity.ts
- Represents a marketing campaign instance
- Links to a TemplateMessage
- Stores nexus instructions and variable definitions
- Manages campaign status (draft, pending, accepted, sent, closed)
- Contains campaign statistics (sent, delivered, read counts)
MarketingMessage Entity
Located at:src/domain/entities/marketing-message/marketing-message.entity.ts
- Represents individual messages within a campaign
- Stores recipient information and message status
- Contains resolved template variables
- Tracks delivery and read receipts
2. Application Layer - Use Cases
CreateTemplateMessageByEntityUsecase
Purpose: Creates WhatsApp message templates for locations or business organizations Flow:- Validates entity (location/business organization) exists
- Checks WhatsApp integration is configured
- Calls 360dialog API to create template
- Stores template in database with Dialog ID
- Returns created template
TEMPLATE_VALIDATION_ERROR: Invalid input dataTEMPLATE_LOCATION_NOT_FOUND: Location doesn’t existTEMPLATE_WHATSAPP_NOT_CONFIGURED: No WhatsApp integrationTEMPLATE_WHATSAPP_API_ERROR: 360dialog API failure
CreateWhatsappCampaignUsecase
Purpose: Creates a new marketing campaign Flow:- Validates template message exists and is approved
- Validates entity has WhatsApp integration
- Creates campaign with initial status (draft or accepted based on user role)
- Stores nexus instructions and variable definitions
- Admin-created campaigns are auto-accepted
- Auto-acceptance for admin users
- Variable validation and type checking
- Integration validation
SendMarketingCampaignUsecase
Purpose: Initiates campaign sending to recipients Flow:- Validates campaign is in ‘accepted’ status
- Deduplicates recipient phone numbers
- Enqueues campaign data to BullMQ for processing
- Returns immediately (async processing)
- Emits
marketing.campaign.sentevent
SendMarketingMessageUsecase
Purpose: Sends individual marketing messages Flow:- Creates MarketingMessage record
- Resolves all template variables (reserved + custom)
- Builds Dialog API payload
- Sends via 360dialog
- Updates message status
- Handles conversation initialization
- Reserved variables (e.g.,
customerFirstName) pull from database - Custom variables come from campaign or recipient overrides
- Fallback to default values if not found
3. Infrastructure Layer
MarketingQueue Implementation
Located at:src/infrastructure/queues/marketing.queue.ts
Configuration:
- Queue name:
marketing - Default concurrency: 5
- Retry attempts: 3
- Backoff strategy: Exponential
-
send-campaignJob: Entry point for campaign processing- Receives the entire campaign data with all recipients
- Creates MarketingMessage records in the database
- Splits recipients into batches for processing
- Enqueues individual
send-messagejobs for each recipient - This job doesn’t send any messages directly
-
send-messageJob: Handles individual message sending- Receives a single MarketingMessage ID
- Loads message and related data from database
- Resolves all variables (reserved and custom)
- Calls 360dialog API to send the actual WhatsApp message
- Updates message status (sent, failed, etc.)
- Handles retries on failure
MarketingProcessor
Located at:src/infrastructure/queues/processors/marketing.processor.ts
Detailed Processing Flow:
-
Campaign Job Processing (
processSendCampaign): -
Message Job Processing (
processSendMessage):
DialogClient Integration
Located at:src/infrastructure/services/dialog/client/dialog.client.ts
Key Methods:
template.createTemplateMessage(): Creates templatestemplate.sendTemplateMessage(): Sends messagestemplate.getTemplateStatus(): Checks approval status
4. Frontend Implementation
Marketing Campaign Components
MarketingCampaignsModal- Creates new campaigns
- Variable definition with visual indicators
- Nexus instructions editor
- Template selection
- File upload (CSV/Excel) support
- Automatic column matching
- Variable preview and editing
- Recipient management
-
Reserved Variable Indicators
- Blue badges for database variables
- Tooltips explaining data sources
- Automatic value resolution
-
File Processing
- Supports CSV and Excel formats
- Case-insensitive column matching
- Visual feedback for matched columns
-
Variable Management
- Three types: reserved, file-sourced, manual
- Inline editing capabilities
- Clear visual differentiation
Campaign Acceptance Workflow
Admin Dashboard Integration
The campaign acceptance feature ensures compliance with WhatsApp Business policies and maintains quality standards.Acceptance Flow
-
Campaign Creation:
- Regular users create campaigns with status
draft - Admin users’ campaigns are auto-accepted with status
accepted
- Regular users create campaigns with status
-
Admin Review Dashboard:
- Located at
/admin/campaigns - Shows all campaigns pending approval
- Displays campaign details:
- Template message content
- Variable definitions
- Nexus instructions
- Located at
-
Review Actions:
Approve Campaign (
POST /campaign/:id/approve):Reject Campaign (POST /campaign/:id/reject): -
Compliance Checks:
- Template content appropriateness
- Variable usage correctness
-
Status Transitions:
Admin Dashboard UI Components
Campaign Review Card:- Preview of template message with resolved variables
- Variable mapping visualization
- Nexus instructions preview
- Quick approve/reject buttons
- Rejection reason modal
- Approve multiple campaigns
- Apply consistent rejection reasons
- Filter by location/organization
Data Flow Diagrams
Template Creation Flow
Campaign Sending Flow
Queue Processing Architecture
Why Two Separate Job Types?
The separation betweensend-campaign and send-message jobs provides several architectural benefits:
-
Scalability:
- Campaign jobs are lightweight - they only create database records
- Message jobs can be distributed across multiple workers
- Failed messages don’t block the entire campaign
-
Reliability:
- Individual message failures can be retried independently
- Campaign progress is trackable at the message level
- Partial campaign completion is possible
-
Rate Limiting:
- Messages are spread over time to respect API limits
- Each message has its own delay calculation
- Prevents overwhelming the WhatsApp API
-
Observability:
- Clear separation of concerns for monitoring
- Individual message status tracking
- Detailed error reporting per recipient
Queue Processing Timeline
Queue Processing Details
Rate Limiting
The system implements rate limiting to comply with WhatsApp Business API limits:Error Handling Strategy
Campaign Job Failures:- Retry entire campaign creation
- Idempotent operation (won’t duplicate messages)
- Maximum 3 retries with exponential backoff
- Individual retry per message
- Failed messages marked with error status
- After 3 retries, moved to dead letter queue
- Campaign continues for other recipients
Reserved Variables System
The system supports automatic variable resolution from the database:Supported Reserved Variables
| Variable Name | Database Field | Description |
|---|---|---|
customerFirstName | customer.firstName | Customer’s first name |
customerLastName | customer.lastName | Customer’s last name |
Resolution Process
- Identification: System identifies reserved variables in template
- Customer Lookup: Finds customer by phone number
- Data Extraction: Retrieves values from customer record
- Fallback: Uses default or empty string if not found
CSV and Excel File Import System
The marketing campaign system supports importing recipient data from CSV and Excel files with automatic column matching and variable mapping.File Processing Architecture
Supported Formats
- CSV: Comma, semicolon, or tab-separated values
- Excel: .xlsx and .xls formats (via
xlsxlibrary)
File Parser Implementation
Located at:src/features/whatsapp/utils/file-parser.ts
Core Functions:
-
parseFile(file: File): Main entry point -
CSV Parsing:
- Supports multiple delimiters: comma, semicolon, tab
- First row is always treated as headers
- Empty lines are automatically filtered out
-
Excel Parsing:
- Uses the first sheet only
- Converts to JSON array format
- Empty cells are converted to empty strings
Column Matching Logic
The system uses intelligent column matching to automatically map file columns to campaign variables:1. Phone Number Detection
phone,phoneNumber,phone_numbernumero,numéro,numeroTelephonetel,telephone,mobile
2. Variable Column Matching
- Case-insensitive comparison
- Ignores underscores, spaces, and hyphens
- Example:
customer_first_namematchescustomerFirstName
3. Template Variable Override Matching
The system can also match columns to template message variables (header, body, button) based on the actual variable values defined in the campaign.Import Flow in Send Campaign Modal
Data Processing Pipeline
-
File Upload Handling:
-
Row Processing:
- Each row is processed individually
- Phone numbers are normalized and validated
- Variables are extracted based on column mappings
- Template overrides are applied if matching columns found
-
Duplicate Handling:
- Phone numbers are deduplicated automatically
- Existing recipients are updated with new variable values
- User receives feedback on duplicates
Variable Priority System
When sending a campaign, variables are resolved in this priority order:- File Import Values (highest priority)
- Values from CSV/Excel columns that match variable names
- Manual Overrides
- Values manually edited in the UI after import
- Reserved Variables
- Database values (e.g., customerFirstName)
- Default Values (lowest priority)
- Values defined during campaign creation
Import Validation and Feedback
The system provides comprehensive feedback during import:- Phone number format validation
- Required variable presence
- Data type compatibility
- File size limits (10MB)
- Row count limits (50,000 rows)
Error Handling
Common import errors and their handling:-
Missing Phone Column:
- Error: “Aucune colonne de numéro de téléphone trouvée”
- Solution: Ensure file has a column with phone-related name
-
Invalid File Format:
- Error: “Format de fichier non supporté”
- Solution: Use CSV or Excel formats only
-
Empty File:
- Error: “Le fichier est vide”
- Solution: Ensure file contains headers and data
-
Large Files:
- Files are processed in memory
- Progress feedback for files > 1000 rows
- Chunked processing to prevent UI freezing
Error Handling
-
Retry Logic:
- Automatic retry with exponential backoff
- Maximum 3 retry attempts
- Failed messages marked with error status
-
Dead Letter Queue:
- Messages failing after retries go to DLQ
- Manual inspection and reprocessing available
-
Status Updates:
- Real-time status via WebSocket events
- Campaign statistics updated after each batch