📖 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 |
app/api/campaign/schemas.py defines validation & serialisation models used by both the API layer and the service logic.
Below is a condensed reference of the most important ones.
1. Twilio Content Context Schemas
These guarantee that the content_context_json supplied when creating/updating a campaign conforms to Twilio's restrictions.
| Schema | content_type |
Key Fields |
|---|---|---|
TwilioTextContext |
twilio/text |
body (≤ 1 600 chars) |
TwilioMediaContext |
twilio/media |
body (optional), media – list of URLs (or filled by file upload) |
TwilioCardContext |
twilio/card |
title, subtitle, media, actions[] |
TwilioCallToActionContext |
twilio/call-to-action |
body, actions[] (URL / PHONE_NUMBER / COPY_CODE) |
TwilioQuickReplyContext |
twilio/quick-reply |
body, actions[] (1-5 quick replies) |
All actions are composed using one of the following unions (aliased as TwilioAction):
* QuickReplyAction
* UrlAction
* PhoneAction
* CopyCodeAction
* VoiceCallAction
The schema layer enforces per-button character limits, E.164 phone format, etc.
2. API Payload Schemas
CampaignLeadUser
Input model used by /add-leads. Allows either phone_number or conversation_user_id plus optional custom_variables.
CampaignLeadSchema
Serialised representation of a single lead with message status (sent, replied, not_received, …) used inside CampaignSchema.
CampaignSchema
High-level DTO returned by most routes. It enriches the raw Campaign ORM model with:
* Aggregated metrics (messages_sent, reply_rate, conversion_rate).
* Campaign state (enabled timestamp indicating if campaign can send messages).
* Nested leads (optional) and discovered custom_variable_keys.
* context_variables – dynamic variables allowed by the selected default template.
CampaignSchema.from_model() runs additional DB queries to calculate the above fields and to hydrate the body preview.
Key Fields in CampaignSchema
| Field | Type | Description |
|---|---|---|
id |
int |
Campaign identifier |
name |
str |
Campaign name |
status |
CampaignStatus |
Approval status (unsubmitted, pending, approved, rejected) |
enabled |
datetime \| None |
Campaign enable state: None = disabled/paused, timestamp = enabled |
campaign_type |
str |
Type of campaign (marketing or service) |
total_leads |
int |
Count of active leads |
messages_sent |
int |
Count of successfully sent messages |
messages_replied |
int |
Count of leads who replied |
reply_rate |
float |
Percentage of sent messages that received replies |
Campaign State Logic
The enabled field controls campaign behavior:
For Marketing Campaigns:
- enabled = None: Campaign cannot send messages via UI or API
- enabled = <timestamp>: Campaign can send messages and appears as "active" in UI
For Service Campaigns:
- enabled = None: Automatic service messages are disabled (order confirmations, etc.)
- enabled = <timestamp>: Service automation is active and will trigger based on events
The frontend uses this field to: - Show green indicator for enabled campaigns - Enable/disable play/pause buttons appropriately - Filter campaign states in the UI
3. Helper Functions
get_variable_supported_fields(content_type) returns a list of top-level JSON fields that may legally embed variables for the given Twilio template type. This list is consumed by find_and_validate_variables().
Example – Valid Text Context
{
"body": "Hi {{lead_name}}, your order {{order_id}} is confirmed!"
}
Passing this through TwilioTextContext protects the system from accidentally sending over-long messages.
For further reading see: * Models * Service * Twilio Content API Docs