OpenClaw integration

OpenClaw runs on the same box (gateway 127.0.0.1:18789). Two directions, both over loopback:

Events → OpenClaw → Telegram

Subscriptions with "target": "openclaw" are delivered to OpenClaw's inbound webhook (POST /hooks/agent, docs: docs/automation/cron-jobs/webhooks.md in the openclaw package). Each event starts a fresh, isolated agent turn whose reply is delivered to Evan's Telegram:

POST http://127.0.0.1:18789/hooks/agent
Authorization: Bearer <LOCATION_OPENCLAW_HOOK_TOKEN>
{
  "message": "[location-service event] Entered geofence 'Home' (...)\nEvent type: ...\nSubscription note ...\nFix: ...",
  "name": "location geofence.entered",
  "agentId": "main",
  "deliver": true, "channel": "telegram", "to": "8853252411",
  "idempotencyKey": "<event id>"
}

OpenClaw answers 200 {"ok":true,"runId":…} on admission; that counts as delivered. The event id is the idempotency key, so a retried delivery does not start a second turn.

OpenClaw config set by scripts/deploy.sh (deploy/remote-setup.sh), nothing else touched:

hooks: {
  enabled: true,
  token: "<LOCATION_OPENCLAW_HOOK_TOKEN>",   // dedicated; not the gateway token
  path: "/hooks",
  allowedAgentIds: ["main"],
  allowRequestSessionKey: false,
}

The hook endpoint is only reachable on loopback: Caddy's openclaw.evanrthomas.com site sits behind Google login (oauth2-proxy), and location.evanrthomas.com proxies only to the location service.

Service-side settings (systemd unit deploy/location-service.service): LOCATION_OPENCLAW_HOOK_URL, LOCATION_OPENCLAW_DELIVER_CHANNEL=telegram, LOCATION_OPENCLAW_DELIVER_TO=8853252411; the hook token comes from /etc/location-service/location.env.

OpenClaw → location service (the location skill)

ethomas2/openclaw-ec2/skills/location/SKILL.md, installed to ~/.openclaw/workspace/skills/location/. It teaches the agent to curl $LOCATION_API_URL with Authorization: Bearer $LOCATION_API_TOKEN to read current location/history and to create/list/delete subscriptions (with target: "openclaw" and a note, e.g. "remind me to buy milk when I get to Trader Joe's"). Both env vars are in ~/.openclaw/gateway.systemd.env (mode 600).

Checking it

# on the box
journalctl -u location-service -f                      # "delivered event …" / "delivery … failed"
openclaw logs --follow | grep -i 'hook agent'         # "hook agent run completed"