Back to Knowledge Base
Automation

How do I create a custom hook?

Hooks let you automate actions when events (like /new, /reset, or startup) occur.

Hooks allow you to run custom TypeScript code when specific events occur in OpenClaw. They are powerful tools for auditing commands, persisting memory snapshots, or triggering external automations (like effective zapier-style workflows) whenever a user interacts with your agent.

A hook is simply a directory containing two essential files: HOOK.md (for metadata and discovery) and handler.ts (for the executable logic).

Step 1: Create the directory

Hooks are automatically discovered from standard locations. You can place them in ~/.openclaw/hooks/ for global availability across all agents, or in <workspace>/hooks/ for agent-specific logic.

mkdir -p ~/.openclaw/hooks/my-greeter

Step 2: Define metadata (HOOK.md)

The HOOK.md file uses YAML frontmatter to tell OpenClaw's plugin system how to load your hook. The events array is critical—it defines exactly which triggers will wake up your handler.

---
name: my-greeter
description: 'Says hello when you run /new'
metadata:
  openclaw:
    emoji: '👋'
    events: ['command:new'] # Triggers only when /new is detected
---

# My Greeter Hook

This hook sends a welcome message when a new session starts.
Docs: https://docs.openclaw.ai/hooks

Step 3: Write Logic (handler.ts)

Your `handler.ts` exports a default function that receives an `event` object. This object contains all the context you need, including the session ID, the user's message, and a mutable `messages` array for sending replies.

import type { HookHandler } from "../../src/hooks/hooks.js";

const handler: HookHandler = async (event) => {
  // 1. Validate the event context
  // It is good practice to double-check event types, even if filtered by metadata.
  if (event.type !== "command" || event.action !== "new") {
    return;
  }

  // 2. Perform your custom logic
  console.log(`[my-greeter] New session started for session: ${event.sessionKey}`);
  
  // 3. Interact with the user
  // Pushing strings to event.messages sends them back to the user immediately.
  event.messages.push("👋 Hello! I am your custom greeter hook.");
};

export default handler;

Step 4: Enable it

For security, new hooks are disabled by default. You must explicitly enable them via the CLI and restart the gateway for changes to take effect.

# 1. Verify the hook is discovered
openclaw hooks list

# 2. Enable it by name
openclaw hooks enable my-greeter

# 3. Restart the gateway to load the new handler
openclaw gateway restart

Troubleshooting

If your hook isn't firing, check the gateway logs. OpenClaw logs hook registration at startup.

openclaw logs --follow

Look for lines like Registered hook: my-greeter -> command:new. If you don't see them, run openclaw hooks info my-greeter to check for missing requirements or syntax errors in your `HOOK.md`.

Pro Tip: Event Types

You can listen for a variety of lifecycle events to build complex workflows:

  • command:new - Triggered on session reset.
  • command:stop - Triggered when a task is aborted.
  • gateway:startup - Runs once when OpenClaw boots (useful for background jobs).
  • tool_result_persist - Intercept and modify tool outputs before they save to memory.