Campaign Creation Process
Campaigns are created through a visual flow builder that defines the messaging sequence. Each campaign consists of nodes (actions) connected by edges (flow paths).
Campaign Name
Required field that identifies the campaign:
- Displayed in campaign list, statistics, and audit logs
- Used for filtering and searching
- Best practice: Use descriptive names like “Welcome Sequence - Q1 2024”
Description
Optional field for campaign documentation:
- Visible to team members in organization mode
- Useful for explaining campaign goals and strategy
- Not used in processing logic
Telegram Account
Required - Select which Telegram account sends messages:
- Must have at least one connected account
- Account must be healthy and connected
- Campaign cannot send without valid account
Account Selection:
- Dropdown shows all available accounts
- Account health status displayed
- Unhealthy accounts cannot be selected
Campaigns cannot send messages if the Telegram account is disconnected or unhealthy. Ensure account is connected before creating campaign.
Step 2: Flow Builder
The flow builder is a visual interface for creating campaign workflows. It uses a node-based system where each node represents an action or decision point.
Start Node
Every campaign begins with a START node that defines when execution begins.
Start Type: Immediate
- Campaign starts as soon as it’s launched
- All executions begin processing immediately
next_execution_at set to now()
Start Type: Scheduled
- Campaign starts at specific date/time
- Requires
scheduled_start_at (date + time)
- Requires
timezone (e.g., “America/Sao_Paulo”)
- Worker checks scheduled campaigns every 30 seconds
- Automatically transitions to
active when time reached
Timezone Handling:
- Scheduled time stored in UTC in database
- Displayed in selected timezone in UI
- Worker converts UTC to campaign timezone for comparison
- Ensures campaigns start at correct local time
Node Types
SEND_MESSAGE Node
Sends a message to the lead.
Message Content:
- Plain text message
- Supports dynamic tags and spintax
- Optional media URL (image, video, document)
Message Processing:
- Spintax processed first (variations resolved deterministically)
- Tags replaced with actual values (with fallbacks)
- Rate limiting checked
- Message sent via Telegram API
- Execution log created
Dynamic Tags:
{firstName}, {lastName}, {username}, {phoneNumber}, {groupName}
{cf-fieldName} for custom fields
{tag|fallback} for fallback values
Spintax:
{option1|option2|option3} for message variations
- Same lead always gets same variation (deterministic)
- Supports nested spintax
WAIT Node
Pauses execution for specified duration or until response.
Duration-Based Wait:
- Specify days, hours, minutes
- Execution status:
waiting
next_execution_at calculated: now() + duration
- Worker resumes execution when time reached
Response-Based Wait:
- Waits for lead to reply
- Configurable timeout (days/hours/minutes)
- Execution status:
waiting
- If response detected: execution continues immediately
- If timeout reached: execution continues to next node
- If no timeout: waits indefinitely
CONDITION Node
Branches flow based on evaluation result.
Condition Types:
- Response check: Did lead reply?
- Variable check: Does variable match value?
- Custom condition: Evaluate expression
Branching:
- Edges define paths:
condition: "yes" or condition: "no"
- Next node determined by condition result
- If no matching edge: execution stops (error)
Edge Configuration:
- Source: Condition node ID
- Target: Next node ID
- Condition:
"yes" or "no" (or custom value)
END Node
Marks execution as completed.
Completion Behavior:
- Execution status:
completed
completed_at timestamp set
- Campaign checks if all executions done
- If all done: campaign status →
completed
Adding Nodes
From Node Palette:
- Click ”+” button or node type icon
- Node added to flow canvas
- Auto-connected to previous node (if sequential)
- Configure node properties in sidebar
Node Properties:
- Each node type has specific properties
- SEND_MESSAGE: message text, media URL
- WAIT: duration or response timeout
- CONDITION: condition expression
- Properties saved in node
data field
Connecting Nodes
Sequential Connections:
- Nodes processed in array order by default
- Edges created automatically for sequential flow
- Manual edges only needed for condition branches
Conditional Branches:
- Drag edge from condition node to target node
- Set edge
condition to "yes" or "no"
- Multiple edges from same condition node allowed
- Each edge represents different branch path
Edge Properties:
source: Source node ID
target: Target node ID
condition: Branch condition (for condition nodes)
label: Optional display label
Flow Validation
Before saving, flow is validated:
Required Checks:
- Must have START node
- Must have at least one SEND_MESSAGE node
- All nodes must be connected (directly or via edges)
- Condition nodes must have edges for all branches
Warnings:
- Unconnected nodes
- Condition nodes without branches
- Empty message nodes
- Invalid wait durations
Step 3: Advanced Features
A/B Testing
Enable A/B testing to test multiple flow variations.
Configuration:
- Toggle
ab_test_enabled to enable
- Create variations (A, B, C, etc.)
- Each variation has independent flow configuration
- Variations can be enabled/disabled independently
Variation Selection:
- Deterministic: Same lead always gets same variation
- Uses hash of
contact_id as seed
- Weighted distribution: Configure weights per variation
- Default: Uniform distribution (equal weights)
Optimization:
- Automatic optimization based on performance
- Compares response rates between variations
- Adjusts weights to favor better performers
- Threshold:
ab_test_optimization_threshold (default: 0.1)
Statistics:
- Tracked per variation: sent, responses, response rate
- Updated every 5 minutes
- View via campaign statistics page
Response Handling
Pause on Response:
pause_on_response: If true, execution stops immediately when response detected
- If
false, execution completes current node before stopping
- Default:
false
Response Timeout:
response_timeout_hours: Maximum wait time for response
- If no response after timeout, execution continues
- Default: No timeout (waits indefinitely)
- Only applies to response-based WAIT nodes
Timezone Configuration
Campaign Timezone:
- Required for scheduled campaigns
- Used for converting scheduled time
- Format: IANA timezone (e.g., “America/Sao_Paulo”, “Europe/London”)
- Default: “UTC”
Timezone Impact:
- Scheduled start time displayed in campaign timezone
- Worker converts to UTC for storage
- Ensures campaigns start at correct local time
Contacts can be added during creation or after:
During Creation:
- Select contacts from available list
- Filter by segment, custom fields, etc.
- Executions created immediately when campaign saved
After Creation:
- Add contacts via campaign detail page
- Executions created with status
pending
- For active campaigns: executions processed immediately
- For completed campaigns: campaign reactivated to
active
Available Filters:
- Segment membership
- Custom field values
- Tags
- Organization (in org mode)
Execution Creation:
- One execution per contact
- Status:
pending
next_execution_at: now() for immediate processing
- Context initialized with contact data
Step 5: Save and Launch
Save as Draft
Draft Status:
- Campaign saved but not launched
- Status:
draft
- Can be edited freely
- No executions processed
- Can launch later
Save and Launch
Launch Behavior:
- Status changes to
active (or scheduled if scheduled)
- Executions created for all selected contacts
next_execution_at set to now() (or scheduled time)
- Worker picks up executions on next cycle
Launch Requirements:
- Campaign must be enabled (
enabled = true)
- Telegram account must be connected and healthy
- At least one contact selected
- Flow must be valid
Flow Examples
Simple Sequence
START → SEND_MESSAGE (Welcome) → WAIT (24 hours) → SEND_MESSAGE (Follow-up) → END
Execution Flow:
- START: Initialize execution
- SEND_MESSAGE: Send welcome message
- WAIT: Set
next_execution_at to 24 hours later
- Worker resumes after 24 hours
- SEND_MESSAGE: Send follow-up message
- END: Mark execution completed
Conditional Flow
START → SEND_MESSAGE (Initial) → CONDITION (Response?)
├─ Yes → SEND_MESSAGE (Thank you) → END
└─ No → WAIT (48 hours) → SEND_MESSAGE (Reminder) → END
Execution Flow:
- START: Initialize execution
- SEND_MESSAGE: Send initial message
- CONDITION: Check for response
- If response: Branch to “Yes” path → Send thank you → END
- If no response: Branch to “No” path → Wait 48h → Send reminder → END
Edge Configuration:
- Edge 1:
source: condition_node_id, target: thank_you_node_id, condition: "yes"
- Edge 2:
source: condition_node_id, target: wait_node_id, condition: "no"
Scheduled Campaign
START (Scheduled: 2024-01-15 09:00 America/Sao_Paulo)
→ SEND_MESSAGE (Announcement) → END
Execution Flow:
- Campaign status:
scheduled
- Worker checks every 30 seconds
- When scheduled time reached: Status →
active
- Executions begin processing
- SEND_MESSAGE: Send announcement
- END: Mark execution completed
A/B Test Campaign
START → A/B SELECTION
├─ Variation A: SEND_MESSAGE (Version A) → END
├─ Variation B: SEND_MESSAGE (Version B) → END
└─ Variation C: SEND_MESSAGE (Version C) → END
Execution Flow:
- START: Initialize execution
- A/B service selects variation based on
contact_id hash
- Execution uses selected variation’s flow
- Variation tracked in execution (
ab_variation field)
- Statistics updated per variation
Best Practices
- Test Flow First: Create draft, review flow visually, test with small audience
- Use Descriptive Names: Make campaigns easy to identify
- Set Correct Timezone: Ensure scheduled campaigns start at right time
- Add Fallbacks: Always provide fallback values for tags:
{firstName|Guest}
- Respect Rate Limits: Space out messages with WAIT nodes
- Monitor Responses: Enable pause on response to stop when lead engages
- Use A/B Testing: Test variations to optimize performance
- Document Strategy: Use description field to explain campaign goals
Common Mistakes
- Missing START Node: Every campaign needs START node
- No Telegram Account: Campaign cannot send without account
- Invalid Timezone: Scheduled campaigns need valid IANA timezone
- No Contacts: Campaign needs at least one contact
- Condition Without Branches: Condition nodes need edges for all paths
- Circular References: Avoid loops in flow (causes infinite execution)
- Missing Fallbacks: Tags without fallbacks may break messages
- Too Aggressive Rate Limiting: Sending too fast causes FloodWaitError