Skip to content

Multi-Channel Overview

Triggerfish connects to your existing messaging platforms. You talk to your agent wherever you already communicate -- terminal, Telegram, Slack, Discord, WhatsApp, a web widget, or email. Every channel is a first-class citizen with its own classification level, owner identity checks, and policy enforcement.

How Channels Work

Every channel adapter implements the same interface: connect, disconnect, send, onMessage, and status. The channel router sits above all adapters and handles message dispatch, classification checks, and retry logic.

   Telegram  Slack  Discord  WhatsApp  WebChat  Email  CLI
      |        |       |        |         |       |     |
      +--------+-------+--------+---------+-------+-----+
                              |
                        Channel Router
                     (classification gate)
                              |
                        Gateway Server

When a message arrives on any channel, the router:

  1. Identifies the sender (owner or external) using code-level identity checks -- not LLM interpretation
  2. Tags the message with the channel's classification level
  3. Forwards it to the policy engine for enforcement
  4. Routes the agent's response back through the same channel

Channel Classification

Each channel has a default classification level that determines what data can flow through it. The policy engine enforces the no write-down rule: data at a given classification level can never flow to a channel with a lower classification.

ChannelDefault ClassificationOwner Detection
CLIINTERNALAlways owner (terminal user)
TelegramINTERNALTelegram user ID match
SlackPUBLICSlack user ID via OAuth
DiscordPUBLICDiscord user ID match
WhatsAppPUBLICPhone number match
WebChatPUBLICNever owner (visitors)
EmailPUBLICEmail address match

Fully Configurable

All classifications are configurable in your triggerfish.yaml. You can set any channel to any classification level based on your security requirements.

yaml
channels:
  telegram:
    classification: CONFIDENTIAL
  slack:
    classification: INTERNAL

Effective Classification

The effective classification for any message is the minimum of the channel classification and the recipient classification:

Channel LevelRecipient LevelEffective Level
INTERNALINTERNALINTERNAL
INTERNALEXTERNALPUBLIC
CONFIDENTIALINTERNALCONFIDENTIAL
CONFIDENTIALEXTERNALPUBLIC

This means that even if a channel is classified as CONFIDENTIAL, messages to external recipients on that channel are treated as PUBLIC.

Channel States

Channels move through defined states:

  • UNTRUSTED -- New or unknown channels start here. No data flows in or out. The channel is completely isolated until you classify it.
  • CLASSIFIED -- The channel has a classification level assigned and is active. Messages flow according to policy rules.
  • BLOCKED -- The channel has been explicitly disabled. No messages are processed.

UNTRUSTED Channels

An UNTRUSTED channel cannot receive any data from the agent and cannot send data into the agent's context. This is a hard security boundary, not a suggestion.

Channel Router

The channel router manages all registered adapters and provides:

  • Adapter registration -- Register and unregister channel adapters by channel ID
  • Message dispatch -- Route outbound messages to the correct adapter
  • Retry with exponential backoff -- Failed sends are retried up to 3 times with increasing delays (1s, 2s, 4s)
  • Bulk operations -- connectAll() and disconnectAll() for lifecycle management
yaml
# Router retry behavior is configurable
router:
  maxRetries: 3
  baseDelay: 1000  # milliseconds

Ripple: Typing and Presence

Triggerfish relays typing indicators and presence state across channels that support them. This is called Ripple.

ChannelTyping IndicatorsRead Receipts
TelegramSend and receiveYes
SlackSend only--
DiscordSend only--
WhatsAppSend and receiveYes
WebChatSend and receiveYes

Agent presence states: idle, online, away, busy, processing, speaking, error.

Message Chunking

Platforms have message length limits. Triggerfish automatically chunks long responses to fit within each platform's constraints, splitting on newlines or spaces for readability:

ChannelMax Message Length
Telegram4,096 characters
Discord2,000 characters
Slack40,000 characters
WhatsApp4,096 characters
WebChatUnlimited

Next Steps

Set up the channels you use:

  • CLI -- Always available, no setup needed
  • Telegram -- Create a bot via @BotFather
  • Slack -- Create a Slack app with Socket Mode
  • Discord -- Create a Discord bot application
  • WhatsApp -- Connect via WhatsApp Business Cloud API
  • WebChat -- Embed a chat widget on your site
  • Email -- Connect via IMAP and SMTP relay

Released under the MIT License.