← Back to Skills Marketplace
robbeverhelst

Wakehook

by Robbe Verhelst · GitHub ↗ · v1.0.0 · MIT-0
cross-platform ⚠ suspicious
37
Downloads
1
Stars
0
Active Installs
1
Versions
Install in OpenClaw
/install wakehook
Description
Install, configure, authorize and run wakehook so OpenClaw runs the user's morning routine when they wake up. wakehook turns Google Health / Fitbit sleep dat...
README (SKILL.md)

wakehook → OpenClaw

wakehook is a tiny self-hosted service that watches the user's sleep data (Google Health / Fitbit), detects the moment they woke up, and POSTs OpenClaw a neutral user.awake event so the morning routine runs itself — at most once per morning. OpenClaw maps that event into a wake action (its native pattern), so wakehook stays vendor-neutral.

Work through the steps in order. Ask the user at the decision points instead of assuming. Do not improvise from the README — these steps are verified.

Prerequisites (check, don't assume)

  1. Bun ≥ 1.3bun --version; install with curl -fsSL https://bun.sh/install | bash. wakehook is Bun-only (bun:sqlite); never run it with Node.
  2. Google OAuth credentials — a Google Cloud project with the Health API enabled and the googlehealth.sleep.readonly scope, plus an OAuth 2.0 client (client id + secret). An API key will NOT work; sleep data needs user-consented OAuth. Ask the user for the id + secret (reuse their existing Google project if they have one).

Step 1 — add an OpenClaw mapped hook

wakehook POSTs the raw user.awake event to an OpenClaw mapped hook; OpenClaw turns it into a wake of the main session via hooks.mappings. In the OpenClaw gateway config:

{
  hooks: {
    enabled: true,
    path: "/hooks",            // must not be "/"
    token: "\x3CHOOKS_TOKEN>",    // any strong random string
    mappings: [
      {
        match: { path: "wakehook" },   // matches POST /hooks/wakehook
        action: "wake",
        wakeMode: "now",
        name: "wakehook",
        // reads fields straight from wakehook's user.awake event:
        messageTemplate: "You woke at {{wokeAt}} (slept {{session.durationMin}} min).",
      },
    ],
  },
}

Note the gateway address (host + port — OpenClaw's docs examples use 127.0.0.1:18789; confirm the user's actual port). The delivery URL is then http://\x3Cgateway-host>:\x3Cport>/hooks/wakehook, and \x3CHOOKS_TOKEN> is the token wakehook must present. (Verified: /hooks/* is gated by the token in a header — Authorization: Bearer \x3Ctoken> or x-openclaw-token: \x3Ctoken>; query-string tokens are rejected. The mapping then renders messageTemplate and wakes the session.)

Step 2 — choose how wakehook gets the sleep data (ask the user)

Two modes — confirm which they want; don't assume:

  • poll (recommended default) — wakehook pulls from Google on a timer. No public URL / tunnel / open port (all outbound). By default it only polls around the morning window and stops once it has fired today (pollWindowOnly), so a short pollIntervalMs (5 min default) is cheap — wake is detected within one interval. This path is verified end-to-end.
  • webhook — Google pushes the instant data lands → fires immediately, but requires a public HTTPS endpoint for wakehook plus registering a Google Health sleep subscription. ⚠️ This path is not yet verified — only choose it if the user explicitly wants instant fires and can expose an endpoint.

If the user has no preference, use poll.

Step 3 — configure wakehook

Create config.json in the working directory. Set timezone to the user's IANA zone, the subscriber url to the mapped hook from Step 1, and pass the \x3CHOOKS_TOKEN> as the Authorization header:

{
  "dbPath": "./wake.sqlite",
  "source": "google-health",
  "inference": {
    "timezone": "Europe/Brussels",
    "windowStart": "04:00",
    "windowEnd": "11:00",
    "minDurationMin": 180,
    "supersedeGapMin": 45
  },
  "google": { "mode": "poll", "pollIntervalMs": 300000, "pollLookbackMin": 720, "pollWindowOnly": true, "pollWindowMarginMin": 30 },
  "subscribers": [
    {
      "id": "openclaw",
      "url": "http://\x3Cgateway-host>:\x3Cport>/hooks/wakehook",
      "headers": { "Authorization": "Bearer \x3CHOOKS_TOKEN>" }
    }
  ]
}

No preset needed — generic (the raw signed event) is the default and is what the OpenClaw mapping expects. \x3CHOOKS_TOKEN> must equal the gateway's hooks.token from Step 1.

If the user chose webhook mode instead: set "google" to { "mode": "webhook", "webhookAuthToken": "\x3Crandom>" }, also put GOOGLE_WEBHOOK_AUTH_TOKEN in .env, expose wakehook's /webhook over public HTTPS, and register a Google Health sleep subscription pointing at it. (Unverified.)

Create .env (keep secrets out of config.json):

GOOGLE_CLIENT_ID=\x3Cclient-id>
GOOGLE_CLIENT_SECRET=\x3Cclient-secret>
GOOGLE_REDIRECT_URI=http://localhost:8080/oauth/callback

Ensure http://localhost:8080/oauth/callback is an authorized redirect URI on the OAuth client.

Step 4 — authorize once

bunx wakehook-auth

Prints a Google consent URL — give it to the user to open and approve. It stores a refresh token in ./wake.sqlite and auto-refreshes forever (one-time step). If Google returns HTTP 400, the OAuth client is missing the localhost:8080/oauth/callback redirect URI — add it and retry.

Step 5 — run it

bunx wakehook

(Docker alt: docker run -v wakehook-data:/data --env-file .env ghcr.io/robbeverhelst/wakehook.) Keep it running (long-lived process / service). In poll mode it polls Google every pollIntervalMs around the morning window only (set pollWindowOnly: false to poll all day) and, on the morning wake, POSTs OpenClaw once.

Step 6 — decide what happens on wake (optional)

By default the Step-1 mapping just nudges the main session. To make waking up do something, shape the behavior in the mapping (this is OpenClaw-side config, not wakehook). wakehook only supplies the trigger; the actual abilities (calendar, weather, messages, …) come from OpenClaw's own skills/tools — install/enable those separately.

A — simple nudge, routine in the prompt (action: "wake"): make messageTemplate the instruction the main session executes.

{
  match: { path: "wakehook" },
  action: "wake",
  wakeMode: "now",
  messageTemplate: "Good morning — the user just woke ({{wokeAt}}). Run the morning routine: review today's calendar, summarize overnight messages, and give the weather.",
}

B — full routine run on a dedicated agent (action: "agent"): route to an agent that has the relevant skills, and deliver the result to a chat surface.

{
  match: { path: "wakehook" },
  action: "agent",
  agentId: "morning",          // an agent you've set up with calendar/weather/etc. skills
  wakeMode: "now",
  messageTemplate: "User woke at {{wokeAt}} (slept {{session.durationMin}} min). Produce the morning briefing.",
  deliver: true,               // send the result back to a chat surface…
  channel: "last",             // …e.g. Telegram/Discord (defaults to last used)
}

Note: you generally don't trigger a cron from this — wakehook is the real wake signal, so it replaces guessing a fixed time. Just run the task on the event. The capabilities themselves are separate OpenClaw skills; this step only wires when and what to ask for.

What OpenClaw receives

wakehook POSTs the raw, neutral event (the OpenClaw mapping templates it):

POST http://\x3Cgateway-host>:\x3Cport>/hooks/wakehook
Authorization: Bearer \x3CHOOKS_TOKEN>
Content-Type: application/json

{ "event": "user.awake", "wokeAt": "2026-06-13T08:04:00Z", "user": "self",
  "source": "google-health",
  "session": { "start": "...", "end": "2026-06-13T08:04:00Z", "durationMin": 464 } }

The Step-1 mapping turns this into a now wake of the main session with the templated text — handle that as the trigger to run the morning routine. wakehook also sends X-Wake-Event-Id (and X-Wake-Signature if a secret is set) for optional extra verification. Fires at most once per morning.

Verify without waiting for morning

curl -X POST http://localhost:8080/test/replay \
  -H 'Content-Type: application/json' -d '{}'

Injects a synthetic wake "now" and delivers it exactly like a real one — confirm OpenClaw maps it and runs the routine.

Gotchas

  • Bun-only — never run with Node.
  • The Authorization bearer MUST equal OpenClaw's gateway hooks.token, or /hooks/wakehook rejects it (401). Hooks must be enabled and the mapping (match.path: "wakehook") must exist, or the path won't route.
  • poll needs the OAuth creds but no inbound URL; webhook is instant but unverified — prefer poll unless the user asks otherwise.
  • A Google API key is not enough — it needs the OAuth client + wakehook-auth.
  • If the hook returns 200 but nothing happens, check the OpenClaw version (a known issue affected some 2026.3.x builds) and that the mapping action: "wake" is set.

Source + full docs: https://github.com/robbeverhelst/wakehook

Usage Guidance
Review before installing. Use poll mode if possible, keep the service bound to localhost or behind trusted access controls, set a webhook auth token even for testing, avoid exposing /test/replay publicly, send wake events only to trusted HTTPS subscribers, and protect or encrypt the SQLite database containing Google refresh tokens.
Capability Tags
cryptorequires-oauth-tokenrequires-sensitive-credentials
Capability Assessment
Purpose & Capability
Core behavior matches the stated wake automation purpose, but the artifacts also describe a vendor-neutral fan-out bus that can send wake events to arbitrary configured URLs, which is broader than the OpenClaw-focused skill description.
Instruction Scope
The setup asks for Google OAuth credentials and a long-lived service, and the test replay route can synthesize wake events that may trigger downstream routines; in the recommended poll setup this route is not clearly required to be authenticated.
Install Mechanism
Installation uses normal Bun/npm/Docker paths, but the SKILL.md suggests installing Bun with a pipe-to-shell command, which is a supply-chain risk even though it is not evidence of malicious behavior in this package.
Credentials
Reading sleep data, storing refresh tokens, polling Google Health, and posting to configured subscribers are proportionate for wake automation, but the sensitivity of health-derived wake data requires tighter destination and exposure guidance.
Persistence & Privilege
The service persists OAuth access and refresh tokens in a local SQLite database and keeps running as a long-lived process; this is disclosed and functional, but high impact if the host, database, or exposed endpoint is not well protected.
How to Use
  1. Make sure OpenClaw is installed (local or Docker)
  2. Run the install command in chat: /install wakehook
  3. After installation, invoke the skill by name or use /wakehook
  4. Provide required inputs per the skill's parameter spec and get structured output
Version History
v1.0.0
wakehook 1.0.0 — Initial release - Enables OpenClaw to automatically run the user’s morning routine based on Google Health or Fitbit wake events. - Supports both polling and webhook modes for detecting when the user wakes up, with polling as the recommended default. - Provides step-by-step setup, including prerequisites, OpenClaw hook mapping, and secure OAuth configuration. - Handles user consent and securely stores tokens for ongoing access. - Posts neutral user.awake events to OpenClaw, allowing flexible automations triggered on wake. - OpenClaw mapping determines the specific routine or actions to run when wakehook detects the user is awake.
Metadata
Slug wakehook
Version 1.0.0
License MIT-0
All-time Installs 0
Active Installs 0
Total Versions 1
Frequently Asked Questions

What is Wakehook?

Install, configure, authorize and run wakehook so OpenClaw runs the user's morning routine when they wake up. wakehook turns Google Health / Fitbit sleep dat... It is an AI Agent Skill for Claude Code / OpenClaw, with 37 downloads so far.

How do I install Wakehook?

Run "/install wakehook" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.

Is Wakehook free?

Yes, Wakehook is completely free, licensed under MIT-0. You can download, install and use it at no cost.

Which platforms does Wakehook support?

Wakehook is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).

Who created Wakehook?

It is built and maintained by Robbe Verhelst (@robbeverhelst); the current version is v1.0.0.

💬 Comments