Skip to main content
Filter, redact, or reject messages from Telegram, Slack, Discord, WhatsApp, and email before your agent sees them.

Quick Start

1

Allowlist — drop messages from unknown senders

2

PII redaction — rewrite content before the LLM sees it


How It Works


Decision Table

Hook exceptions are non-fatal. Raising an exception does not drop the message — the message passes through to the agent. Use HookResult.deny(...) to explicitly block.

Supported Adapters

Every built-in messaging adapter honours the gate decision:
Custom adapters must call fire_message_received and check the returned drop / content fields to participate in the gate.

Slack @mentions

The Slack app_mention handler fires MESSAGE_RECEIVED before allow-list checks, so @mentions now flow through the same gate as DMs (previously DM-only). Mentions also now count toward channel last_activity and increment messages_inbound_total, so an @mention registers as inbound activity for /health.
Even if the credential probe passes with SLACK_BOT_TOKEN, Socket Mode inbound needs SLACK_APP_TOKEN (xapp-…). Without it, praisonai gateway test appends SLACK_APP_TOKEN missing — Socket Mode will not start to probes.<channel>.details.warnings[] and mentions never arrive. See Gateway Readiness.

Quoted content in the hook

On Telegram, when a user replies to or quotes an earlier message, event_input.content for MESSAGE_RECEIVED is the rendered turn — the quoted block above the new text — so a redaction/deny hook can inspect and veto quoted text too. If the hook rewrites content, the separately-resolved quoted reference is cleared so unredacted quoted text can’t be re-appended after the hook runs. See Quoted Reply Context.

Common Patterns

Allowlist

Rate Limiter

Keyword Ban

Combined Gate + Redaction

Behaviour:
  • Blocked user’s messages: agent stays silent, no reply sent.
  • Messages containing an SSN pattern: LLM sees [SSN] instead of the digits.
  • All other messages: unchanged.

User Interaction Flow

A Telegram user sends a message. The gate runs before the agent responds:

Symmetry with Outbound

MESSAGE_RECEIVED (inbound) and MESSAGE_SENDING (outbound) share the same deny / modified_input contract. Use the same pattern for both directions:
For secrets specifically, you don’t have to hand-roll a hook. The built-in Outbound Secret Scrub runs after every MESSAGE_SENDING hook and masks registered secrets and credential-shaped tokens by default. Keep hooks for policies the core scrub doesn’t cover (PII, company-specific patterns).

Best Practices

The hook runs on every inbound message. Avoid blocking I/O or heavy computation — use in-memory lookups and pre-compiled regex patterns.
Raising an exception lets the message through. Explicitly call HookResult.deny(...) if you mean to block.
The LLM will see the modified_input content and may quote it back in replies. Only rewrite when necessary (e.g. PII scrubbing).
deny prevents agent dispatch entirely. modified_input still dispatches — use it only when you want the agent to respond to the sanitised content.

Hook Events

Complete reference for all hook events and input types

Bot Lifecycle Hooks

Gateway, session, and schedule lifecycle hooks

Quoted Reply Context

The hook sees the rendered turn, including any quoted block