✓ Verified 🛒 E-commerce ✓ Enhanced Data

Campaign Orchestrator

Multi-channel follow-up campaign orchestrator.

Rating
3.9 (12 reviews)
Downloads
24,348 downloads
Version
1.0.0

Overview

Multi-channel follow-up campaign orchestrator.

Key Features

1

Multi-channel: SMS (Dialpad) + Email (Gmail)

2

Scheduled: Cron-based execution with configurable delays

3

Personalized: Templates filled from Attio CRM data

4

Auto-terminating: Replies stop all future scheduled steps

5

Logged: All activities recorded in Attio

Complete Documentation

View Source →

Campaign Orchestrator Skill

Multi-channel follow-up campaign orchestrator for ShapeScale sales. Executes scheduled SMS + Email sequences with CRM integration and auto-termination on replies.

Overview

A Campaign is a defined sequence of steps (SMS/Email) that executes over time. When a lead replies to any message, the campaign automatically terminates.

Key Features

  • Multi-channel: SMS (Dialpad) + Email (Gmail)
  • Scheduled: Cron-based execution with configurable delays
  • Personalized: Templates filled from Attio CRM data
  • Auto-terminating: Replies stop all future scheduled steps
  • Logged: All activities recorded in Attio

Setup

Environment variables required:

bash
DIALPAD_API_KEY=your_dialpad_api_key
ATTIO_API_KEY=your_attio_api_key
GOG_KEYRING_PASSWORD=your_google_password  # For Gmail access

Also ensure:

  • Dialpad webhook is configured to hit this server
  • Attio has company/contact records for leads
  • Gmail API access enabled for sales email

Usage

Start a Campaign

bash
# Start primary follow-up campaign for a lead
python3 campaign.py start "primary" --lead "Apex Fitness"

# Start with custom delay override (hours)
python3 campaign.py start "primary" --lead "Apex Fitness" --delay 2

# Start with Attio deal/company ID
python3 campaign.py start "post-demo" --lead "Apex Fitness" --attio-id "deal-uuid"

Pre-Campaign Checklist (MANDATORY)

Before starting ANY campaign, verify:

  • Customer Status Check
  • Search memory/CRM for "already a customer" or "purchased" flags
  • Check exclusion list in campaigns.json
  • Verify email domain not in customer database
  • Email Formatting Check (for email steps)
  • Preview template renders as proper paragraphs
  • 2-4 sentences per paragraph, blank line between
  • No single-sentence orphan paragraphs
  • No hard line breaks mid-paragraph
  • Tone Check
  • No apologetic language ("no worries", "sorry to bother")
  • No easy outs ("if not relevant, no problem")
  • Professional, not needy
NEVER campaign to existing customers unless explicitly requested for upsell.

Check Campaign Status

bash
# Status for specific lead
python3 campaign.py status "Apex Fitness"

# All active campaigns
python3 campaign.py list

Stop a Campaign

bash
# Manual termination (lead replied, not interested, etc.)
python3 campaign.py stop "Apex Fitness" --reason "replied_interested"

Remove a Lead

bash
# Remove lead from campaigns (opted out, not interested)
python3 campaign.py remove "Apex Fitness"

Check for Responses

bash
# Check if lead has responded to any prior messages
python3 campaign.py check "Apex Fitness"
# Shows response status for each completed step
# Warns if responses detected (safe to proceed or terminate)

View Pending Steps

bash
# Show all pending campaign steps sorted by time
python3 campaign.py pending
# Useful for seeing what's due soon across all campaigns

Template Management

bash
# List available templates
python3 campaign.py templates

# Preview a template
python3 campaign.py preview "primary"

Campaign Templates

TemplateTimingChannelPurpose
primary+4 hoursSMSRecap demo, share recording
secondary+1 dayEmailPricing, detailed ROI
tertiary+4 daysSMSQuick check-in
quaternary+7 daysEmailFinal follow-up, case study
post-demo+0 hoursSMSImmediate thank you

Template Variables

Templates support variable substitution:

text
{name}      - Lead first name
{company}   - Company name
{deal_value} - Deal value from Attio
{owner}     - Sales owner name
{demo_notes} - Notes from demo conversation
{checkout_link} - Personalized checkout URL

Architecture

text
campaign-orchestrator/
├── SKILL.md              # This file
├── campaign.py           # Main CLI (start, stop, status, list)
├── webhook_handler.py    # Processes reply → termination
├── primary.md            # SMS follow-up template
├── secondary.md          # Email template
├── post-demo.md          # Immediate follow-up template
└── state/
    └── campaigns.json    # Campaign state persistence

State Management

Campaign state is stored in /state/campaigns.json:

json
{
  "campaigns": {
    "Apex Fitness": {
      "template": "primary",
      "attio_id": "deal-uuid",
      "started": "2026-01-27T13:00:00Z",
      "steps_completed": ["sms_primary"],
      "next_step": "email_secondary",
      "next_scheduled": "2026-01-28T13:00:00Z",
      "status": "active"
    }
  },
  "templates": {
    "primary": {...},
    "secondary": {...}
  }
}

Cron Integration

Campaign steps are executed via Clawdbot's cron system:

  • Executor job: Runs every 5 minutes to check for due steps
  • Per-campaign jobs: Created for each scheduled step
The scheduler script creates and manages these jobs automatically.

Webhook Handling

When Dialpad receives a reply to a campaign message:

  • Dialpad sends webhook to server
  • webhook_handler.py parses the reply
  • Looks up which campaign the original message belonged to
  • Marks campaign as terminated
  • Logs the reply to Attio

Integration Points

