Skip to content

Channels

Octipus supports multiple communication channels, allowing you to interact with your agents from wherever you work. All channels route through the Gateway Hub — a central WebSocket entry point with unified authentication, event routing, and rate limiting.

Every channel connects through the Gateway Hub, which handles auth, rate limiting, and event routing:

Telegram ──┐
Slack ─────┤
Teams ─────┤
WhatsApp ──┼──► Gateway Hub ──► Orchestrator ──► Worker(s) ──► Gateway Hub ──► Channel
WebChat ───┤
TUI ───────┘

The Gateway Hub provides:

  • Typed WebSocket protocol (Zod-validated messages)
  • Multi-auth — session tokens, local file tokens (TUI), HMAC keys (adapters), API keys
  • Central event bus — pub/sub with pattern matching and per-session replay
  • Gateway commands/help, /status, /expert, /abort, /clear, /compact, /cost, /diff, /version, /persona, /reload-extensions
  • Rate limiting — per-connection, per-action, trust-level-aware
  • Real-time emoji reactions — agent lifecycle feedback on all channels (👀→🧠→🔧→✅)
  • Typing indicators — repeating typing status while agent works (4s refresh for Telegram)
  • Stall detection — 😐 after 15s, 😬 after 45s without progress

Channels support hot-reload — change a setting in the web UI and the channel reconnects automatically.

All external channels (Telegram, Slack, WhatsApp, Teams) provide real-time emoji reactions on user messages:

PhaseEmojiMeaning
Received👀Message received, queued
Working💻🔍✍️🧠Role-specific (coding, research, writing, etc.)
Tool use📖💻🔍🐳💬🔧Tool-specific during execution
PermissionWaiting for user approval
DoneCompleted successfully
FailedError occurred

Permission prompts show tool details (file path, command, URL) so you know exactly what you’re approving.

See the dedicated Terminal UI page for the full surface guide, keybindings, and troubleshooting.

As of v0.2 the terminal surfaces are rebuilt on top of @mariozechner/pi-tui — a differential renderer that writes only changed cells. Two surfaces are exposed:

Terminal window
octi tui # Chat shell — full-width conversation with the orchestrator
octi edit # File editor — split tree + buffer + side chat

Both share the same Editor primitive (paste markers, undo, history, fuzzy @… / ./… file completion, slash-command autocomplete), the same overlay system (command palette, keybindings help), and the same KeybindingsManager. App-level bindings can be overridden in ~/.octipus/keybindings.json.

  • Status bar with model + cost + token budget
  • Streaming markdown rendering for assistant turns, plain wrap for user/system
  • Permission prompts inline; tool details visible (path, command, URL)
  • /help overlay lists all gateway commands; /quit exits
  • Glyphs auto-degrade to ASCII on terminals without emoji glyph support
  • Three-pane split — file tree, buffer, side chat — sized off tui.terminal.rows
  • Multiple buffers; Alt+, / Alt+. (or F2 / F3) to cycle, F4 palette, F5 keybindings overlay
  • Fuzzy file picker (Ctrl+O) with substring match on relative path
  • Side chat shares the same agent context as octi tui — files referenced via @… are picked up automatically

Mint a personal octi_… api token in Settings → API Tokens and place it at ~/.octipus/local-token (or set OCTIPUS_TOKEN in the environment).

The bootstrap token at ~/.octipus/mcp-token is for MCP/CLI clients (see MCP) — not the TUI. The TUI prefers a user-owned token so audit attribution stays correct.


Built with grammY. Uses long polling by default — no public URL required.

  1. Message @BotFather on Telegram
  2. Send /newbot and follow the prompts
  3. Copy the bot token
  4. Add it in Settings > Channels or set TELEGRAM_BOT_TOKEN
SettingEnv VarDescription
telegram.botTokenTELEGRAM_BOT_TOKENBot token from BotFather (stored in vault)
telegram.allowedUsersTELEGRAM_ALLOWED_USERSAllowed user IDs (empty = all)
telegram.webhookUrlTELEGRAM_WEBHOOK_URLWebhook URL (empty = polling)
telegram.pollingTimeoutTELEGRAM_POLLING_TIMEOUTPolling timeout in seconds (default: 30)
CommandDescription
/startInitialize the bot
/helpShow available commands
/linkGet a code to link your account
/statusCheck bot status
/clearClear conversation history
  • Text, photo, document, voice, and video messages
  • Reply-to message context
  • Automatic message chunking (4096 char limit)
  • Markdown formatting in responses
  • User whitelist via allowedUsers

