FabricFabric
Messaging

Messaging

Drive Fabric Agents sessions from Telegram and WhatsApp — inbound chat messages run the agent, agent replies stream back into the chat.

Messaging bridges an external chat (Telegram DM or WhatsApp contact) to a Fabric Agents session. When the bridged contact sends a message, the agent runs. When the agent replies, the response lands back in the chat. Sessions show up in the desktop UI exactly as if you'd driven them locally — the two are live-linked.

Typical uses:

  • Phone-away control — trigger a long-running task from the road; the agent keeps working on your workstation or remote server.
  • Push notifications that talk back — the agent summarises a PR review, you reply "merge it", the next turn runs.
  • Teammates driving your setup — share access to a single session with a collaborator over WhatsApp without them needing the desktop app.

Platforms

PlatformAuthWhere it runsNotes
TelegramBot token from @BotFatherDirectly in-processOfficial Bot API. Photo / document / voice / video / audio attachments up to 20 MB.
WhatsAppQR pairing (scan from your phone)Separate Node subprocess, built on BaileysUnofficial Web API. Self-chat (DM yourself) is the recommended testing channel.

Both platforms support the same command set/new, /bind, /pair, /status, /stop, /unbind, /help — and the same three response modes (see below).

Response modes

Each binding picks how agent output lands in the chat. Default is progress.

ModeBehaviour
progress (default)One evolving bubble per run. Starts as 💭 thinking…, edits to 🔧 <tool>… while tools run, then replaces itself with the final text on completion. Intermediate assistant text is dropped.
streamingLive edits as tokens arrive. Each text_complete finalises a message, so one agent run with multiple turns produces multiple messages. On platforms without message-editing (WhatsApp), degrades to one message per turn at text_complete.
final_onlySilent until the agent finishes, then one message with the full final text.

Change the mode per-binding from Settings → Messaging → ⋯ menu on the binding row → Response mode.

Where bindings live

Every binding is workspace-scoped. A single session can only be bound to one chat per platform at a time; a single chat can only drive one session at a time.

Bindings and platform credentials persist at:

~/.fabric-agent/workspaces/{workspace-id}/messaging/
  ├── bindings.json
  ├── config.json              # per-platform config (responseMode, selfChatMode, …)
  ├── whatsapp-auth/           # Baileys session state (QR-login keys)
  └── telegram/                # Telegram token (encrypted via OS keychain)

If you wipe whatsapp-auth/, the next connect will trigger a fresh QR scan.

Headless / remote server

The same messaging stack runs inside the headless server (packages/server/src/index.ts) when you point the desktop app at a remote workspace. The WhatsApp worker is spawned as a Node subprocess by the server; paths are controlled with:

Env varDefaultWhat it does
FABRIC_MESSAGING_WA_WORKER$FABRIC_BUNDLED_ASSETS_ROOT/packages/messaging-whatsapp-worker/dist/worker.cjsAbsolute path to the worker bundle
FABRIC_MESSAGING_NODE_BINnodeNode binary used to spawn the worker (Bun can't run the Baileys worker directly)

The Docker image (ghcr.io/fabric-pro/fabric-agents-server) ships both. See Workspaces — remote workspaces for the remote setup flow.

  • Telegram setup — create a bot, paste the token, drive your first session
  • WhatsApp setup — QR pair your phone, test with self-chat
  • Command reference — every slash command you can send from a chat
  • Workspaces — messaging is workspace-scoped; each workspace has its own bindings

On this page