Dialpad SMS

bash
python3 /home/art/niemand/skills/dialpad/send_sms.py --to "+14155551234" --message "..."

Gmail (via gog)

bash
gog-shapescale --account [email protected] send-email --to "[email protected]" --subject "..." --body "..."

Attio CRM

bash
attio note companies "company-uuid" "Campaign message sent: {message}"

Examples

Full Campaign Workflow

bash
# 1. After demo, start campaign
/campaign start "post-demo" --lead "Dr. Smith's Clinic"

# 2. Check status next day
/campaign status "Dr. Smith's Clinic"
# Output: Step 1 sent, Step 2 scheduled for tomorrow

# 3. Lead replies "interested"
# Webhook automatically terminates campaign
# Logs reply to Attio

# 4. Manual follow-up if needed
/campaign start "secondary" --lead "Dr. Smith's Clinic" --delay 0

Monitoring Active Campaigns

bash
# List all active
/campaign list

# Output:
# Active Campaigns:
# - Apex Fitness (primary) - Step 2/4, next: email
# - Dr. Smith's Clinic (post-demo) - Complete
# - Wellness Center (tertiary) - Step 1/3, next: sms

Troubleshooting

Campaign not sending:

  • Check cron is running: crontab -l
  • Check logs: journalctl -u moltbot or campaign logs
  • Verify API keys: echo $DIALPAD_API_KEY
Webhook not terminating:
  • Verify Dialpad webhook URL is configured
  • Check webhook handler is running
  • Check campaigns.json for matching lead
Template variables not filling:
  • Verify lead exists in Attio with required fields
  • Check template syntax: {variable} not { variable }

License

Part of shapescale-moltbot-skills. See parent repository.

Installation

Terminal bash

openclaw install campaign-orchestrator
    
Copied!

💻Code Examples

**Environment variables required:**

environment-variables-required.sh
DIALPAD_API_KEY=your_dialpad_api_key
ATTIO_API_KEY=your_attio_api_key
GOG_KEYRING_PASSWORD=your_google_password  # For Gmail access

python3 campaign.py start "post-demo" --lead "Apex Fitness" --attio-id "deal-uuid"

python3-campaignpy-start-post-demo---lead-apex-fitness---attio-id-deal-uuid.txt
### Pre-Campaign Checklist (MANDATORY)

Before starting ANY campaign, verify:

1. **Customer Status Check**
   - Search memory/CRM for "already a customer" or "purchased" flags
   - Check exclusion list in campaigns.json
   - Verify email domain not in customer database

2. **Email Formatting Check** (for email steps)
   - Preview template renders as proper paragraphs
   - 2-4 sentences per paragraph, blank line between
   - No single-sentence orphan paragraphs
   - No hard line breaks mid-paragraph

3. **Tone Check**
   - No apologetic language ("no worries", "sorry to bother")
   - No easy outs ("if not relevant, no problem")
   - Professional, not needy

**NEVER campaign to existing customers unless explicitly requested for upsell.**

### Check Campaign Status

python3 campaign.py preview "primary"

python3-campaignpy-preview-primary.txt
## Campaign Templates

| Template | Timing | Channel | Purpose |
|----------|--------|---------|---------|
| `primary` | +4 hours | SMS | Recap demo, share recording |
| `secondary` | +1 day | Email | Pricing, detailed ROI |
| `tertiary` | +4 days | SMS | Quick check-in |
| `quaternary` | +7 days | Email | Final follow-up, case study |
| `post-demo` | +0 hours | SMS | Immediate thank you |

### Template Variables

Templates support variable substitution:

└── campaigns.json # Campaign state persistence

--campaignsjson--campaign-state-persistence.txt
## State Management

Campaign state is stored in `<workspace>/state/campaigns.json`:

}

.txt
## Cron Integration

Campaign steps are executed via Clawdbot's cron system:

- **Executor job**: Runs every 5 minutes to check for due steps
- **Per-campaign jobs**: Created for each scheduled step

The scheduler script creates and manages these jobs automatically.

## Webhook Handling

When Dialpad receives a reply to a campaign message:

1. Dialpad sends webhook to server
2. `webhook_handler.py` parses the reply
3. Looks up which campaign the original message belonged to
4. Marks campaign as terminated
5. Logs the reply to Attio

## Integration Points

### Dialpad SMS

attio note companies "company-uuid" "Campaign message sent: {message}"

attio-note-companies-company-uuid-campaign-message-sent-message.txt
## Examples

### Full Campaign Workflow
example.sh
# Start primary follow-up campaign for a lead
python3 campaign.py start "primary" --lead "Apex Fitness"

# Start with custom delay override (hours)
python3 campaign.py start "primary" --lead "Apex Fitness" --delay 2

# Start with Attio deal/company ID
python3 campaign.py start "post-demo" --lead "Apex Fitness" --attio-id "deal-uuid"
example.sh
# Status for specific lead
python3 campaign.py status "Apex Fitness"

# All active campaigns
python3 campaign.py list
example.sh
# Check if lead has responded to any prior messages
python3 campaign.py check "Apex Fitness"
# Shows response status for each completed step
# Warns if responses detected (safe to proceed or terminate)
example.sh
# Show all pending campaign steps sorted by time
python3 campaign.py pending
# Useful for seeing what's due soon across all campaigns

Tags

#marketing_and-sales

Quick Info

Category E-commerce
Model Claude 3.5
Complexity One-Click
Author kesslerio
Last Updated 3/10/2026
🚀
Optimized for
Claude 3.5
🧠

Ready to Install?

Get started with this skill in seconds

openclaw install campaign-orchestrator