?

Scenario

You want a daily nudge on WhatsApp at 09:00 asking whether the code-review inbox has anything stale. The agent should read your local review-queue file, summarise, and deliver the summary to your phone — no matter whether your laptop is in the middle of another task.

The moving parts:

  • A running rousseau whatsapp daemon.
  • A cron job persisted in SQLite via rousseau cron add.
  • The robfig/cron/v3 scheduler goroutine inside the daemon fires the job; the reply is dispatched through the same WhatsApp transport.

Prerequisites

  • rousseau whatsapp paired and delivering messages to at least one JID (First transport).
  • A file the prompt can point at — for this walkthrough, a Markdown queue at /workspace/review-queue.md.

Step 1 — Register the job

rousseau cron add \
  --name daily-review-nag \
  --schedule "0 9 * * *" \
  --prompt "Read /workspace/review-queue.md and list every PR that has been open for more than 3 days. Reply with 3 bullets max." \
  --deliver-to 447900123456@s.whatsapp.net

--schedule is a 5-field POSIX-style cron expression parsed by robfig/cron/v3 (min hour dom mon dow). Rousseau validates the expression at add time; an invalid schedule fails fast before it lands in the store.

--deliver-to is the WhatsApp JID that will receive the reply. For groups, use the @g.us form.

Step 2 — Confirm the job is live

rousseau cron list

Output:

b7a3f2e1  on   daily-review-nag      0 9 * * *             last=never
    Read /workspace/review-queue.md and list every PR that has been open for more than 3 days. Reply with 3 bullets max. → 447900123456@s.whatsapp.net

New jobs become live within the next scheduler poll interval (default 60 seconds). No restart required.

Step 3 — Force a dry run

Scheduled jobs are fired by the running rousseau whatsapp daemon. To verify the wiring without waiting until 09:00, temporarily change the schedule to run one minute from now:

rousseau cron remove daily-review-nag
rousseau cron add \
  --name daily-review-nag \
  --schedule "*/1 * * * *" \
  --prompt "..." \
  --deliver-to 447900123456@s.whatsapp.net

Watch the daemon's log:

cron.fire   name=daily-review-nag job=b7a3f2e1
tool.execute name=read id=t_1
cron.deliver name=daily-review-nag target=447900123456@s.whatsapp.net bytes=284

Once you see the message on your phone, delete the every-minute copy and re-add the daily version.

Step 4 — Disable without deleting

rousseau cron disable daily-review-nag

Toggling enabled=false leaves the job in the store but skips it on every fire. Re-enable with rousseau cron enable daily-review-nag.

What happens under the hood

  1. rousseau cron add writes a row to the cron table in ~/.local/share/rousseau/sessions.db.
  2. The rousseau whatsapp daemon starts a robfig/cron/v3 scheduler goroutine at boot and polls the table every PollInterval (60s default).
  3. When the cron expression fires, Runner.RunOnce(ctx, prompt) runs a one-shot agent turn against a fresh session (no history from prior fires).
  4. The reply passes through Delivery — a transport-agnostic callback the daemon wires to client.Deliver(ctx, target, body).
  5. last_run_at is updated in the store. Failures are logged but do not disable the job.

The scheduler is durable: if the daemon dies mid-fire, the next launch picks up the queue. Jobs never fire twice for the same minute because robfig/cron/v3 deduplicates by tick.

Common patterns

Schedule Meaning
0 9 * * * 09:00 every day.
*/15 9-17 * * 1-5 Every 15 minutes, 09:00–17:59, Mon–Fri.
0 * * * * Top of every hour.
0 0 * * 0 Midnight every Sunday.

Layering with skills

Long prompts get tedious. If a scheduled job's prompt keeps growing, move the boilerplate into a skill and let the prompt reference it. The skill is spliced into the system prompt at fire time.

Caveats

  • Scheduled jobs run against the daemon's configured provider. If your primary provider is claudecli and you rotate the underlying claude login, the fire fails until you re-authenticate.
  • The delivery target must belong to the daemon's allowlist. Rousseau will not deliver to an out-of-allowlist JID even if a scheduled job asks it to.
  • The cron scheduler runs inside the rousseau whatsapp daemon by design. Running rousseau slack alongside gives you two independent schedulers reading the same table — jobs will fire twice. Pick one daemon to own the schedule.

Next

Type to search 150+ pages. Ranking: BM25 with title/description boost.