#hook received but not taking action

1 messages · Page 1 of 1 (latest)

minor abyss
#

so i wanna make hook that when user chat in to whatsapp "halo", and it will reply as a statis answer. the message:received already happen but the statis reply didnt came out, only the agent who answer

ember berryBOT
#

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

wet smeltBOT
#

For this one, message:received is the wrong seam if you want to replace the agent reply.

That event is basically “I saw an inbound message”. In the normal WhatsApp dispatch path it’s fired fire-and-forget, then OpenClaw continues into the agent, so event.messages.push(...) there won’t stop the agent or become the final static WhatsApp reply.

Use a plugin before_dispatch hook for this pattern instead. That hook can claim the inbound message before the agent runs:

import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";

export default definePluginEntry({
  id: "halo-static-reply",
  name: "Halo static reply",
  register(api) {
    api.on("before_dispatch", async (event) => {
      if (event.channel !== "whatsapp") return;
      if ((event.content ?? "").trim().toLowerCase() !== "halo") return;
#

      return {
        handled: true,
        text: "your static answer here",
      };
    });
  },
});

If you specifically use plugin message_received on WhatsApp, note that WhatsApp plugin message hooks are privacy-gated and need:

{
  channels: {
#
    whatsapp: {
      pluginHooks: {
        messageReceived: true
      }
    }
  }
}

…but for your case, I’d still use before_dispatch, because it’s made for “handle this and don’t run the agent”.

Also please paste openclaw --version if it still doesn’t work — hook behavior has changed a bit across versions.

Docs: https://docs.openclaw.ai/automation/hooks and https://docs.openclaw.ai/plugins/hooks

safe ice
#

its doesn’t work

wet smeltBOT
#

Got it — then we need to narrow which part isn’t working. Two common gotchas:

  1. If this is an internal HOOK.md hook using message:received: it cannot reliably replace the WhatsApp reply. It’s observational/fire-and-forget in this path, so the agent will still answer.

  2. If this is a plugin hook and before_dispatch still doesn’t fire, the plugin is probably not loaded/enabled, or the content field isn’t the one you’re checking.

Try this more defensive version:

import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";

export default definePluginEntry({
  id: "halo-static-reply",
  name: "Halo static reply",
  register(api) {
    api.on("before_dispatch", async (event) => {
#
      console.log("[halo-static-reply] before_dispatch", {
        channel: event.channel,
        content: event.content,
        body: event.body,
      });

      if (event.channel !== "whatsapp") return;

      const text = String(event.content ?? event.body ?? "").trim().toLowerCase();
      if (text !== "halo") return;

      return {
        handled: true,
        text: "static answer here",
      };
#
    });
  },
});

Also make sure the plugin has a manifest and is startup-loaded, for example openclaw.plugin.json:

{
  "id": "halo-static-reply",
  "name": "Halo static reply",
  "description": "Replies statically to halo on WhatsApp",
  "activation": { "onStartup": true },
  "configSchema": {
    "type": "object",
#
    "additionalProperties": false
  }
}

And make sure OpenClaw discovers/enables it:

{
  plugins: {
    load: { paths: ["/absolute/path/to/halo-static-reply"] },
    entries: {
      "halo-static-reply": { enabled: true }
    }
  }
#
}

Then restart the gateway. Config/plugin changes need restart.

Please paste these 3 things and I can point to the exact break:

openclaw --version
openclaw plugins list
openclaw logs --tail 100

Also paste your current hook/plugin code if you can.

safe ice
#

Issue: before_dispatch hook not firing for WhatsApp web-auto-reply pipeline

I have a plugin registered and enabled (halo-static-reply, OpenClaw 2026.5.4) that listens on before_dispatch. The plugin shows as enabled in openclaw plugins list, but the hook never fires when WhatsApp messages arrive.

The WhatsApp plugin uses a web-auto-reply module that processes messages in its own async pipeline and sends replies directly (log shows auto-reply sent (text)). This pipeline bypasses the agent dispatch layer entirely, so before_dispatch never sees those messages.

