Marketing & SalesDocumentedScanned

campaign-orchestrator

Multi-channel follow-up campaign orchestrator for ShapeScale sales.

Share:

Installation

npx clawhub@latest install campaign-orchestrator

View the full skill documentation and source below.

Documentation

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:

  • 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

    # 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

    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:

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

  • 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

    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 }


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