My OpenClaw Script Pattern (Or: How I Stopped Burning Tokens and Started Building Tools)
1 week agoAfter using OpenClaw for a couple weeks, I've settled on a pattern that works really well: make scripts do the actual work, OpenClaw just executes them.
The Problem with Pure AI Generation
For the first day or so, I had OpenClaw generating output directly. Need a weather forecast? Ask the AI to fetch the data, format it nicely, and post it to Discord.
This worked, but it burned tokens, produced inconsistent formatting, and wasn't reusable outside of AI conversations. I needed a better approach.
The Script-First Architecture
The pattern I landed on is pretty straightforward: write focused Python scripts that do one thing well, then have OpenClaw execute them.
Instead of this:
"OpenClaw, fetch the weather for San Diego, format it nicely with emoji and box drawing characters, and post it to #weather"
I do this:
"OpenClaw, run the weather script and post the output to #weather"
The script handles all the logic — API calls, data parsing, formatting, output. OpenClaw just executes it and relays the result.
Example: Weather Forecast System
Every morning at 6:50 AM, I get a weather forecast for San Diego posted to my #weather Discord channel.
File structure:
weather-system/
├── .venv/ # Python virtual environment
├── weather-system.py # Main script
├── requirements.txt # Dependencies (requests)
└── .last-run # Timestamp tracking
What the script does:
- Calls Open-Meteo API for San Diego coordinates
- Parses current temp, today's high, precipitation timing
- Formats output with weather emoji and Unicode box drawing
- Prints pre-formatted text
Output format:
☀️ WEATHER - 92130
Current: 62°F @ 06:50
Today High: 68°F @ 14:00
Precipitation: 04:00-09:00 (heavy 05:00-06:00)
Tomorrow:
High: 58°F @ 13:00
Low: 48°F
Precipitation: none
What OpenClaw does:
- Runs the script at 6:50 AM (scheduled via cron)
- Wraps the output in Discord code blocks
- Posts to #weather channel
- Done
Total tokens used per run: minimal (just executing a script and posting output, not generating the forecast content).
Example: Air Quality Monitor
This one runs every hour but only posts when air quality is above 50 or crosses the threshold in either direction.
File structure:
aqi-monitor/
├── .venv/
├── aqi-monitor.py
├── aqi-state.json # Tracks last reading for threshold detection
└── requirements.txt
What the script does:
- Fetches current AQI from IQAir API
- Loads previous reading from state file
- Checks if current AQI > 50 OR crossed threshold
- If alert condition: prints formatted alert
- If no alert needed: prints "SILENT"
- Updates state file with current reading
Output format (when alerting):
AQI - 92130 (San Diego) @ 11:00
AQI: 65 | Main: PM2.5
What OpenClaw does:
- Runs the script hourly (scheduled via cron)
- If output is "SILENT": does nothing
- If output is alert data: posts to #weather
- Done
This prevents spam — I only get notified when air quality actually matters, not every single hour saying "everything is fine."
The Pattern
Both systems (and the four others I've built) follow the same approach:
1. Focused Python script that does one thing well
2. Pre-formatted output designed for Discord code blocks
3. State tracking when needed (for thresholds, timestamps, rate limiting)
4. Simple execution via OpenClaw cron jobs
5. Explicit channel routing using the message tool
No complex logic in the cron configuration. No asking the AI to format things on the fly. Just "run this script, post the output to this channel."
Token Management Strategy
Another benefit of this is easier cron job setups. I pay for Claude API usage and need tokens for work during the day. So automation tasks run as cron jobs in the middle of the night. Also sometimes a bigger operation I will make as a script then have it be cronned for late at night.
This keeps my daytime budget available for interactive work. Plus I wake up to completed tasks posted to Discord, which is pretty nice.
Summary
Once you have the pattern down, adding new systems is pretty straightforward. I can usually go from idea to working automation in under an hour.
Anyway, that's how I approach making tools for Openclaw so far. If you're building something similar, hopefully this gives you a useful starting point.