#Triggering OpenClaw Agent from external script — what we tried

1 messages · Page 1 of 1 (latest)

pure heart
#

Triggering OpenClaw Agent from external script — what we tried

Goal: Send a message from a bash script into the agent's running main session and trigger it to work instantly on that task.

1️⃣ openclaw agent --agent miro --message "..." --timeout 0
→ Message stored in transcript, no trigger. Fire-and-forget.

2️⃣ openclaw message send --channel signal --target "<NUMBER>" --message "..."
→ Sends to user via Signal. Agent not triggered. ~20s CLI startup on Pi.

3️⃣ openclaw agent --agent miro --message "..." --deliver --reply-channel signal
→ Starts new isolated session (not the running one). Reply is contextless.

4️⃣ Same with --session-id <ID> (parsed from sessions.json)
→ Same result: new session, message NOT injected into running session.

5️⃣ Same with --to "<NUMBER>" instead of --agent
→ Same result: new session.

6️⃣ Cron workaround: disabled cron job + openclaw cron run
→ systemEvent injected into transcript but doesn't trigger a turn (Issue #11726). Only processed at next heartbeat.

full sedgeBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> ✅ Mark Solution

jolly canopyBOT
#

Yep — the closest supported path for “external script wakes the main session now” is system event + heartbeat, not message send.

Try this first:

openclaw --version

openclaw system heartbeat enable

openclaw system event \
  --text "External task: do the thing now" \
  --mode now \
  --json

system event --mode now enqueues a system event into the main session and requests an immediate heartbeat; it’s injected as a System: line, not as a normal user chat message. Docs: https://docs.openclaw.ai/cli/system (docs.openclaw.ai)

#

For the Pi startup delay, use the HTTP hook instead of launching the CLI:

{
  hooks: {
    enabled: true,
    token: "shared-secret",
    path: "/hooks",
  },
}
curl -sS -X POST http://127.0.0.1:18789/hooks/wake \
  -H "Authorization: Bearer $OPENCLAW_HOOK_TOKEN" \
  -H "Content-Type: application/json" \
#
  -d '{"text":"External task: do the thing now","mode":"now"}'

That avoids the ~20s CLI cold start and is the intended external-trigger path. Keep it loopback/tailnet/reverse-proxy protected and use a dedicated hook token. Docs: https://docs.openclaw.ai/automation/cron-jobs#webhooks (docs.openclaw.ai)

A few clarifications on what you tried:

  • openclaw message send is outbound chat delivery only; it won’t trigger the agent.
  • openclaw agent --agent miro --message ... should run a one-shot agent turn through the Gateway, but it’s not “inject this as an inbound chat message into the live running turn.” Delivery flags only affect where the reply goes. Docs: https://docs.openclaw.ai/cli/agent (docs.openclaw.ai)
  • /hooks/agent is also available, but it runs an isolated agent turn, so it’s expected to feel contextless unless that’s what you want. (docs.openclaw.ai)
  • Cron main-session jobs are basically the scheduled version of “system event + wake”; isolated cron jobs are fresh sessions. (docs.openclaw.ai)

If system event --mode now or /hooks/wake still only processes on the next heartbeat, please paste openclaw --version and the relevant openclaw logs --follow lines — that would be the real bug path to chase.

pure heart
#

The hook does not trigger the agent.
In openclaw.json I have configured heartbeat.every = 0m is this an issue.

jolly canopyBOT
#

Yes — if that’s agents.defaults.heartbeat.every: "0m" or agents.list[].heartbeat.every: "0m", it disables heartbeats, and /hooks/wake works by requesting a heartbeat run. So the hook can accept/enqueue the event but the agent run gets skipped as disabled.

First please paste:

openclaw --version

Then try:

{
  agents: {
    defaults: {
      heartbeat: {
        every: "30m",   // 0m disables
#
        target: "last"  // or signal + to if you want explicit delivery
      }
    }
  }
}

Restart after changing it:

openclaw gateway restart

Then test:

#
curl -sS -X POST http://127.0.0.1:18789/hooks/wake \
  -H "Authorization: Bearer $OPENCLAW_HOOK_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"text":"External task: please handle this now","mode":"now"}'

Two gotchas:

  1. If you’re using /hooks/wake, that wakes the main/default heartbeat path, not a normal inbound user message.
  2. If target is left as default none, it may run but not visibly deliver a reply. Check:
openclaw system heartbeat last --json
openclaw logs --follow