Skill: Remind Me
When to use
- User says "remind me to...", "set a reminder", "set an alarm"
- User says "every Monday at 9 AM...", "every 30 minutes check..."
- User says "in 20 minutes tell me...", "at 3 PM send me..."
- User wants to schedule a recurring cron job via chat
- User says "cancel my reminder", "delete that cron", "stop the alert"
- User says "list my reminders", "what reminders do I have?"
- User wants to know what cron jobs are active in this chat
When NOT to use
- User wants to check a stock price right now (not scheduled) → use
stock-price-checker-pro - User wants to run a one-time task immediately (no scheduling involved)
⚠️ CRITICAL: Always resolve these THREE things before creating a reminder
Before calling the script, you MUST have all three resolved:
| Field | Question to answer | Example |
|---|---|---|
| WHAT | What should happen / be said? | "Check NVDA stock price" |
| WHEN / HOW OFTEN | One-time or recurring? At what time/interval? | "Every Monday at 9 AM" |
| WHERE | Which channel + chat ID to deliver to? | Auto-detected from session |
Missing field rules
- WHAT is missing → Ask: "What would you like me to remind you about?"
- WHEN is missing AND cannot be reasonably assumed → Ask: "How often, or at what time?"
- WHEN is missing BUT can be reasonably assumed as once → Assume one-shot, but confirm: "Just once, right?"
- WHERE is always auto-detected → Never ask the user for this. Read it from session context (see below).
Do NOT create the job until all three are confirmed.
Step 1 — Auto-detect channel and chat ID from session context
The source channel and chat ID are available in your session context. Extract them before doing anything else.
- channel: the platform the message arrived on (e.g.
telegram,discord) - chatId / to: the specific chat or user ID within that platform (e.g.
<chatId>)
These two values are passed as --channel and --to to the script.
Never ask the user for these. Never hardcode them. Always read from session context.
Step 2 — Parse the user's intent
From the user's natural language request, extract:
Schedule type
Map what the user said to one of three prefixed schedule strings:
| What user said | Schedule string to pass |
|---|---|
| "every 30 minutes" | every:30m |
| "every hour" | every:1h |
| "every day at 9 AM" | cron:0 9 * * * |
| "every Monday at 9 AM" | cron:0 9 * * 1 |
| "weekdays at 8 AM" | cron:0 8 * * 1-5 |
| "every Friday at 5 PM" | cron:0 17 * * 5 |
| "in 20 minutes" | at:20m |
| "in 2 hours" | at:2h |
| "at 3 PM today" | at:<computed duration from now> |
| "once at 9:30 AM tomorrow" | at:<computed duration from now> |
One-shot vs recurring
at:→ always one-shot (--onceis auto-set by the script)every:orcron:→ recurring by default- If user says "just once" or "one time" with a
cron:orevery:→ pass--once
Job name
Generate a short, descriptive name from the user's request.
- "Remind me to check NVDA every Monday" →
"NVDA Check - Monday 9AM" - "Alert me in 20 minutes" →
"Alert - 20min" - "Grocery reminder at noon" →
"Groceries - Noon"
Message
The message is what the agent will say or do when the job fires. Craft it clearly so the agent knows exactly what to do:
- "Remind me to do groceries" →
"Reminder: Time to do groceries! 🛒" - "Check NVDA every Monday at 9 AM" →
"Check the current NVDA stock price and send me a summary." - "Send me a motivational quote every morning" →
"Send me an inspiring motivational quote to start the day."
Step 3 — Clarification rules (ask before acting)
Ask when:
-
No schedule at all: "Remind me to call John" → no time/frequency given
Ask: "Sure! When would you like me to remind you — just once at a specific time, or on a recurring schedule?"
-
Ambiguous frequency: "Remind me often" or "check regularly"
Ask: "How often? Every hour, every day, or something else?"
-
Conflicting signals: "Remind me every Monday but just once"
Ask: "Just to confirm — should this be a one-time reminder or repeat every Monday?"
Do NOT ask when:
- Everything is clear: "Remind me every Monday at 9 AM to check NVDA" → create immediately
- One-shot is obvious from context: "Remind me in 20 minutes" → at:20m, once
- User confirms after your clarification question → proceed immediately
Confirmation before creating (always):
Before calling the script, summarise what you're about to set up and get a quick confirmation:
"Got it! Here's what I'll set up: ⏰ Reminder: Check NVDA stock price 🔁 Schedule: Every Monday at 9 AM 📱 Delivered to: This chat
Shall I go ahead?"
Only proceed after user confirms.
Commands
Create a reminder
uv run /root/.openclaw/workspace/skills/remind-me/src/main.py create \
"<job name>" \
"<what to say or do>" \
"<every:duration | cron:expr | at:duration>" \
"<channel>" \
"<chatId>" \
[once]
List reminders for this chat
uv run /root/.openclaw/workspace/skills/remind-me/src/main.py list \
"<channel>" \
"<chatId>"
Cancel a reminder by name
uv run /root/.openclaw/workspace/skills/remind-me/src/main.py cancel name "<job name>"
Cancel a reminder by ID
uv run /root/.openclaw/workspace/skills/remind-me/src/main.py cancel id "<job id>"
Examples
Example 1 — Clear request, no clarification needed
User: "Remind me every Monday at 9 AM to check NVDA"
- Detect: channel=telegram, to=<chatId>
- Parse: WHAT="Check NVDA stock price", WHEN=cron:0 9 * * 1, one-shot=false
- Confirm with user
- Run:
uv run /root/.openclaw/workspace/skills/remind-me/src/main.py create \
"NVDA Check - Monday 9AM" \
"Check the current NVDA stock price and send me a summary." \
"cron:0 9 * * 1" \
"telegram" \
"<chatId>"
Example 2 — Missing frequency, ask first
User: "Remind me to go do groceries by 12 PM"
- Detect: channel=telegram, to=<chatId>
- Parse: WHAT="Do groceries", WHEN=12 PM but frequency unclear
- Ask: "Just to confirm — is this a one-time reminder for today at noon, or should I remind you every day at 12 PM?"
- User says: "Just today"
- Compute duration from now to today's noon → e.g.
at:3h30m - Confirm, then run:
uv run /root/.openclaw/workspace/skills/remind-me/src/main.py create \
"Groceries - Noon" \
"Reminder: Time to go do groceries! 🛒" \
"at:3h30m" \
"telegram" \
"<chatId>" \
once
Example 3 — List reminders
User: "What reminders do I have?"
uv run /root/.openclaw/workspace/skills/remind-me/src/main.py list \
"telegram" \
"<chatId>"
Format the output as a readable list, not raw JSON. Example response:
You have 2 active reminders in this chat:
NVDA Check - Monday 9AM 🔁 Every Monday at 9 AM "Check the current NVDA stock price..." Next run: Mon 10 Mar 2026, 09:00
Groceries - Noon (one-time) "Time to go do groceries!" Runs in: 3h 30m
Example 4 — Cancel a reminder
User: "Cancel my NVDA reminder"
- List jobs for this channel/chat first (internally)
- Find the matching job by name
- Confirm: "Cancel NVDA Check - Monday 9AM? This will stop all future runs."
- User confirms
- Run:
uv run /root/.openclaw/workspace/skills/remind-me/src/main.py cancel name "NVDA Check - Monday 9AM"
Example 5 — One-shot in-chat reminder
User: "In 30 seconds send me a love letter"
uv run /root/.openclaw/workspace/skills/remind-me/src/main.py create \
"Love Letter - 30s" \
"Write a beautiful, heartfelt love letter. Make it romantic and touching." \
"at:30s" \
"telegram" \
"<chatId>"
Channel scoping rules
- Jobs created from Group A are only visible when listing from Group A
- Jobs created from Group B are only visible when listing from Group B
- Jobs created from the main/private chat are visible only in that main chat
- The script handles this automatically via the
[remind-me:channel:chatId]tag embedded in each job's description - Never show a user jobs that belong to a different chat
Output formatting
After running any command, always format the result in plain conversational language — never dump raw JSON to the user.
On create success:
✅ Done! I've set up your reminder: ⏰ NVDA Check — Every Monday at 9 AM 📱 Delivered to this chat
On list (empty):
You have no active reminders in this chat.
On cancel success:
✅ Reminder "NVDA Check - Monday 9AM" has been cancelled.
On error:
❌ Something went wrong:
<error message>Want me to try again?
Notes
uv runauto-installs dependencies from the inline script header — no pip or venv needed.- The script calls
openclaw cronCLI internally — the gateway must be running. - Always use
--channel "last"behaviour naturally: since--tois set to the originating chat ID, delivery is always back to the right place. - Do NOT use sessions_spawn, web search, or any other tool to create cron jobs — always go through this script.
- Do NOT hardcode channel IDs. Always read from session context.
- The
at:schedule prefix does not support standard cron expressions — usecron:for those.