Built with Bolt.js. Uses Socket Mode — no public URL required.

  1. Go to api.slack.com/apps > Create New App > From scratch

  2. Name your app and select your workspace

  3. OAuth & Permissions — add Bot Token Scopes:

    • chat:write, channels:history, groups:history, im:history, mpim:history
    • users:read, files:read, app_mentions:read
    • commands — only needed if you add the /link slash command (step 7)
  4. Socket Mode — enable it, generate an App-Level Token (xapp-…) with connections:write scope. With Socket Mode on, Event Subscriptions and Interactivity are delivered over the WebSocket — no Request URL / event endpoint is configured anywhere (that’s why Octipus settings never ask for one; the bot connects outbound).

  5. Event Subscriptions — enable and subscribe to these bot events:

    • message.channels, message.groups, message.im, message.mpim, app_mention
  6. App Home — enable the Messages Tab and check “Allow users to send Slash commands and messages from the messages tab”. Without this, users can’t DM the bot.

  7. (Optional) Slash Commands — create /link (the Request URL field is ignored in Socket Mode — put any placeholder). Octipus also accepts the plain message link. Requires the commands scope.

  8. Install / Reinstall to Workspace.

  9. Copy the Bot User OAuth Token (xoxb-…) and the App Token (xapp-…) to Settings > Channels.

SettingEnv VarDescription
slack.botTokenSLACK_BOT_TOKENBot token (xoxb-...) (stored in vault)
slack.appTokenSLACK_APP_TOKENApp-level token (xapp-...) (stored in vault)
slack.signingSecretSLACK_SIGNING_SECRETSigning secret from app settings (stored in vault)
  • Direct messages and @mentions
  • Thread-based conversations
  • File attachments (images, documents)
  • Rich message blocks with Markdown
  • Socket Mode (no public endpoint needed)
  • Account linking via link keyword

Built with the Bot Framework. Webhook-based — requires a public URL.

  1. Go to the Azure Portal
  2. Create a new Bot Channels Registration resource
  3. Note the Microsoft App ID and generate a Client Secret
  4. Under Channels, add Microsoft Teams
  5. Set the messaging endpoint to https://your-domain.com/api/channels/teams/webhook
SettingEnv VarDescription
teams.appIdTEAMS_APP_IDMicrosoft App ID from Azure
teams.appPasswordTEAMS_APP_PASSWORDClient secret (stored in vault)
teams.tenantIdTEAMS_TENANT_IDAzure AD tenant ID (optional)
  • Message and conversation update handling
  • Bot mention removal from text
  • Proactive messaging via conversation references
  • File attachments and Adaptive Cards
  • Enterprise integration

Uses the Meta WhatsApp Cloud API. Webhook-based — requires a public URL.

  1. Go to developers.facebook.com > My Apps > Create App
  2. Select Business type, fill in the app name, select your Business Account
  1. In the app dashboard, click Add Product > WhatsApp > Set up
  2. This creates a test phone number and gives you a temporary access token

From WhatsApp > API Setup in the Meta developer dashboard:

  • Phone Number ID — listed under the test number
  • Access Token — click “Generate” for a temporary token
  • App Secret — go to Settings > Basic

Your assistant must be reachable from the internet (use Cloudflare Tunnel, ngrok, etc.).

  1. In Meta’s WhatsApp > Configuration > Webhook:
    • Callback URL: https://your-domain.com/api/channels/whatsapp/webhook
    • Verify Token: same value as your whatsapp.verifyToken setting
  2. Click Verify and Save
  3. Subscribe to the messages field

The temporary token expires after 24 hours. For production:

  1. Meta Business Suite > Settings > System Users — create an Admin System User
  2. Add your WhatsApp Business Account as an asset with full control
  3. Generate a token with whatsapp_business_messaging and whatsapp_business_management permissions
  4. Use this as your whatsapp.accessToken
