from praisonai.bots import SlackBot # or TelegramBot, DiscordBotbot = SlackBot( token="xoxb-...", app_token="xapp-...", agent=agent, config=config)# Run the botimport asyncioasyncio.run(bot.start())
Outbound tools are from praisonai-tools for sending messages from agents.
For receiving messages via bot runtime, use the CLI or Python SDK shown above.Install: pip install praisonai-tools
When bots are connected through PraisonAI UI (praisonai chat), channel messages appear in the Chat dashboard with full visibility into agent processing steps — tool calls, reasoning, and intermediate responses stream in real-time.
All channel messages and responses are persisted and replayable
The streaming bridge hooks into the same StreamEventEmitter used by the web chat, so channel messages get identical step visibility as messages typed directly in the dashboard.
Bots ship with sensible defaults so you can start chatting immediately — no tool wiring required.Both praisonai bot start and praisonai gateway start apply the same defaults:
Set tools: [] explicitly in YAML, or pass tools=[] to Agent
Require manual approval
Set auto_approve_tools: false in the channel config
Override the tool list
Set default_tools: [...] under the channel — destructive tools are still filtered
Destructive tools (execute_command, delete_file, write_file, shell_command) are never auto-injected, even if you add them to default_tools. Wire them explicitly on the agent and add a chat-level approval flow.
Upgrading from an older release? auto_approve_tools used to default to False. If your bot relied on manual approval, set auto_approve_tools: false explicitly.
from praisonaiagents import Agentfrom praisonai.bots import Bot# Zero config — gets search_web, schedule_*, memory, learning, and auto-approvalagent = Agent(name="assistant", instructions="Help the user")bot = Bot("telegram", agent=agent)bot.run()
# Same result — no YAML tool list neededpraisonai bot telegram --token $TELEGRAM_BOT_TOKEN
Socket Mode works by opening an outbound WebSocket connection to Slack/Discord. No public URL or port forwarding is needed - your bot initiates the connection from behind NAT/firewall.
Safe tools auto-injected when the agent has no tools configured. Destructive tools (execute_command, delete_file, write_file, shell_command) are excluded from auto-injection even if listed.
auto_approve_tools
bool
True
Skip confirmation for safe tool execution. Chat bots can’t show CLI approval prompts, so this defaults to True. Set False to require approval (only useful if you wire a chat-level approval flow).
unknown_user_policy
Literal["deny","pair","allow"]
"deny"
How to handle messages from users not in allowed_users. deny silently drops, pair runs the owner-approval flow, allow lets everyone through.
owner_user_id
Optional[str]
None
Platform-specific ID of the bot owner. Required for inline-button approvals — without it, "pair" policy falls back to a plain-text CLI instruction.
retry_attempts
int
3
Number of retry attempts for failed operations
polling_interval
float
1.0
Interval for polling mode (seconds)
Reply behavior:
Default: Inline replies in the channel
Auto-thread: Responses > 500 chars are automatically threaded
Force thread: Set reply_in_thread=True to always use threads
Group policy:
mention_only — Bot only responds when @mentioned (default, safest)
respond_all — Bot responds to every message in the group
command_only — Bot only responds to /commands
For the full owner-approval workflow (inline buttons on Telegram / Discord / Slack, HMAC signing, CLI fallback), see Bot Unknown-User Pairing.
Create a Verify Token (any secret string you choose)
The temporary access token from the API Setup page expires in 24 hours. For production, generate a System User Token from Business Settings → System Users.
3
Configure Webhook
Go to Configuration → Webhook
Click Edit and enter:
Callback URL: https://your-domain.com/webhook
Verify Token: The same string you set in WHATSAPP_VERIFY_TOKEN
Subscribe to: messages
For local development, use ngrok to create a public HTTPS URL:
Send a WhatsApp message to your business phone number. The bot will reply via the Cloud API.
Troubleshooting: Webhook not verifying
Verify token matches? → Must be identical in Meta console and env var
Bot running? → Webhook server must be up before configuring in Meta
HTTPS required? → Meta only accepts HTTPS webhook URLs
ngrok running? → If using ngrok, ensure the tunnel is active
WhatsApp API Limits
Tier
Messages/day
Requirement
Test
1,000
Default for new apps
Business
10,000+
Verified business account
Unlimited
No limit
Meta approval required
Experimental Feature — WhatsApp Web mode uses a reverse-engineered protocol (not officially supported by Meta). Your WhatsApp number may be banned. Use Cloud API mode for production workloads.
WhatsApp Web mode connects directly via the WhatsApp Web protocol — no tokens, no Meta developer account, no webhooks needed. Just scan a QR code.
1
Install Dependencies
pip install 'praisonai[bot-whatsapp-web]'
This installs neonize (WhatsApp Web client with built-in QR display).
2
Start the Bot
praisonai bot whatsapp --mode web
A QR code appears in your terminal. Open WhatsApp on your phone → Settings → Linked Devices → Link a Device → scan the QR code.
3
Send a Message
Send any message to the linked WhatsApp number from another phone. The bot will reply using your AI agent.Your session is saved locally — on restart, the bot reconnects automatically without scanning again.
CLI
Python
YAML
# Basic web modepraisonai bot whatsapp --mode web# With custom credentials directorypraisonai bot whatsapp --mode web --creds-dir ~/.myapp/wa-creds# With agent capabilitiespraisonai bot whatsapp --mode web --agent agents.yaml --memory --web
from praisonaiagents import Agentfrom praisonai.bots import WhatsAppBotagent = Agent(name="assistant", instructions="Be helpful")# Web mode — no tokens neededbot = WhatsAppBot(mode="web", agent=agent)import asyncioasyncio.run(bot.start()) # Shows QR → scan → running
# whatsapp-web-bot.yamlplatform: whatsappmode: webagent: name: "WhatsApp Assistant" instructions: "You are a helpful AI assistant." llm: "gpt-4o-mini" memory: true
from praisonaiagents import BotConfigconfig = BotConfig( token="your-token", allowed_users=["user123", "user456"], allowed_channels=["channel789"])
from praisonaiagents import BotConfigconfig = BotConfig( token="your-token", webhook_url="https://your-domain.com/webhook", webhook_path="/telegram/webhook")
from praisonaiagents import BotConfigconfig = BotConfig( token="your-token", mention_required=True, # Only respond when @mentioned command_prefix="!", # Use ! for commands)
The Slack bot uses Slack Bolt, Slack’s official Python framework.
When running, you’ll see “⚡️ Bolt app is running!” - this confirms the bot is connected and listening.
By default, WhatsApp Web mode responds only to self-chat messages — when you message your own number. This prevents the bot from replying to every conversation on your account, including messages you send in other people’s chats.
Self-chat means messaging your own phone number — not just any message you send. Messages you send in other people’s chats or groups are filtered out by default.
Phone numbers are normalized automatically — +1-234-567-890, 1234567890, and (123) 456-7890 all match the same number. Group IDs use WhatsApp’s JID format (e.g., 120363123456@g.us).Stale message guard: Messages older than when the bot connected are always dropped, even with --respond-to-all. This prevents replaying old conversations on reconnect.
Run all bots simultaneously with a single gateway config:gateway.yaml:
agents: personal: name: "Personal Assistant" instructions: "You are a helpful personal assistant." llm: "gpt-4o-mini" support: name: "Support Agent" instructions: "You are a customer support agent." llm: "gpt-4o-mini"channels: telegram: token: "${TELEGRAM_BOT_TOKEN}" routing: dm: "personal" group: "support" default: "personal" discord: token: "${DISCORD_BOT_TOKEN}" routing: dm: "personal" channel: "support" default: "support" slack: token: "${SLACK_BOT_TOKEN}" app_token: "${SLACK_APP_TOKEN}" auto_approve_tools: true # NEW (default: true for chat bots) # default_tools: # NEW — override the safe tool list per channel # - search_web # - store_memory routing: dm: "personal" channel: "support" default: "support" whatsapp: token: "${WHATSAPP_ACCESS_TOKEN}" phone_number_id: "${WHATSAPP_PHONE_NUMBER_ID}" verify_token: "${WHATSAPP_VERIFY_TOKEN}" webhook_port: 8080 routing: dm: "personal" default: "personal" # Or use WhatsApp Web mode (no tokens needed): # whatsapp: # mode: web # routing: # dm: "personal" # default: "personal"
praisonai gateway --config gateway.yaml
The gateway now produces identical results to Bot() — agents get the same safe tools and auto-approval in both entry points.
The gateway uses routing rules to send messages to different agents based on context (DM vs group vs channel). Each channel can have its own routing configuration.
Run a bot with a single YAML file — no Python code needed:bot.yaml:
platform: telegramtoken: "${TELEGRAM_BOT_TOKEN}"agent: name: "My Assistant" instructions: "You are a helpful AI assistant." llm: "gpt-4o-mini" memory: true web_search: true tools: [search_web]
praisonai bot start --config bot.yaml
Tip: You can omit tools: entirely — the bot auto-injects safe defaults (search_web, schedule, memory, learning). Keep tools: [] only if you want the bot to run with zero tools.
The .env file in the current directory is auto-loaded, so you can store tokens there and reference them with ${VAR_NAME} syntax.
Never commit bot tokens to version control. Use environment variables or secure secret management.
Use allowlists in production
Set allowed_users and allowed_channels to prevent unauthorized access to your bot.
Enable mention requirement for groups
Set mention_required=True to prevent the bot from responding to every message in group chats.
Handle rate limits gracefully
Configure retry_attempts and implement exponential backoff for API rate limits.
Safe default tools only
The default tool list is intentionally safe (search_web, schedule_*, memory/learning). Tools like execute_command require explicit opt-in and should be paired with an approval backend. See Approval Protocol.
Set approval flow for auto-approve disabled
Only set auto_approve_tools: false if you’ve wired a chat-level approval flow (e.g. SlackApproval). Otherwise tool calls will hang silently waiting for a CLI prompt the user cannot see.
You can also define multiple agents in an agents.yaml file for complex workflows:agents.yaml:
agents: searcher: name: Researcher role: Web Researcher goal: Search the web for relevant information on the given topic instructions: | Search the web thoroughly for information on the user's query. Return comprehensive, accurate results with sources. tools: - search_web summarizer: name: Summarizer role: Content Summarizer goal: Create clear, concise summaries of information instructions: | Take the research findings and create a well-structured summary. Highlight key points and insights. Keep it concise but informative.
When users send multiple rapid messages (e.g. “hey” → “can you” → “search for AI news”), debounce coalesces them into a single agent call — saving tokens and preventing duplicate responses.
Long agent responses are split at paragraph boundaries while preserving code fences — no more broken code blocks mid-message.
How splitting works
1
Paragraph boundaries
Split at blank lines (\n\n) first — keeps ideas together.
2
Sentence boundaries
If a paragraph is still too long, split at sentence endings (. ).
3
Hard split
Last resort: character-level split for very long single lines.
Code fence protection
Code blocks wrapped in triple backticks are never split, even if they exceed max_message_length. This ensures your users always see complete, copyable code.
Smart chunking is enabled automatically for all bot adapters. No configuration needed.
Override max_message_length in BotConfig to change the split threshold (default: 4096).
Bot agents automatically remember the last 20 messages per conversation — no extra dependencies required.
Automatic (default)
Custom memory
from praisonaiagents import Agentfrom praisonai.bots import Bot# History is injected automatically — zero config neededagent = Agent(name="assistant", instructions="Be helpful")bot = Bot("telegram", agent=agent)bot.run()# Agent now remembers last 20 messages per session
from praisonaiagents import Agentfrom praisonai.bots import Bot# Override with your own memory configagent = Agent( name="assistant", instructions="Be helpful", memory={"history": True, "history_limit": 50} # Remember more)bot = Bot("telegram", agent=agent)bot.run()
Setting memory=True (full memory with ChromaDB) requires pip install praisonaiagents[memory].
The default history=True injection uses zero extra dependencies.
Acknowledge inbound messages with an emoji reaction (e.g. ⏳) so users know the bot is processing, then swap to a done emoji (e.g. ✅) when the response is sent.
Deploy bots entirely from YAML — including agent memory, tools, roles, and multi-platform config.
Full YAML
Python loader
agent: name: Research Bot role: AI Research Assistant goal: Help users find and understand AI research instructions: | You are a research assistant that helps users find and understand the latest AI research papers. llm: gpt-4o-mini memory: history: true history_limit: 30 tools: - search_webplatforms: telegram: token: ${TELEGRAM_BOT_TOKEN} debounce_ms: 1500 discord: token: ${DISCORD_BOT_TOKEN} slack: token: ${SLACK_BOT_TOKEN}
from praisonai.bots import BotOSbotos = BotOS.from_config("bot.yaml")botos.run() # Starts all platforms concurrently
Supported agent fields
Field
Type
Description
name
string
Agent display name
role
string
Role/job title
goal
string
Primary objective
backstory
string
Background context
instructions
string
Direct instructions
llm
string
Model name (gpt-4o-mini, claude-3-sonnet)
memory
bool/dict
Memory config (true or {history: true})
tools
list
Tool names from praisonaiagents.tools
knowledge
list
Knowledge sources
guardrail
string
Output validation
Environment variable syntax
Use ${ENV_VAR} in YAML values — resolved at load time.
When your bot agent uses dangerous tools (e.g. execute_command), you can route approval requests to Slack:
from praisonaiagents import Agentfrom praisonai.bots import Bot, SlackApprovalagent = Agent( name="assistant", instructions="You are a helpful assistant.", approval=SlackApproval(channel="#approvals") # Approvals go to Slack)bot = Bot("telegram", agent=agent) # Users talk via Telegrambot.run()