🎁 Get the FREE AI Skills Starter Guide β€” Subscribe β†’
BytesAgainBytesAgain
πŸ¦€ ClawHub

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.

TERMINAL
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

  • 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:

    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

    # 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:

    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 templates

    Preview 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 /state/campaigns.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:

    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 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.

    πŸ’‘ 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 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

    βš™οΈ 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:

  • Dialpad webhook is configured to hit this server
  • Attio has company/contact records for leads
  • Gmail API access enabled for sales email
  • πŸ“‹ Tips & Best Practices

    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 }