📖 Campaign Documentation

Page Description
Overview Module overview, workflows, and high-level architecture
Models & Constants Database models, enums, and default templates
Routes API endpoints, request/response formats, and examples
Service Business logic functions and integration points
Schemas Validation schemas and data structures

This section describes the database models and enumerations that power the Campaign module.
For the full source code see app/api/campaign/models.py.


Enumerations

Enum Purpose
CampaignStatus Current approval / operational state (unsubmitted, received, pending, approved, rejected, paused, disabled, archived).
CampaignType Whether the campaign is marketing or service (utility).
CampaignAuthorType Who created the template: system (Cosmo) vs merchant.
DefaultCampaigns, CommerceDefaultCampaigns Constant names for built-in templates created by create_default_templates().
CampaignVariableType Allowed variable identifiers (e.g. merchant_name, lead_phone, order_id, …). These determine what can be referenced with {{variable}} inside a template.

ORM Models

Campaign

Represents one specific version of a WhatsApp template.

class Campaign(Base):
    __tablename__ = "campaigns"
    id: int                # Primary key / version id
    merchant_id: int       # Owner merchant
    next_campaign_id: int? # Link to newer version (if any)
    name: str              # Logical template name (Merchant-unique)
    body: str              # Human-readable body (first text field)
    language: str = "en"   # WhatsApp language locale
    content_sid: str?      # Twilio Content SID once approved
    status: CampaignStatus # Approval state
    rejection_reason: str? # Twilio rejection details
    variables: dict        # Map {'1': 'lead_name', ...}
    content_type: str      # twilio/text, twilio/media, …
    content_context: dict  # JSON payload sent to Twilio Content API
    campaign_type: CampaignType
    author_type: CampaignAuthorType
    channel: str = "twilio"

Relations: * one-to-many with CampaignLead (who will receive the template). * one-to-many with CampaignLeadMessage (messages actually sent).


CampaignLead

A target audience member for a campaign. Serves dual purpose as sending queue and historical record.

class CampaignLead(Base):
    id: int
    campaign_id: int               # FK Campaign
    conversation_user_id: int       # FK ConversationUser (phone number)
    active: bool = True             # Soft-delete flag (queue management)
    custom_variables: dict = {}     # Lead-specific variables (overrides defaults)

Key Behaviors: - Queue Management: Only active = True leads are processed during bulk sends - Historical Persistence: Inactive leads remain in database for analytics and compliance - Variable Personalization: Custom variables override campaign defaults for this specific lead - Marketing Compliance: Previous sends are tracked to prevent duplicate marketing messages


CampaignLeadMessage

Associates a Message in a conversation with the campaign + lead that triggered it.
Also stores extra context used by redirect links.

class CampaignLeadMessage(Base):
    id: int
    campaign_id: int
    campaign_lead_id: int
    message_id: int?          # FK to Conversation Message once created
    context: dict?            # Hydrated variables at send time

Relationships Diagram

graph LR
    Campaign -->|1..n| CampaignLead
    CampaignLead -->|1..n| CampaignLeadMessage
    CampaignLeadMessage --> Message
    CampaignLead --> ConversationUser
    Campaign --> Merchant

Service Template Defaults

System-created service templates available to all merchants (defined in service.py):

Basic Service Templates

  • hello_world – Generic greeting message
  • merchant_user_welcome – Onboarding message for new merchant users
  • merchant_user_override_request – Support ticket notifications to merchant staff
  • merchant_user_question_request – Customer inquiry alerts for merchant staff
  • merchant_user_question_answer – Response template for customer questions

Commerce-Specific Service Templates

All of the above, plus:

Inventory Management

  • out_of_stock – Product unavailability notifications
  • low_stock – Limited inventory warnings
  • in_stock – Restock notifications
  • sku_price_change – Product price update alerts

Order Lifecycle

  • merchant_user_order_placed – New order alerts for merchant staff
  • customer_order_processing – Order confirmation for customers
  • customer_order_delivering – Shipping/delivery notifications
  • customer_order_fulfilled – Delivery confirmation for customers
  • merchant_user_order_fulfilled – Completion notifications for merchant staff
  • customer_order_failed – Order failure notifications for customers
  • merchant_user_order_failed – Order failure alerts for merchant staff

Payment & Logistics

  • customer_cash_on_delivery_confirmation – COD verification requests
  • customer_order_confirmation – Generic order confirmation
  • customer_order_confirmation_with_receipt – Order confirmation with receipt link
  • customer_order_status_update – Generic status change notifications
  • customer_order_shipping_fee_changed – Shipping cost updates

Driver/Delivery Integration

  • driver_order_request – Delivery requests for drivers
  • driver_order_request_not_available – Driver unavailability notifications

These templates are automatically created/updated during merchant onboarding and can be customized by merchants while maintaining their service classification.


Constant Lists

DEFAULT_CAMPAIGNS & DEFAULT_COMMERCE_CAMPAIGNS reside in service.py.
They bootstrap the system with a library of ready-made templates for common flows ("order placed", "hello world", etc.).
Each definition contains:

{
  "name": "merchant_user_welcome",
  "content_type": "twilio/text",
  "content_context": {"body": "Welcome …"}
}

These are converted into real Campaign rows by create_default_templates() during merchant onboarding.