Channels Gateway
Connect agents to chat platforms like Telegram, Discord, Slack, WhatsApp, and Signal
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.
How It Works
Quick Start
- Install Bot Dependencies
Install the bot integration package:
bash pip install "praisonai[bot]"This adds support for Telegram, Discord, Slack, and WhatsApp platforms.
- 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" - Launch Gateway with Channels
Start the integrated gateway with channel bot support:
bash praisonai dashboard --aiuiThis starts Pattern B host integration with channels feature enabled.
Platform Configuration
Telegram Setup
- Create bot with @BotFather
- Get your bot token
- Set environment variable:
export TELEGRAM_BOT_TOKEN="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11"Discord Setup
- Create application in Discord Developer Portal
- Create bot and get token
- Set environment variable:
export DISCORD_BOT_TOKEN="your_discord_bot_token"Slack Setup
- Create Slack app in Slack API
- Get Bot User OAuth Token and App-Level Token
- Set environment variables:
export SLACK_BOT_TOKEN="xoxb-your-bot-token"
export SLACK_APP_TOKEN="xapp-your-app-token"WhatsApp Setup
- Set up WhatsApp Business API
- Get access token and phone number ID
- Set environment variables:
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.
- Run the bridge (
docker run -p 8080:8080 bbernhard/signal-cli-rest-api) - Link a device by scanning the bridge QR from Signal → Linked Devices
- Set environment variables:
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.
channels:
local: {}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.
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.
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:
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 setPattern C: Integrated Gateway
Single process with WebSocket support:
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:
export PRAISONAI_HOST_LEGACY=1
praisonai uiThis uses only @aiui.reply callbacks without automatic agent integration.
BotOS Multi-Platform Orchestration
Use BotOS for advanced multi-platform management:
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:
| Feature | Description |
|---|---|
| Auto-detection | Platforms start automatically when environment variables are set |
| Session Management | Each user gets persistent sessions across bot restarts |
| Gateway Integration | Works seamlessly with Pattern B/C host integration |
| WebSocket Support | Real-time updates via /ws endpoint in Pattern C |
Example with custom configuration:
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.
| Feature | Standalone Bot | Gateway 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.
Complete YAML field documentation and pipeline diagram
BotConfig ReferenceStandalone 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.
channels:
slack:
token: "${SLACK_BOT_TOKEN}"
app_token: "${SLACK_APP_TOKEN}"
allow_shell: true
auto_approve_shell: false
approval_channel: "UOWNER"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_policygateway:
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 approvalOn 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.
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
- 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
Send agent-generated images and files through channel adapters with path validation
Bot Inbound MediaReceive and validate photos and documents from users
Development vs Production
Development
# Single platform for testing
export TELEGRAM_BOT_TOKEN="your_token"
praisonai dashboard --aiui
# Check logs
tail -f ~/.praisonai/unified/logs/ui.logProduction
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.
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 Type | How to Configure | Appears As |
|---|---|---|
| Home channel | set_home_channel(platform, channel_id) | "<platform>:home" |
| Named alias | add_alias(name, platform, channel_id) | "<name> (<platform>:<channel_id>)" |
| Observed channel | Seen 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:
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())Full reference for Origin, ReachableTarget, and channel-directory configuration.
Troubleshooting
Common Issues
Bot not starting
Check environment variables are set correctly:
# 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 workspaceMessages not reaching agents
Ensure gateway is running with proper agent configuration:
# 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:
# Test WebSocket connectivity
curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" \
http://localhost:8080/wsBest Practices
Use environment variables for tokens
Never hardcode tokens in source code:
# Good
token = os.getenv('TELEGRAM_BOT_TOKEN')
if not token:
raise ValueError("TELEGRAM_BOT_TOKEN not set")
# Bad
token = "123456:hardcoded_token" # Security riskHandle rate limits gracefully
Different platforms have different rate limits:
# 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:
# 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
Pattern B/C integration
Integration PatternsPattern comparison
Outbound Media DeliveryDeliver agent-generated media via gateway channel adapters
Messaging BotsFull bot setup for Telegram, Discord, Slack, and WhatsApp
Bot Streaming RepliesProgressive streaming for Python-Agent and recipe/YAML-backed channels