#11597: feat(hooks): implement message:received hook
docs
stale
## Summary
Implements the `message:received` hook that was listed under "Future Events" in the docs. This hook triggers when a message is received before agent processing.
## Motivation
This enables custom hooks to:
- Log/analyze incoming messages in real-time
- Build experiential memory systems that score message importance
- Implement custom message filtering or tagging
- Track conversation patterns
## Implementation
- Added `message` to `InternalHookEventType`
- Added `MessageReceivedHookContext` and `MessageReceivedHookEvent` types
- Modified `dispatchInboundMessage` to trigger the hook
- Hook fires asynchronously (fire-and-forget) to avoid blocking message processing
- Commands (starting with `/`) do not trigger this hook (they have their own hooks)
## Context Fields
| Field | Type | Description |
|-------|------|-------------|
| `body` | string | Message text |
| `rawBody` | string? | Raw message without structural context |
| `senderId` | string? | Sender identifier |
| `channel` | string? | Originating channel (telegram, whatsapp, etc.) |
| `chatType` | string? | direct/group |
| `messageId` | string? | Provider message ID |
| `replyToId` | string? | Reply-to ID if applicable |
| `wasMentioned` | boolean? | Whether bot was mentioned |
| `workspaceDir` | string? | Agent workspace directory |
## Example Usage
```typescript
// In a custom hook handler.ts
const handler: HookHandler = async (event) => {
if (event.type !== "message" || event.action !== "received") {
return;
}
const { body, senderId, channel } = event.context;
console.log(`Message from ${senderId} on ${channel}: ${body}`);
// Score importance, save to memory, etc.
};
export default handler;
```
## Testing
- Added unit tests for the hook trigger
- Verified commands do not trigger the hook
- Verified empty messages do not trigger the hook
## Documentation
- Updated `docs/automation/hooks.md` to move `message:received` from Future Events to implemented
- Documented context fields
Co-authored-by: Tony Xia <xia.tony@gmail.com>
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
Implements a new internal hook event `message:received` and wires it into the inbound message dispatch path so custom hooks can observe non-command messages before agent processing. Adds the corresponding internal hook event types/guards, updates hook documentation, and adds unit tests intended to verify the hook fires for normal messages and not for commands/empty bodies.
<h3>Confidence Score: 3/5</h3>
- This PR is close to mergeable but has test reliability issues and a likely mismatch between documented and actual command suppression behavior.
- Core hook wiring is straightforward, but the added Vitest tests use `vi.mock()` inside `it()` blocks (non-deterministic due to hoisting/module cache) and the command-skip logic in `dispatchInboundMessage` only checks `Body/RawBody`, which may not cover all command inputs used elsewhere in the pipeline.
- src/auto-reply/dispatch-hooks.test.ts, src/auto-reply/dispatch.ts
<!-- 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
#7580: feat: add message:received internal hook with prompt injection
by rodrigoschott · 2026-02-03
90.7%
#7545: feat(hooks): add message:received hook for pre-turn automation
by wangtian24 · 2026-02-02
89.4%
#19922: feat(hooks): add message:received and message:sent hook events
by NOVA-Openclaw · 2026-02-18
88.7%
#10706: feat(hooks): add message:received internal hook for Telegram
by thebtf · 2026-02-06
86.9%
#10109: feat(plugins): invoke message_received and message_sent hooks
by nezovskii · 2026-02-06
84.3%
#19565: feat: add agent lifecycle hook events (session, message, error)
by tag-assistant · 2026-02-17
83.0%
#6630: feat(hooks): add agent:turn_start and agent:turn_end lifecycle events
by drdigital13 · 2026-02-01
82.1%
#16618: feat: bridge message lifecycle hooks to workspace hook system
by DarlingtonDeveloper · 2026-02-14
81.1%
#15577: feat(hooks): add message:preprocessed hook event
by heybeaux · 2026-02-13
81.0%
#9906: feat: wire message_sending hook in outbound delivery
by teempai · 2026-02-05
80.3%