Channels Gateway

Connect agents to chat platforms like Telegram, Discord, Slack, WhatsApp, and Signal

python
from praisonaiagents import Agent

agent = Agent(name="channel-agent", instructions="Route messages across multiple channels.")
agent.start("Handle messages from Telegram, Slack, and Discord via the gateway.")

The user messages on Telegram, Slack, or Discord; the gateway routes each channel to your agent.

Connect PraisonAI agents to popular chat platforms through the channels gateway integration.

Diagram

PraisonAI

Chat Platforms

📱 Telegram

🤖 BotOS

💬 Discord

💼 Slack

📞 WhatsApp

🔒 Signal

💻 Local Terminal

⚙️ Gateway

🧠 Agents

How It Works

Diagram
Channels GatewayAgentUserChannels GatewayAgentUserRequestProcess requestResult Agent–>>User: Response

Quick Start

  1. Install Bot Dependencies

    Install the bot integration package:

    bash
    pip install "praisonai[bot]"

    This adds support for Telegram, Discord, Slack, and WhatsApp platforms.

  2. Configure Platform Tokens

    Set environment variables for your chosen platforms:

    bash
    # Telegram
    export TELEGRAM_BOT_TOKEN="your_telegram_token"
    
    # Discord  
    export DISCORD_BOT_TOKEN="your_discord_token"
    
    # Slack
    export SLACK_BOT_TOKEN="xoxb-your-slack-token"
    export SLACK_APP_TOKEN="xapp-your-slack-app-token"
    
    # WhatsApp
    export WHATSAPP_ACCESS_TOKEN="your_whatsapp_token"
    export WHATSAPP_PHONE_NUMBER_ID="your_phone_number_id"
  3. Launch Gateway with Channels

    Start the integrated gateway with channel bot support:

    bash
    praisonai dashboard --aiui

    This starts Pattern B host integration with channels feature enabled.


Platform Configuration

Telegram Setup

  1. Create bot with @BotFather
  2. Get your bot token
  3. Set environment variable:
bash
export TELEGRAM_BOT_TOKEN="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11"

Discord Setup

  1. Create application in Discord Developer Portal
  2. Create bot and get token
  3. Set environment variable:
bash
export DISCORD_BOT_TOKEN="your_discord_bot_token"

Slack Setup

  1. Create Slack app in Slack API
  2. Get Bot User OAuth Token and App-Level Token
  3. Set environment variables:
bash
export SLACK_BOT_TOKEN="xoxb-your-bot-token"
export SLACK_APP_TOKEN="xapp-your-app-token"

WhatsApp Setup

  1. Set up WhatsApp Business API
  2. Get access token and phone number ID
  3. Set environment variables:
bash
export WHATSAPP_ACCESS_TOKEN="your_access_token"
export WHATSAPP_PHONE_NUMBER_ID="your_phone_number_id"

Signal Setup

Signal links a device through a local signal-cli-rest-api bridge — no cloud token.

  1. Run the bridge (docker run -p 8080:8080 bbernhard/signal-cli-rest-api)
  2. Link a device by scanning the bridge QR from Signal → Linked Devices
  3. Set environment variables:
bash
export SIGNAL_ACCOUNT="+15551234567"
export SIGNAL_BRIDGE_URL="http://localhost:8080"

Local (Terminal) Setup

The built-in local channel reads stdin and writes stdout — no token, no webhook, no allowlist. Add it alongside remote channels to chat with the same live agent from your terminal.

yaml
channels:
  local: {}
Local (Terminal) Channel

Chat from your terminal, commands, capabilities, and cross-channel continuity

Webhook Setup

Route any third-party HTTP webhook (GitHub, Stripe, CI) to an agent with a type: webhook channel and declarative routes — no adapter code.

yaml
channels:
  github:
    type: webhook
    path: /hooks/github
    verify:
      hmac: { header: X-Hub-Signature-256, secret: ${GITHUB_WEBHOOK_SECRET} }
    routes:
      - when: { field: headers.X-GitHub-Event, equals: issues }
        prompt: "New issue #{{ payload.issue.number }}: {{ payload.issue.title }}"

See Webhook Channel for the full filter DSL, prompt templating, and response contract.

Add a custom channel

Point a channel at your own adapter class from YAML — no packaging, no bootstrap Python.

yaml
channels:
  my_intranet_chat:
    adapter: "my_company.adapters:IntranetBot"
    token: ${INTRANET_TOKEN}