SettingEnv VarDescription
whatsapp.accessTokenWHATSAPP_ACCESS_TOKENCloud API access token (stored in vault)
whatsapp.phoneNumberIdWHATSAPP_PHONE_NUMBER_IDPhone Number ID from Meta
whatsapp.verifyTokenWHATSAPP_VERIFY_TOKENWebhook verify token (default: octipus-whatsapp-verify)
whatsapp.appSecretWHATSAPP_APP_SECRETMeta App Secret for signature verification (stored in vault)
whatsapp.businessAccountIdWHATSAPP_BUSINESS_ACCOUNT_IDBusiness Account ID (optional)
CommandDescription
/startInitialize the bot
/helpShow available commands
/linkGet a code to link your account
/statusCheck bot status
/clearClear conversation history
MethodPathAuthDescription
GET/api/channels/whatsapp/webhookNoneMeta verification (hub.challenge)
POST/api/channels/whatsapp/webhookSignatureIncoming messages
  • Text, image, document, audio, video, and location messages
  • Reply-to context (quoted messages)
  • Webhook signature verification (X-Hub-Signature-256)
  • Automatic message chunking (4096 char limit)
  • Media download via Graph API
  • Delivery status tracking (sent, delivered, read)

The built-in WebSocket chat is always available and is the primary interface through the web UI. No configuration required.

  • Real-time bidirectional messaging via WebSocket
  • Persistent sessions across page reloads
  • Typing indicators and agent activity tracking
  • Permission request/approval flow
  • Voice input support
  • Session management

All external channels use the same cross-channel identity binding flow:

  1. Send /link (or link in Slack) in the channel
  2. You receive a 6-character code valid for 5 minutes
  3. Enter the code in the web UI at Settings > Channels

Once linked, messages from all your connected channels are attributed to the same user account. This enables:

  • Shared session history across channels
  • Unified permission settings
  • Consistent agent access regardless of channel

When an agent needs permission (e.g., to run a shell command), the request is forwarded to the channel where the conversation originated. Reply yes or no directly in the channel to approve or deny.

# ─── Telegram ────────────────────────────────────────────────
TELEGRAM_BOT_TOKEN= # From @BotFather
TELEGRAM_ALLOWED_USERS= # Comma-separated user IDs
TELEGRAM_WEBHOOK_URL= # Leave empty for polling
# ─── Slack ───────────────────────────────────────────────────
SLACK_BOT_TOKEN= # xoxb-...
SLACK_APP_TOKEN= # xapp-...
SLACK_SIGNING_SECRET= # From app settings
# ─── Microsoft Teams ────────────────────────────────────────
TEAMS_APP_ID= # Azure App ID
TEAMS_APP_PASSWORD= # Azure Client Secret
TEAMS_TENANT_ID= # Azure AD Tenant (optional)
# ─── WhatsApp ───────────────────────────────────────────────
WHATSAPP_ACCESS_TOKEN= # Meta Cloud API token
WHATSAPP_PHONE_NUMBER_ID= # From Meta dashboard
WHATSAPP_VERIFY_TOKEN= # Your chosen verify token
WHATSAPP_APP_SECRET= # Meta App Secret
WHATSAPP_BUSINESS_ACCOUNT_ID= # Business Account ID (optional)

Channel not connecting:

  • Check Settings > Channels in the web UI to verify credentials
  • Check backend logs: tail -f ~/.octipus/backend.log
  • Ensure secrets are stored in the vault (not as plain text in env vars)

Messages not arriving:

  • Telegram: Verify token at https://api.telegram.org/bot<TOKEN>/getMe
  • Slack: Ensure Socket Mode is enabled and the app is installed to the workspace. In Socket Mode there is no Request URL to configure — the bot connects outbound. If every event fails with invalid_auth, the loaded xoxb-… token is wrong/stale; re-copy the Bot User OAuth Token, re-save, and restart. Verify with curl -H "Authorization: Bearer xoxb-…" https://slack.com/api/auth.test (expect "ok":true)
  • Teams: Verify the endpoint URL is reachable from Azure
  • WhatsApp: Check webhook is verified (green checkmark) and subscribed to messages

Account linking fails:

  • Link codes expire after 5 minutes
  • Ensure the web account is logged in before entering the code
  • Verify Valkey is running (codes are stored in Valkey)