If you already use OpenClaw to answer chat questions, you can squeeze a lot more value out of it by automating the bookends of your day: a morning briefing that lands before coffee and an evening review that helps you shut the laptop without wondering what you forgot. I wired this up for myself six months ago and haven't touched the default Weather app or my notes inbox since. Below is the exact setup: cron jobs, prompts, channel routing, and the small tweaks that made it stick.
Why bother with a daily routine automation?
Context switching kills productivity faster than social media. A compressed, reliable summary at 08:00 saves at least ten tab-hops. A recap at 18:30 forces reflection and clears mental cache. The friction point is consistency; humans forget, schedulers don’t. OpenClaw already knows how to talk to APIs, so we let it pull the data, format it, and deliver it where we actually read it (Telegram in my case, Slack for the team).
Prerequisites: what you need before copy-pasting anything
- OpenClaw v0.27.3+ (requires Node 22).
npm i -g openclaw - A running gateway (local or on ClawCloud) and the daemon enabled.
- At least one messaging integration configured. Examples below assume Telegram and email SMTP.
- Access tokens for Composio if you want calendar/email/Notion tasks.
- A Unix-ish host that supports cron (Mac, Linux, or a tiny $4 Cloud VM).
Folder layout that keeps the automation sane
Throwing everything into ~/openclaw works until version control. I keep a dedicated repo:
~/claw-routines/
├─ morning-briefing.json
├─ evening-review.json
├─ scripts/
│ ├─ run-morning.sh
│ └─ run-evening.sh
└─ README.md
Each .json is an agent config slice: prompt template, tools, memory slots. Shell wrappers keep cron syntax readable and isolate logs.
Designing the morning briefing (weather, calendar, tasks, email summary)
The goal: one message titled “Morning Briefing – 2024-04-26” that contains:
- Local weather + severe alerts
- First three calendar events, start times adjusted to my timezone
- Top five tasks due today (Notion DB)
- Unread priority emails (Gmail label
\Starred)
Prompt template
You are my personal chief of staff. Produce a concise morning briefing for {{date}}.
Sections:
1. Weather (celsius, include precipitation chance, severe alerts)
2. Calendar (next 3 events, start time in Europe/Vienna, 1-line descript.)
3. Tasks (Notion DB 'Tasks', status=Todo, due today, limit 5)
4. Email (Gmail label:Starred, unread only, newest first, limit 5)
Bullet points, max 1200 chars total. End with an inspiring but non-cheesy quote.
Save that as morning-briefing.json under "prompt".
Tool chain
- Weather:
@openclaw/weather.open-meteo - Calendar:
@composio/google-calendar.readEvents - Tasks:
@composio/notion.queryDatabase - Email:
@composio/gmail.listMessages
Enable each with OAuth tokens in ~/.claw/credentials.json. Don’t store them in Git.
Scheduling with cron
# run-morning.sh
#!/usr/bin/env bash
cd ~/claw-routines
openclaw run morning-briefing.json \
--output channel:telegram:@myhandle 2>>logs/morning.err
chmod +x scripts/run-morning.sh
crontab -e
# 7:55 local time every weekday
55 7 * * 1-5 ~/claw-routines/scripts/run-morning.sh
Log files inside ~/claw-routines/logs catch failures; tail -f them the first week.
Designing the evening review (day recap, tomorrow prep, habit tracking)
Evening automation is harder because humans are tired. Keep it short and actionable:
- Recap of meetings actually attended (matching calendar + Zoom logs)
- GitHub pull requests opened/merged (filter repo:pspdfkit/*)
- Daily habit tracker (did I exercise, read, practice German – data from Loop app CSV synced to Dropbox)
- Tasks still open, auto-roll to tomorrow unless flagged “Someday”
- Open text field for reflection, written back to a Journal page in Notion
Prompt template
Create an evening review for {{date}}.
1. Meetings attended: list title, duration, one takeaway line.
2. GitHub activity: PRs opened/merged today (user:psteinberger).
3. Habits: show ✓ or ✗ for exercise, reading, German.
4. Tasks still open: list max 5.
5. Ask me: "Any blockers today?" Capture the answer and save to Notion DB 'Journal'.
Tone: objective, friendly. 800 chars max.
Interactive follow-up
The last bullet is interactive: OpenClaw sends the summary, waits for my reply, then stores it. I accomplish that with the built-in memory.capture tool and a small post-message hook.
"tools": [
"@composio/notion.appendBlock",
"memory.capture"
],
"hooks": {
"afterMessage": "memory.capture(\"journal_entry\") |> notion.appendBlock(page:'Journal/2024')"
}
Cron and time-zone math
I work across CET and PST. The evening review should land at 18:30 local regardless. Easiest fix: run the agent on the same machine I use daily and set cron for local time.
# run-evening.sh
#!/usr/bin/env bash
cd ~/claw-routines
openclaw run evening-review.json \
--output channel:telegram:@myhandle \
--output channel:email:me@steinberger.at \
2>>logs/evening.err
30 18 * * 1-5 ~/claw-routines/scripts/run-evening.sh
Choosing and changing delivery channels
Telegram is frictionless for solo use; Slack is noisy but great for team transparency. OpenClaw lets you specify multiple --output flags. A few learnings:
- Telegram handles markdown nicely, so include
*bold*and`code`in the prompt. - Email is universally reachable but threading is flaky. Prefix a constant subject:
[Claw] Morning Briefing. - iMessage integration (macOS-only) breaks on sleep; run the agent on a headless mini if you depend on it.
- You can combine: morning to Telegram + email, evening only Telegram.
Customizing content over time (the iteration loop)
The first version will annoy you within a week. Here’s the feedback loop I follow:
- Each Sunday, skim the last five briefings/reviews.
- Note any section I skipped reading. If I never look at tasks, drop or reorder.
- Search logs for errors → adjust OAuth scopes before Monday.
- Revise the prompt, commit/push to Git. The repo doubles as change history.
Examples of stuff I removed: Twitter DMs (too noisy), currency rates (clutter). Added later: server uptime alerts.
Security and rate-limit gotchas
- Store tokens in
~/.claw/credentials.jsonwithchmod 600. Never print them in logs. - Gmail API has a 100 requests/100s user quota; fetching full bodies blew it up. Use
listMessageswithformat:metadata. - Notion’s free tier rate-limits to three requests/second. Batch writes:
appendBlocksupports arrays. - If you commit to GitHub, add
morning-briefing.jsonto.gitignoreif it contains personal IDs.
Testing without spamming yourself
Use the built-in --dry-run flag:
openclaw run morning-briefing.json --dry-run | jq .message
This prints the rendered message so you can tweak copy length. Once ready, remove --dry-run and commit.
Scaling up: team dashboards and voice briefings
After personal success, we rolled a variant for the product team. Same structure, different data sources:
- PagerDuty incidents overnight
- Jira tickets moved to “In Review”
- Production deploys (GitHub Actions run-url)
We deliver this to a Slack channel at 09:00 CET. For execs, the agent posts an audio version using @openclaw/tts.elevenlabs and a private RSS feed they can play in Apple Podcasts.
Worst failures and how I fixed them
- Infinite loop: A malformed hook kept appending the same Notion block. Added a UUID guard.
- Daylight saving jump: Two briefings went out. Fixed by switching cron to
CRON_TZ=Europe/Vienna. - Token expiry: Gmail OAuth refresh failed silently. Wrapped the agent in a wrapper that retries once, then pings me via SMS.
Practical next step
Clone the skeleton repo I published yesterday (github.com/steipete/claw-routines), swap your tokens in credentials.json, and run ./scripts/run-morning.sh manually. If you get a nicely formatted message in your chosen channel, schedule the cron job and forget about it. The moment you stop noticing the briefings is when the automation is doing its job.