OpenClaw runs on the same box (gateway 127.0.0.1:18789). Two directions, both over loopback:
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.
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).
# on the box
journalctl -u location-service -f # "delivered event …" / "delivery … failed"
openclaw logs --follow | grep -i 'hook agent' # "hook agent run completed"