← Back to PRs

#7545: feat(hooks): add message:received hook for pre-turn automation

by wangtian24 open 2026-02-02 23:38 View on GitHub →
docs channel: whatsapp-web
## Summary Adds a new hook event type `message:received` that fires before a message is processed by the agent. This enables: - Running custom logic on incoming messages (e.g., memory curation with memfas) - Injecting context into the message body via `injectedContext` - Optionally skipping message processing via `skipProcessing` ## Changes - **`src/hooks/internal-hooks.ts`**: Added `MessageReceivedHookContext` type and `isMessageReceivedEvent()` guard - **`src/web/auto-reply/monitor/on-message.ts`**: Wired up hook for WhatsApp channel - **`src/hooks/internal-hooks.test.ts`**: Added 10 new tests (28 total, all passing) ## Hook Context ```typescript type MessageReceivedHookContext = { message: string; messageId?: string; senderId?: string; senderName?: string; channel: string; chatId?: string; isGroup: boolean; sessionKey: string; agentId: string; injectedContext?: string; // mutable - prepended to message skipProcessing?: boolean; // mutable - skip agent turn skipReason?: string; // mutable - logged if skipped }; ``` ## Usage ```typescript // hooks/my-hook.js export default async function(event) { if (event.type !== 'message' || event.action !== 'received') return; // Inject context event.context.injectedContext = 'Relevant memory: user likes pizza'; // Or skip processing if (isSpam(event.context.message)) { event.context.skipProcessing = true; event.context.skipReason = 'spam detected'; } } ``` ## Future Work - Wire up other channels (Discord, Telegram, Slack, Signal, iMessage) - The pattern is identical - just add the hook trigger before each channel's dispatch Closes #7541 <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR introduces a new internal hook event `message:received` (type `message`, action `received`) with a dedicated context shape and a runtime type guard (`src/hooks/internal-hooks.ts`). The WhatsApp web auto-reply handler now triggers this hook before calling `processMessage()`, allowing hooks to request skipping processing or to inject a context prefix into the inbound message (`src/web/auto-reply/monitor/on-message.ts`). Tests were extended to cover handler registration/triggering and the new `isMessageReceivedEvent` guard (`src/hooks/internal-hooks.test.ts`). Key items to double-check before merging: - The current injection path mutates `msg.body` but `processMessage()` still computes and logs `combinedBody` separately, so the agent input (`RawBody`) and the logged/contextual `Body` can diverge. - The lockfile now contains two axios snapshot variants; ensure this is intentional and produced by the expected pnpm version/settings. <h3>Confidence Score: 3/5</h3> - This PR is reasonably safe to merge but has a couple of behavioral/consistency concerns worth addressing. - Core hook plumbing and tests look straightforward, but the WhatsApp wiring currently injects context by mutating `msg.body` in a way that can diverge from how `processMessage()` constructs/logs `combinedBody`, and the pnpm-lock change introduces an additional axios resolution variant that should be verified as intentional. - src/web/auto-reply/monitor/on-message.ts, pnpm-lock.yaml <!-- greptile_other_comments_section --> <sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub> <!-- /greptile_comment -->

Most Similar PRs