Or drop a single-file adapter into ~/.praisonai/channels/*.py. See Custom Gateway Channel (Zero-Code) for both surfaces, the precedence ladder, and the trust model.


Gateway Patterns

Pattern B: In-Process Host

Run channels within your application process:

python
from praisonai.integration import configure_host, create_host_app

configure_host(
    title="Bot Gateway",
    pages=["chat", "agents", "sessions"],
    agents=[{
        "name": "Support Agent",
        "instructions": "Help users with their questions",
        "llm": "gpt-4o"
    }]
)

app = create_host_app()
# Channels auto-start if environment variables are set

Pattern C: Integrated Gateway

Single process with WebSocket support:

python
import asyncio
from praisonai.integration import run_integrated_gateway

async def main():
    await run_integrated_gateway(
        port=8080,
        title="Multi-Platform Bot",
        agents=[{
            "name": "Assistant", 
            "llm": "gpt-4o"
        }]
    )

asyncio.run(main())

The gateway serves:

  • Chat UI at http://localhost:8080
  • REST API at http://localhost:8080/api
  • WebSocket at ws://localhost:8080/ws
  • Bot integrations auto-start based on environment variables

Legacy Mode

For callback-only integration without provider wiring:

bash
export PRAISONAI_HOST_LEGACY=1
praisonai ui

This uses only @aiui.reply callbacks without automatic agent integration.


BotOS Multi-Platform Orchestration

Use BotOS for advanced multi-platform management:

python
from praisonai.bots import BotOS

# Initialize BotOS with all available platforms
bot_os = BotOS(reliability="production")  # or "default" / "off"

# Platforms auto-detected from environment variables
available_platforms = bot_os.get_available_platforms()
# ['telegram', 'discord'] # Based on set environment variables

# Start specific platforms
await bot_os.start_platform('telegram')
await bot_os.start_platform('discord')

# Or start all available
await bot_os.start_all()

Channel Features Integration

The praisonaiui.features.channels module provides:

FeatureDescription
Auto-detectionPlatforms start automatically when environment variables are set
Session ManagementEach user gets persistent sessions across bot restarts
Gateway IntegrationWorks seamlessly with Pattern B/C host integration
WebSocket SupportReal-time updates via /ws endpoint in Pattern C

Example with custom configuration:

python
from praisonaiui.features.channels import enable_channels

# Manual channel configuration
enable_channels({
    'telegram': {
        'token': os.getenv('TELEGRAM_BOT_TOKEN'),
        'agent_config': {
            'name': 'Telegram Assistant',
            'instructions': 'You are helpful on Telegram'
        }
    },
    'discord': {
        'token': os.getenv('DISCORD_BOT_TOKEN'), 
        'agent_config': {
            'name': 'Discord Bot',
            'instructions': 'You are helpful on Discord'
        }
    }
})

Channel Security

All channels enforce the same access-control pipeline regardless of whether you run them via praisonai bot start or praisonai gateway start.

FeatureStandalone BotGateway Mode
User allowlist (allowed_users)✅✅
Channel allowlist (allowed_channels)✅✅
Unknown user pairing✅✅
Group policy enforcement✅✅
Signal DM allowlist (digit-normalised)✅✅

Gateway channels also accept group:<name> references in allowed_users, allowlist and blocklist — see Access Groups.

Gateway YAML Reference

Complete YAML field documentation and pipeline diagram

BotConfig Reference

Standalone bot configuration options


Shell execution opt-in

Set allow_shell: true on a channel to let its bot run shell commands on the gateway host. Policy is per-channel — Slack can auto-approve while WhatsApp requires approval.

yaml
channels:
  slack:
    token: "${SLACK_BOT_TOKEN}"
    app_token: "${SLACK_APP_TOKEN}"
    allow_shell: true
    auto_approve_shell: false
    approval_channel: "UOWNER"
Loopback DM — kept
gateway:
  bind_host: "127.0.0.1"

channels:
  slack:
    token: "${SLACK_BOT_TOKEN}"
    app_token: "${SLACK_APP_TOKEN}"
    allow_shell: true
    auto_approve_shell: true   # kept: loopback + no group_policy
Exposed bind — must acknowledge
gateway:
  bind_host: "0.0.0.0"

channels:
  slack:
    token: "${SLACK_BOT_TOKEN}"
    app_token: "${SLACK_APP_TOKEN}"
    allow_shell: true
    auto_approve_shell: true
    auto_approve_shell_acknowledge_exposed: true   # else downgraded to approval

On Telegram channels, shell-approval buttons render through the channel’s own bot and taps resolve through its own callback handler — there is no second getUpdates poller on the token.

Diagram

⚙️ allow_shell: true

🔒 PresentationApprovalBackend

💬 Adapter renders Allow / Deny

👆 User taps

📨 Adapter callback handler

✅ Backend resolves — tool runs

Bot Shell Execution

Full field reference, per-platform approval routing, exposure-aware downgrade, and copy-paste recipes.


Platform-Specific Features

Telegram

  • Supports markdown formatting
  • File uploads and downloads
  • Inline keyboards
  • Command handling (/start, /help)

Discord

  • Rich embeds and attachments
  • Slash commands
  • Thread support
  • Role-based permissions

Slack

  • Block kit UI components
  • App Home tab
  • Workflow integration
  • Enterprise security features

WhatsApp

  • Media message support
  • Template messages
  • Business API features
  • Webhook verification

Signal

  • End-to-end encryption via linked-device bridge
  • DMs + groups with digit-normalised allowlist
  • Typing indicators (best-effort)
  • Poll-based (no webhooks); text-only in this release
Outbound Media Delivery

Send agent-generated images and files through channel adapters with path validation

Bot Inbound Media

Receive and validate photos and documents from users


Development vs Production

Development

bash
# Single platform for testing
export TELEGRAM_BOT_TOKEN="your_token"
praisonai dashboard --aiui

# Check logs
tail -f ~/.praisonai/unified/logs/ui.log

Production

python
import os
import asyncio
from praisonai.integration import run_integrated_gateway

async def main():
    await run_integrated_gateway(
        port=int(os.getenv("PORT", "8080")),
        host="0.0.0.0",
        title="Production Bot Gateway",
        agents=[{
            "name": "Support Bot",
            "llm": os.getenv("PRAISONAI_MODEL", "gpt-4o"),
            "instructions": "Professional customer support assistant"
        }],
        ui_config={
            "analytics": os.getenv("ANALYTICS_ID"),
            "error_reporting": True
        }
    )

if __name__ == "__main__":
    asyncio.run(main())

Reachable Targets

Give the agent a named directory of channels it can deliver to. When a message arrives, the agent’s system prompt lists which channels are reachable by friendly name.

python
from praisonai.bots import TelegramBot
from praisonai.bots.delivery import ChannelDirectory
from praisonaiagents import Agent

directory = ChannelDirectory()
directory.set_home_channel("slack", "C0123456")   # default slack target
directory.add_alias("team", "slack", "C0123456")  # friendly alias
directory.add_alias("ops", "discord", "987654321")

agent = Agent(
    name="gateway",
    instructions="Help users. Deliver to team or ops channels when asked.",
)

bot = TelegramBot(
    token="your-telegram-token",
    agent=agent,
    channel_directory=directory,
)

describe_targets() compiles the list that appears in the agent prompt:

Entry TypeHow to ConfigureAppears As
Home channelset_home_channel(platform, channel_id)"<platform>:home"
Named aliasadd_alias(name, platform, channel_id)"<name> (<platform>:<channel_id>)"
Observed channelSeen in traffic or enumerated via refresh_directory()"<platform>:<channel_id>" (kind: "observed")

Call refresh_directory() on a background loop so the agent sees channels it has not yet been messaged from:

python
import asyncio
from praisonai.bots import BotOS, TelegramBot
from praisonaiagents import Agent

agent = Agent(name="gateway", instructions="Help users and deliver summaries when asked.")
bot = TelegramBot(token="your-telegram-token", agent=agent)
botos = BotOS(bots=[bot])

async def background_refresh(interval=300):
    while True:
        botos.delivery_router.refresh_directory()
        await asyncio.sleep(interval)

async def main():
    asyncio.create_task(background_refresh())
    await botos.start()

asyncio.run(main())
Platform-Aware Agents

Full reference for Origin, ReachableTarget, and channel-directory configuration.


Troubleshooting

Common Issues

Bot not starting

Check environment variables are set correctly:

bash
# Verify tokens are set
echo $TELEGRAM_BOT_TOKEN
echo $DISCORD_BOT_TOKEN

# Check bot permissions
# Telegram: Bot must be added to chat
# Discord: Bot needs appropriate server permissions
# Slack: App must be installed to workspace
Messages not reaching agents

Ensure gateway is running with proper agent configuration:

python
# Verify agent is configured
from praisonai.integration import configure_host

configure_host(
    agents=[{
        "name": "Bot Agent",  # Required
        "instructions": "You are helpful",  # Required
        "llm": "gpt-4o"  # Model must be valid
    }]
)
WebSocket connection issues

For Pattern C, ensure WebSocket endpoint is accessible:

bash
# Test WebSocket connectivity
curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" \
  http://localhost:8080/ws

Best Practices

Use environment variables for tokens

Never hardcode tokens in source code:

python
# Good
token = os.getenv('TELEGRAM_BOT_TOKEN')
if not token:
    raise ValueError("TELEGRAM_BOT_TOKEN not set")

# Bad
token = "123456:hardcoded_token"  # Security risk
Handle rate limits gracefully

Different platforms have different rate limits:

python
# Built-in rate limiting
from praisonai.bots import BotOS

bot_os = BotOS(rate_limit_config={
    'telegram': {'requests_per_second': 30},
    'discord': {'requests_per_minute': 50},
    'slack': {'requests_per_minute': 100}
})
Monitor bot health

Set up monitoring for production deployments:

python
# Health check endpoint
@app.get("/health")
async def health_check():
    bot_status = await bot_os.get_platform_status()
    return {"status": "healthy", "bots": bot_status}

Related