⏰ Cron + ⚙️ Workflows = 🤖 Autonomy

Automate Everything

Advanced Cron Workflows: Automate Everything with OpenClaw

Stop doing repetitive tasks. Build intelligent automation systems that run 24/7, make decisions, and handle complex workflows without human intervention.

The difference between a helpful AI assistant and a truly autonomous agent is cron jobs. While you sleep, your agent can check emails, monitor prices, generate reports, and trigger actions across dozens of services.

Understanding Cron: Time as Code

Cron is the Unix scheduler — a simple but incredibly powerful way to say "run this at this time." In OpenClaw, cron jobs become your agent's autonomous nervous system.

📅 Cron Expression Cheatsheet

* * * * *  → Every minute
0 * * * *  → Every hour
0 0 * * *  → Daily at midnight
0 9 * * 1  → Mondays at 9am
*/5 * * * * → Every 5 minutes
0 0 1 * *  → First of every month

Your First Cron Job

# In your SOUL.md or agent config:
cron_jobs:
  - name: "morning-briefing"
    schedule: "0 8 * * *"  # 8am daily
    action: |
      Check calendar for today
      Read unread emails from VIPs
      Check weather for user's location
      Send summary via Telegram
  
  - name: "price-monitor"
    schedule: "0 */2 * * *"  # Every 2 hours
    action: |
      Check prices on watchlist
      If price drops below threshold:
        Send alert to user
        Include purchase link

Building Complex Workflows

Real automation isn't just scheduling — it's decision-making. Here's how to build intelligent workflows:

🔄 Example: Smart Email Triage

Every 15 minutes, the agent:

  1. Fetches unread emails
  2. Analyzes sender priority (VIP list)
  3. Reads subject + first 100 words
  4. Categorizes: Urgent / Important / Low Priority
  5. If urgent: Send immediate alert + summary
  6. Else if important: Queue for next briefing
  7. Else: Mark as read, archive
@cron.schedule("*/15 * * * *")
def email_triage_workflow():
    emails = gmail.get_unread()
    
    for email in emails:
        sender = email['from']
        subject = email['subject']
        
        # Priority classification
        if sender in VIP_LIST:
            priority = "URGENT"
        elif any(word in subject.lower() 
                 for word in ['invoice', 'payment', 'deadline']):
            priority = "IMPORTANT"
        else:
            priority = "LOW"
        
        # Conditional actions
        if priority == "URGENT":
            telegram.send_message(
                f"🚨 URGENT: {subject}\nFrom: {sender}\n\n{email['preview']}"
            )
            
        elif priority == "IMPORTANT":
            queue_for_briefing(email)
            
        else:
            gmail.mark_read(email['id'])
            gmail.archive(email['id'])

The 5 Workflow Patterns

1. The Monitor-Alert Pattern

Watch for changes, notify when detected:

@cron.schedule("0 * * * *")  # Hourly
def monitor_website_uptime():
    sites = ["monks.com", "startwithopenclaw.com"]
    
    for site in sites:
        status = check_website(site)
        
        if status != 200:
            telegram.send_message(
                f"⚠️ {site} is DOWN! Status: {status}"
            )
            
            # Auto-restart if it's our service
            if site == "startwithopenclaw.com":
                restart_server()

2. The Aggregator Pattern

Collect data over time, generate reports:

@cron.schedule("0 18 * * 5")  # Fridays 6pm
def weekly_report():
    # Collect week's data
    emails_sent = count_emails_this_week()
    meetings = get_calendar_summary()
    tasks_completed = notion.query_completed_tasks()
    
    # Generate insights
    report = f"""
📊 Weekly Summary (Auto-generated)

📧 Emails: {emails_sent} sent, {emails_received} received
📅 Meetings: {len(meetings)} total, {meeting_hours} hours
✅ Tasks: {len(tasks_completed)} completed

🎯 Focus areas for next week:
{analyze_priorities(meetings)}
    """
    
    email.send(to=user_email, subject="Weekly Report", body=report)

3. The Maintenance Pattern

Keep systems healthy automatically:

@cron.schedule("0 2 * * 0")  # Sundays 2am
def weekly_maintenance():
    # Cleanup
    delete_old_logs(days=30)
    archive_old_projects()
    
    # Health checks
    disk_usage = check_disk_space()
    if disk_usage > 80%:
        alert_user("Disk space low!")
        clean_temp_files()
    
    # Updates
    if updates_available():
        send_summary("System updates available")

4. The Reaction Pattern

Respond to external events via webhooks:

@app.route('/webhook/github-pr', methods=['POST'])
def handle_pull_request():
    data = request.json
    pr = data['pull_request']
    
    # Auto-assign reviewer based on code area
    files_changed = get_changed_files(pr['number'])
    reviewer = determine_expert(files_changed)
    
    github.assign_reviewer(pr['number'], reviewer)
    
    # Notify relevant people
    slack.send_message(
        channel="#engineering",
        text=f"New PR: {pr['title']} by {pr['user']['login']}\nReviewer: @{reviewer}"
    )

5. The Chain Pattern

Multi-step workflows with dependencies:

@cron.schedule("0 9 * * 1")  # Mondays 9am
def weekly_planning_chain():
    
    # Step 1: Review last week
    last_week = get_completed_tasks()
    insights = analyze_productivity(last_week)
    
    # Step 2: Check upcoming calendar
    upcoming = get_this_weeks_events()
    busy_days = find_busy_days(upcoming)
    
    # Step 3: Query project deadlines
    deadlines = notion.get_upcoming_deadlines()
    urgent_tasks = filter_urgent(deadlines)
    
    # Step 4: Generate recommendations
    plan = generate_weekly_plan(
        insights=insights,
        busy_days=busy_days,
        urgent_tasks=urgent_tasks
    )
    
    # Step 5: Create tasks and notify
    create_notion_tasks(plan)
    send_briefing(plan)
    add_calendar_blocks(plan.focus_time)

Error Handling & Reliability

Production automations need to handle failures gracefully:

@cron.schedule("0 */6 * * *")
def reliable_data_sync():
    max_retries = 3
    
    for attempt in range(max_retries):
        try:
            data = fetch_external_api()
            save_to_database(data)
            log_success("Data sync completed")
            return
            
        except APIError as e:
            if attempt < max_retries - 1:
                wait_time = 2 ** attempt  # Exponential backoff
                time.sleep(wait_time)
            else:
                # All retries failed
                alert_admin(f"Data sync failed: {e}")
                save_failed_state(data)

Real-World Automation Examples

💰 Personal Finance Tracker

Daily: Fetch transactions from banks → Categorize with AI → Update spreadsheet → Alert on unusual spending

📰 Content Curator

Hourly: Check RSS feeds → Filter by interests → Summarize with AI → Queue best articles for evening reading

🛒 Smart Shopper

Every 30 min: Check wishlist prices → Compare to historical lows → Alert on deals → Auto-buy if below threshold

🏋️ Health Coach

Daily: Pull fitness data → Analyze trends → Adjust workout recommendations → Schedule rest days automatically

⚙️ Ready to Automate Your Life?

Get 20+ ready-to-use cron workflow templates for common automation scenarios.

Get Workflow Templates →

Remember: The best automation is invisible. Start simple, add complexity gradually, and always have escape hatches for when things go wrong. Happy automating! ⏰🦞