Reference
Message middleware (inbound pipeline)
FluxyChat runs every inbound chat message through a shared pipeline before it is stored or broadcast (WebSocket `type: "message"` and `POST /messages`).
FluxyChat runs every inbound chat message through a shared pipeline before it is stored or broadcast (WebSocket type: "message" and POST /messages).
Stages
- Validate — non-empty string, max 4000 chars (
validateMessageContent). - Filter — optional block when
MESSAGE_MIDDLEWARE_BLOCK_ON_MATCH=trueand content matchesBUILTIN_MODERATION_BLOCKED_SUBSTRINGS(comma-separated, case-insensitive). - Enrich — optional metadata tag when
MESSAGE_MIDDLEWARE_ENRICH_TAGis set (exposed on the broadcast payload asmiddleware).
Rejected messages return:
- WebSocket:
\{ type: "error", message: "content_blocked: …" \}orinvalid_content: … - REST:
403/400with\{ error, code \}
Environment
| Variable | Default | Effect |
|---|---|---|
MESSAGE_MIDDLEWARE_BLOCK_ON_MATCH | off | Block send on substring match (not only post-hoc auto-flag) |
BUILTIN_MODERATION_BLOCKED_SUBSTRINGS | — | Shared with post-message moderation scan |
MESSAGE_MIDDLEWARE_ENRICH_TAG | — | Adds middleware.enrichTag on outbound WS payload |
Implementation
apps/worker/src/lib/message-middleware.js—runInboundMessageMiddleware- Wired in
room-do.jsandroutes/messages-http.js
Post-persist moderation (auto-flag to moderation_events) remains in post-message-automations.js when block-on-match is off.
AI agent + human handoff (P12-H)
Intercom-Fin-style flow: an in-room AI agent responds until a human operator takes over. Handoff pauses AI invokes, enqueues an agent task with thread context,
Feature flags (P12-J)
FluxyChat evaluates [Cloudflare Flagship](https://developers.cloudflare.com/flagship/) flags via `env.FLAGS` when bound, with legacy env fallbacks for local dev