Skip to Content
Polyant is open source under AGPL-3.0 — star us on GitHub.
Getting StartedConnect a Channel

Channels Setup

Polyant agents can be exposed through multiple channels. Each channel is configured per-instance in the admin panel under the Channels tab. All channel credentials are AES-256-GCM encrypted at rest.

Three channels are built in: Telegram, Slack, and WhatsApp (via Twilio). The OpenAI-compatible HTTP API is always on (no setup required).

Telegram

Protocol: Long polling (via grammY ).

Prerequisites

  • A Telegram account
  • @BotFather bot token

Setup

  1. Open Telegram and start a chat with @BotFather.
  2. Send /newbot, pick a name and username for your bot.
  3. Copy the HTTP API token BotFather gives you (looks like 1234567890:ABC...).
  4. In the Polyant admin panel → your instance → Channels tab → Telegram.
  5. Paste the token. Optionally, fill Allowed User IDs with a comma-separated list of numeric Telegram user IDs to restrict who can talk to the bot — leave empty to accept everyone.
  6. Click Save & Start.

Usage

The adapter starts long-polling immediately. Users can now send messages to your bot on Telegram. Photos and documents are downloaded, stored, and passed to the LLM as multimodal content.

Supported attachments

  • Photos (JPG, PNG, WebP) → passed as vision input
  • Documents (PDF, images) → stored in S3, passed to the LLM

Slack

Protocol: Socket Mode (via @slack/bolt ).

Prerequisites

  • A Slack workspace where you can install apps
  • An admin account (or app-installer permission)

Setup

  1. Go to api.slack.com/apps Create New AppFrom scratch.
  2. Enable Socket Mode in the sidebar; generate an App-Level Token with connections:write scope. Copy it (starts with xapp-).
  3. In OAuth & Permissions, add these Bot Token Scopes:
    • chat:write
    • im:history
    • im:read
    • im:write
    • app_mentions:read
    • channels:history
    • groups:history
    • files:read (if you want file attachments)
  4. Install the app to your workspace; copy the Bot User OAuth Token (starts with xoxb-).
  5. In Basic InformationApp Credentials, copy the Signing Secret. It is required by Polyant to verify request signatures.
  6. In Event Subscriptions, enable events and subscribe to:
    • message.im
    • message.channels (for channel mentions)
    • app_mention
  7. In the Polyant admin panel → your instance → Channels tab → Slack.
  8. Fill in:
    • Bot Token (xoxb-...)
    • App Token (xapp-...)
    • Signing Secret (from step 5)
  9. Click Save & Start.

Usage

DM your bot directly, or mention it in a channel. The adapter handles both. Rich Slack formatting (blocks, code blocks) is supported.

WhatsApp (via Twilio)

Protocol: Webhook (via Twilio’s Messaging API).

Prerequisites

  • A Twilio  account
  • A WhatsApp-enabled Twilio phone number (sandbox or production)
  • A public URL for the webhook (use ngrok  for local development)

Setup

  1. In the Twilio Console → MessagingTry it outSend a WhatsApp message → get your sandbox number (e.g. +14155238886) and join code.

  2. Under Account → API keys & tokens, copy your Account SID and Auth Token.

  3. In the Polyant admin panel → your instance → Channels tab → WhatsApp.

  4. Fill in:

    • Account SID (AC...)
    • Auth Token
    • From number (e.g. whatsapp:+14155238886)
  5. The webhook URL for your instance is:

    https://<your-engine-host>/webhooks/twilio/<instance-slug>/whatsapp

    (mounted by TwilioWebhookController at packages/engine/src/server/channels/twilio-webhook.controller.ts:25,29).

  6. In the Twilio Console, set that URL as the WHEN A MESSAGE COMES IN webhook for your WhatsApp sender. Twilio signs every request with your Auth Token, and the engine verifies the signature before processing.

  7. Click Save & Start in the admin panel.

Inbound typing indicator

On every inbound WhatsApp message, Polyant fires a typing indicator against Twilio’s /v2/Indicators/Typing.json endpoint. The user sees the animated “typing…” dots until the agent’s response is delivered. As a documented side-effect, Twilio also marks the inbound message as read (double blue check).

Message debouncer

When a user sends several short messages in quick succession (a common pattern on WhatsApp/Telegram), Polyant collapses them into a single pipeline run to avoid firing the LLM multiple times on fragments of one thought. Three env vars tune the behavior:

  • MESSAGE_SOFT_DEBOUNCE_MS — the quiet window after a fragment before the pipeline fires (default 2000). New fragments inside the window reset the timer.
  • MESSAGE_TYPING_DELAY_MS — how long after the first fragment Polyant shows the WhatsApp typing indicator (default 1500).
  • MESSAGE_MAX_RESTARTS — the maximum number of consecutive cancel-and-restart cycles when a fragment arrives mid-pipeline (default 3). Beyond this, late fragments accumulate and are flushed in a follow-up run.

Supported attachments

  • Photos → vision input
  • PDFs and documents → stored in S3 (if configured), passed to the LLM as multimodal content

Agent (in-process)

Protocol: virtual, in-process function call — no network, no credentials.

Enable the agent channel on an instance to make it callable from any other instance via a synthesized ask_<slug> tool. The Supervisor of the caller invokes the callee as if it were a regular tool; depth is capped at 1 (a callee cannot call a third agent) and each call is bounded by AGENT_CALL_TIMEOUT_MS (default 60s).

There is nothing to configure beyond toggling the channel on in the Channels tab. See Channels → Agent-to-agent for the full picture.

OpenAI-compatible HTTP API

This channel is always on. Every instance is exposed as a selectable model at POST /v1/chat/completions:

curl -s http://localhost:4000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{"model": "your-instance-slug", "messages": [{"role":"user","content":"hi"}]}'

To require authentication for this endpoint:

  1. In the instance Settings tab, open the API Authentication section and toggle Require authentication on (this sets authEnabled = true on the instance).
  2. Add an entry to Secrets with key auth_api_key (the bearer token clients must present).
  3. Clients now need to send Authorization: Bearer <auth_api_key>.

Per-instance architecture

All channel adapters are per-instance. Starting a Slack channel for instance A does not affect instance B. Adapters start and stop dynamically when you save/delete a channel config — no engine restart needed.

Channel config is stored in the instance_channels table, encrypted with your ENCRYPTION_KEY.

Where to look when something does not work

SymptomLikely causeWhere to fix
Telegram bot does not replyWrong token, or two engines polling with the same token (Conflict: terminated by other getUpdates in the engine logs)Regenerate the token via BotFather, or stop the duplicate engine
Some Telegram users are silently ignoredThe Allowed User IDs whitelist on the Channels tab excludes themAdd their numeric user id, or clear the field to accept everyone
Slack: app cannot connectApp token missing the connections:write scope, or Socket Mode disabledRe-check the Slack app settings, then Reinstall app
Slack: missing_scope in engine logsOne of the bot scopes was not grantedRead the missing scope from the error, add it on the Slack side, reinstall
WhatsApp: nothing happensWebhook URL not reachable from Twilio (typical when running locally without a tunnel)Test with curl from outside; expose the engine via ngrok or a public host
WhatsApp sandbox stopped working after 72 hTwilio sandbox sessions expire on inactivitySend join <sandbox-code> again from the test phone

For deeper troubleshooting (login, database, provider) see Troubleshooting.

Last updated on