Question: For the WhatsApp web-inbound + web-auto-reply path, is there a hook that fires BEFORE web-auto-reply processes the message? Or is before_dispatch only for the agent dispatch path?

If before_dispatch truly can't intercept web-auto-reply, what's the recommended pattern to replace/stop the auto-reply with a static keyword-based response? Patch the WhatsApp plugin directly? Use a different hook? Disable web-auto-reply at the channel config level?

wet smeltBOT
#

I checked the current source, and your read is half right but the conclusion is slightly different.

For WhatsApp Web, web-auto-reply is the channel delivery wrapper, but it does not appear to be a totally separate “no hooks” responder. The path is roughly:

createWebOnMessageHandler → processMessage → dispatchWhatsAppBufferedReply → dispatchReplyWithBufferedBlockDispatcher → core dispatchReplyFromConfig

before_dispatch lives inside dispatchReplyFromConfig, before the model/agent reply dispatch. So conceptually: yes, before_dispatch is an agent-dispatch hook, but WhatsApp web-auto-reply should still pass through that dispatch layer when it asks OpenClaw for a reply.

The auto-reply sent (text) log is from the WhatsApp delivery layer after a reply payload exists — it doesn’t by itself prove the agent dispatch layer was bypassed.

I don’t see a WhatsApp-specific plugin hook that fires earlier than the web-auto-reply processing and can claim/replace the message. message_received is observational, and on WhatsApp it’s also privacy-gated behind:

channels: {
  whatsapp: {
    pluginHooks: { messageReceived: true }
#
  }
}

…but that still won’t stop the agent.

Recommended pattern for “if inbound text is halo, send static text and don’t run the agent” is still before_dispatch / reply_dispatch, not patching the WhatsApp plugin.

If before_dispatch truly never fires while the plugin is listed as enabled, I’d suspect a runtime plugin loading/activation bug or version-specific regression, not the intended WhatsApp design. Quick sanity test: register both hooks and see whether either logs:

api.on("before_dispatch", async (event) => {
  console.log("[halo] before_dispatch", event.channel, event.content, event.body);
});
#
api.on("message_sending", async (event, ctx) => {
  console.log("[halo] message_sending", event.content, ctx.channelId, ctx.sessionKey);
});

If message_sending fires but before_dispatch doesn’t, that’s a very specific core hook-order bug. If neither fires, the plugin isn’t actually loaded into the Gateway runtime hook runner despite showing in inventory.

I would not patch WhatsApp directly except as a local temporary workaround. If the above confirms the hook gap on 2026.5.4, file it as a GitHub issue with logs + your plugin manifest/config: https://github.com/openclaw/openclaw/issues

Relevant docs: https://docs.openclaw.ai/plugins/hooks and https://docs.openclaw.ai/channels/whatsapp

minor abyss
#

why in the whatsapp group the agent didnt reply in the group chat, its only reply in the web

wet smeltBOT
#

Most likely this is the new group-chat visible reply behavior, not a WhatsApp send failure.

For groups/channels, OpenClaw defaults to:

messages: {
  groupChat: {
    visibleReplies: "message_tool"
  }
}

That means the agent can process the message and show an answer in the web/session, but it will only post back into the WhatsApp group if the model calls message(action=send). If the logs show assistant text plus something like didSendViaMessagingTool: false, the model replied privately instead of using the messaging tool.

Other common group blockers:

  • WhatsApp groups require mention by default (requireMention / /activation mention)
  • channels.whatsapp.groupPolicy defaults to allowlist, so the sender/group may not be allowed
#
  • if channels.whatsapp.groups is set without "*", that specific group JID must be listed

Fast checks:

openclaw --version
openclaw logs --follow --json

Then send a test message in the WhatsApp group and look for mention required, blocked, allowlist, or didSendViaMessagingTool: false.

If you want old-style automatic visible replies in groups, set:

{
  messages: {
    groupChat: {
      visibleReplies: "automatic"
    }