Campaign Orchestrator
by @kesslerio
Multi-channel follow-up campaign orchestrator for ShapeScale sales. Schedules and executes SMS + Email sequences with CRM logging and auto-termination on replies. Use when following up with demo leads or managing outreach campaigns.
clawhub install campaign-orchestratorπ About This Skill
name: campaign-orchestrator description: Multi-channel follow-up campaign orchestrator for ShapeScale sales. Schedules and executes SMS + Email sequences with CRM logging and auto-termination on replies. Use when following up with demo leads or managing outreach campaigns. homepage: https://github.com/kesslerio/shapescale-moltbot-skills metadata: {"moltbot":{"emoji":"π","requires":{"env":["DIALPAD_API_KEY","ATTIO_API_KEY","GOG_KEYRING_PASSWORD"]},"primaryEnv":"DIALPAD_API_KEY"}}
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
Setup
Environment variables required:
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:
Usage
Start a Campaign
# 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 2Start 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:
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
# Status for specific lead
python3 campaign.py status "Apex Fitness"All active campaigns
python3 campaign.py list
Stop a Campaign
# Manual termination (lead replied, not interested, etc.)
python3 campaign.py stop "Apex Fitness" --reason "replied_interested"
Remove a Lead
# Remove lead from campaigns (opted out, not interested)
python3 campaign.py remove "Apex Fitness"
Check for Responses
# 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
# Show all pending campaign steps sorted by time
python3 campaign.py pending
Useful for seeing what's due soon across all campaigns
Template Management
# List available templates
python3 campaign.py templatesPreview a template
python3 campaign.py preview "primary"
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:
{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
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 :
{
"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:
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
python3 /home/art/niemand/skills/dialpad/send_sms.py --to "+14155551234" --message "..."
Gmail (via gog)
gog-shapescale --account martin@shapescale.com send-email --to "lead@company.com" --subject "..." --body "..."
Attio CRM
attio note companies "company-uuid" "Campaign message sent: {message}"
Examples
Full Campaign Workflow
# 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
# List all active
/campaign listOutput:
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:
cron is running: crontab -ljournalctl -u moltbot or campaign logsecho $DIALPAD_API_KEYWebhook not terminating:
campaigns.json for matching leadTemplate variables not filling:
{variable} not { variable }License
Part of shapescale-moltbot-skills. See parent repository.
π‘ Examples
Full Campaign Workflow
# 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
# List all active
/campaign listOutput:
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
βοΈ Configuration
Environment variables required:
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:
π Tips & Best Practices
Campaign not sending:
cron is running: crontab -ljournalctl -u moltbot or campaign logsecho $DIALPAD_API_KEYWebhook not terminating:
campaigns.json for matching leadTemplate variables not filling:
{variable} not { variable }