Skip to content

Latest commit

 

History

History
1807 lines (1456 loc) · 50.7 KB

File metadata and controls

1807 lines (1456 loc) · 50.7 KB
title Messaging Bots
sidebarTitle Messaging Bots
description Deploy AI agents to Telegram, Discord, Slack, and WhatsApp
icon robot

Messaging Bots enable your AI agents to interact with users across Telegram, Discord, Slack, and WhatsApp.

graph LR
    subgraph "Messaging Platforms"
        T[📱 Telegram]
        D[💬 Discord]
        S[💼 Slack]
        W[📲 WhatsApp]
        SG[🔐 Signal]
        L[🟢 LINE]
        IM[🍎 iMessage]
    end
    
    subgraph "Communication"
        TW[📞 Twilio SMS]
        WX[🎥 Webex]
        X[𝕏 X/Twitter]
        E[📧 Email]
    end
    
    T --> B[🤖 Bot Runtime]
    D --> B
    S --> B
    W --> B
    E --> B
    SG --> B
    L --> B
    IM --> B
    
    TW --> B
    WX --> B
    X --> B
    
    B --> A[🧠 Agent]
    
    classDef platform fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef comm fill:#2E8B57,stroke:#7C90A0,color:#fff
    classDef bot fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef agent fill:#8B0000,stroke:#7C90A0,color:#fff
    
    class T,D,S,W,SG,L,IM platform
    class TW,WX,X,E comm
    class B bot
    class A agent
Loading

Quick Start

Start a bot with a single command - no Python code required: ```bash # Telegram export TELEGRAM_BOT_TOKEN="123456:ABC-DEF..."

Discord

export DISCORD_BOT_TOKEN="MTIz..."

Slack (requires both tokens)

export SLACK_BOT_TOKEN="xoxb-..." export SLACK_APP_TOKEN="xapp-..."

WhatsApp (Cloud API)

export WHATSAPP_ACCESS_TOKEN="EAAx..." export WHATSAPP_PHONE_NUMBER_ID="123456789" export WHATSAPP_VERIFY_TOKEN="my-secret-verify"

</Step>

<Step title="Start the Bot">
```bash
# Telegram
praisonai bot telegram --token $TELEGRAM_BOT_TOKEN

# Discord
praisonai bot discord --token $DISCORD_BOT_TOKEN

# Slack
praisonai bot slack --token $SLACK_BOT_TOKEN --app-token $SLACK_APP_TOKEN

# WhatsApp Cloud API (starts a webhook server on port 8080)
praisonai bot whatsapp --token $WHATSAPP_ACCESS_TOKEN --phone-id $WHATSAPP_PHONE_NUMBER_ID

# WhatsApp Web Mode (no tokens needed — scan QR code)
praisonai bot whatsapp --mode web

# Email Bot
praisonai bot email --address bot@gmail.com --password "xxxx xxxx xxxx xxxx"

# AgentMail Bot (API-first, no IMAP/SMTP)
praisonai bot agentmail --token $AGENTMAIL_API_KEY

A default agent is created automatically with basic assistant capabilities.

```bash # Use a custom agent configuration praisonai bot slack --token $SLACK_BOT_TOKEN --app-token $SLACK_APP_TOKEN --agent agents.yaml ```

agents.yaml:

name: support-bot
instructions: |
  You are a customer support assistant.
  Be helpful and concise.
llm: gpt-4o-mini
tools:
  - search_web
Full programmatic control with Python: ```python from praisonaiagents import Agent

agent = Agent( name="assistant", instructions="Help users with their questions", llm="gpt-4o-mini" )

</Step>

<Step title="Configure Bot">
```python
from praisonaiagents import BotConfig

config = BotConfig(
    token="your-bot-token",
    command_prefix="/",
    typing_indicator=True,
    reply_in_thread=False,  # Inline replies
)
```python from praisonai.bots import SlackBot # or TelegramBot, DiscordBot

bot = SlackBot( token="xoxb-...", app_token="xapp-...", agent=agent, config=config )

Run the bot

import asyncio asyncio.run(bot.start())

</Step>

<Step title="Email Bot Example">
```python
from praisonai.bots import EmailBot

bot = EmailBot(
    address="bot@gmail.com",
    password="xxxx xxxx xxxx xxxx",
    agent=agent
)
asyncio.run(bot.start())

Supported Platforms

Bot Runtimes (Bidirectional — Send + Receive)

Bot Class Platform Env Variable Status
SlackBot Slack SLACK_BOT_TOKEN, SLACK_APP_TOKEN
DiscordBot Discord DISCORD_BOT_TOKEN
TelegramBot Telegram TELEGRAM_BOT_TOKEN
WhatsAppBot WhatsApp Business WHATSAPP_ACCESS_TOKEN, WHATSAPP_PHONE_NUMBER_ID
EmailBot Email (IMAP/SMTP) EMAIL_ADDRESS, EMAIL_APP_PASSWORD
AgentMailBot AgentMail (API) AGENTMAIL_API_KEY

Outbound Tools (Send-Only — Bot Runtime Coming Soon)

Tool Platform Env Variable Bot Runtime
SignalTool Signal Requires signal-cli daemon 🔜 Coming Soon
LineTool LINE LINE_CHANNEL_ACCESS_TOKEN 🔜 Coming Soon
iMessageTool iMessage (macOS only) No token needed 🔜 Coming Soon
TwilioTool SMS/Voice TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN 🔜 Coming Soon
WebexTool Webex WEBEX_ACCESS_TOKEN 🔜 Coming Soon
XTool X (Twitter) X_API_KEY, X_API_SECRET 🔜 Coming Soon
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


How It Works

sequenceDiagram
    participant User
    participant Platform
    participant Bot
    participant Agent
    
    User->>Platform: Send Message
    Platform->>Bot: Webhook/Poll
    Bot->>Agent: Process Request
    Agent->>Bot: Generate Response
    Bot->>Platform: Send Reply
    Platform-->>User: Display Message
Loading
Component Role
Platform Telegram, Discord, Slack, or WhatsApp
Bot Message router and formatter
Agent AI processing and response
User End user on messaging app

AIUI Dashboard Integration

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.

sequenceDiagram
    participant Platform as Slack/Discord/Telegram
    participant Bot as Bot Runtime
    participant Bridge as Chat Bridge
    participant Agent as agent.chat()
    participant UI as Chat UI (WebSocket)

    Platform->>Bot: User message
    Bot->>Bridge: _session.chat()
    Bridge->>Agent: Attach StreamEventEmitter callback
    Bridge->>Agent: Execute agent
    Agent-->>Bridge: tool_call_started (via emitter)
    Bridge-->>UI: broadcast({type: tool_call_started, platform: slack})
    Agent-->>Bridge: tool_call_completed (via emitter)
    Bridge-->>UI: broadcast({type: tool_call_completed, ...})
    Agent->>Bridge: Final response
    Bridge->>Bridge: Remove callback
    Bridge-->>UI: broadcast({type: channel_response, content: ...})
    Bridge->>Platform: Send reply
Loading

What You See in the Dashboard

Feature Description
Tool call steps Each tool the agent uses appears as a collapsible step with icon, description, and result
Reasoning steps Chain-of-thought reasoning streams in real-time
Platform icon Session sidebar shows the platform badge (e.g. 💬 Slack, ✈️ Telegram)
Message history 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.

Smart Defaults

Bots ship with sensible defaults so you can start chatting immediately — no tool wiring required.

graph LR
    A[🤖 Agent<br/>tools=None] --> SD[⚙️ Smart Defaults]
    SD --> T[🔍 search_web<br/>📅 schedule_*<br/>🧠 memory<br/>📚 learning]
    SD --> AA[✅ auto-approve<br/>for safe tools]
    SD --> H[💬 session history<br/>last 20 messages]

    classDef agent fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef config fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef tools fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef result fill:#10B981,stroke:#7C90A0,color:#fff

    class A agent
    class SD config
    class T tools
    class AA,H result
Loading

Both praisonai bot start and praisonai gateway start apply the same defaults:

Default Applied when What you get
Safe tools Agent has no tools configured search_web, web_crawl, schedule_*, store_memory/search_memory, store_learning/search_learning
Auto-approval auto_approve_tools=True (default) Tool calls run without CLI prompts — chat bots can't show them anyway
Session history Agent has no memory configured Last 20 messages remembered per user, zero-dep

Opting out

Goal How
Run with zero tools 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 Agent
from praisonai.bots import Bot

# Zero config — gets search_web, schedule_*, memory, learning, and auto-approval
agent = Agent(name="assistant", instructions="Help the user")
bot = Bot("telegram", agent=agent)
bot.run()
# Same result — no YAML tool list needed
praisonai bot telegram --token $TELEGRAM_BOT_TOKEN
sequenceDiagram
    participant U as 👤 User (Telegram)
    participant B as 🤖 Bot
    participant A as 🧠 Agent
    participant T as 🔍 search_web

    U->>B: "What's the latest on Llama 4?"
    B->>A: Forward message (no tool prompt)
    A->>T: auto-approved call
    T-->>A: Results
    A-->>B: Answer
    B-->>U: 📰 Here's the latest...
Loading

Socket Mode vs Webhook

PraisonAI bots support two connection modes:

graph LR
    subgraph "Socket Mode (Default)"
        L[🖥️ Local Bot] -->|WebSocket outbound| S[☁️ Slack Cloud]
        S -->|Events| L
    end
    
    subgraph "Webhook Mode (Production)"
        W[🌐 Public Server] <-->|HTTPS| P[☁️ Platform API]
    end
    
    classDef local fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef cloud fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef server fill:#2E8B57,stroke:#7C90A0,color:#fff
    
    class L local
    class S,P cloud
    class W server
Loading
Mode Use Case Requirements
Socket Mode Local development, behind firewall App Token only
Webhook Mode Production, high scale Public URL with HTTPS
**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.

Configuration Options

from praisonaiagents import BotConfig

config = BotConfig(
    token="bot-token",              # Bot authentication token
    webhook_url=None,               # Webhook URL (optional)
    command_prefix="/",             # Command prefix
    mention_required=True,          # Require @mention in groups
    typing_indicator=True,          # Show typing indicator
    max_message_length=4096,        # Max message length
    allowed_users=[],               # Allowed user IDs (empty = all)
    allowed_channels=[],            # Allowed channel IDs
    reply_in_thread=False,          # Reply in threads (default: inline)
    thread_threshold=500,           # Auto-thread if response > N chars (0 = disabled)
    group_policy="mention_only",    # Group chat policy: respond_all, mention_only, command_only
    auto_approve_tools=True,        # Auto-approve safe tool executions (default: True for chat bots)
)
Option Type Default Description
token str "" Bot authentication token
webhook_url str None Webhook URL for webhook mode
command_prefix str "/" Prefix for bot commands
mention_required bool True Require @mention in channels (DMs never require mention)
typing_indicator bool True Show typing indicator
max_message_length int 4096 Max message length
allowed_users list [] Allowed user IDs
allowed_channels list [] Allowed channel IDs
timeout int 30 Request timeout
reply_in_thread bool False Always reply in threads
thread_threshold int 500 Auto-thread responses longer than N chars (0 = disabled)
group_policy str "mention_only" Group chat behavior: respond_all, mention_only, or command_only
default_tools list[str] ["search_web", "web_crawl", "schedule_add", "schedule_list", "schedule_remove", "store_memory", "search_memory", "store_learning", "search_learning"] 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).
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`

CLI Capabilities

Enable powerful agent features directly from the command line:

graph LR
    CLI["praisonai bot slack"]:::tool --> CAPS["Capabilities"]:::tool
    CAPS --> MEM["--memory"]:::agent
    CAPS --> KNOW["--knowledge"]:::agent
    CAPS --> SKILLS["--skills"]:::agent
    CAPS --> THINK["--thinking"]:::agent
    CAPS --> WEB["--web"]:::agent
    
    classDef agent fill:#8B0000,color:#fff
    classDef tool fill:#189AB4,color:#fff
Loading
```bash praisonai bot slack --memory ``` Bot remembers previous conversations ```bash praisonai bot slack --knowledge \ --knowledge-sources docs.pdf manual.txt ``` Answer from your documents ```bash praisonai bot slack --skills researcher writer ``` Load named skill modules ```bash praisonai bot slack --thinking high ``` Enable reflection mode (off/minimal/low/medium/high) | Flag | Description | Example | |------|-------------|---------| | `--memory` | Enable conversation memory | `--memory` | | `--memory-provider` | Memory backend | `--memory-provider chroma` | | `--knowledge` | Enable RAG/knowledge | `--knowledge` | | `--knowledge-sources` | Source files | `--knowledge-sources file.pdf` | | `--skills` | Skill modules | `--skills researcher` | | `--thinking` | Thinking mode | `--thinking high` | | `--web` | Enable web search | `--web` | | `--web-provider` | Search provider | `--web-provider duckduckgo` | | `--browser` | Enable browser | `--browser` | | `--tools` | Named tools | `--tools WikipediaTool` | | `--sandbox` | Sandbox mode | `--sandbox` | | `--auto-approve` | Auto-approve tool executions | `--auto-approve` |

Platform Setup

1. Message [@BotFather](https://t.me/BotFather) on Telegram 2. Send `/newbot` and follow prompts 3. Copy the bot token
export TELEGRAM_BOT_TOKEN="123456:ABC-DEF..."
praisonai bot telegram --token $TELEGRAM_BOT_TOKEN
1. Go to [Discord Developer Portal](https://discord.com/developers/applications) 2. Create new application → Bot → Reset Token 3. Enable Message Content Intent 4. Invite bot to server with proper permissions
export DISCORD_BOT_TOKEN="MTIz..."
praisonai bot discord --token $DISCORD_BOT_TOKEN
1. Go to [Slack API Console](https://api.slack.com/apps) 2. Click **Create New App** → **From scratch** 3. Enter app name (e.g., "PraisonAI Bot") and select workspace 1. Go to **OAuth & Permissions** in the sidebar 2. Scroll to **Scopes** → **Bot Token Scopes** 3. Add these scopes:
Scope Purpose
chat:write Send messages
app_mentions:read Receive @mentions
im:history Read DM history
im:read Access DMs
channels:history Read channel messages
  1. Click Install to Workspace at the top
  2. Copy the Bot User OAuth Token (xoxb-...)
1. Go to **Socket Mode** in the sidebar 2. Toggle **Enable Socket Mode** ON 3. When prompted, create an app-level token: - Token Name: `socket-mode` - Add scope: `connections:write` 4. Copy the **App Token** (`xapp-...`) **This step is critical!** Without event subscriptions, the bot won't receive messages.
  1. Go to Event Subscriptions in the sidebar
  2. Toggle Enable Events ON
  3. Scroll to Subscribe to bot events
  4. Add these events:
Event Purpose
app_mention When someone @mentions your bot
message.im Direct messages to your bot
  1. Click Save Changes
  2. Reinstall the app when prompted (or go to OAuth & Permissions → Reinstall)
1. Go to **App Home** in the sidebar 2. Scroll to **Show Tabs** → **Messages Tab** 3. Ensure **Allow users to send Slash commands and messages from the messages tab** is toggled **ON** ```bash export SLACK_BOT_TOKEN="xoxb-..." # Bot User OAuth Token export SLACK_APP_TOKEN="xapp-..." # App-Level Token

praisonai bot slack --token $SLACK_BOT_TOKEN --app-token $SLACK_APP_TOKEN


You should see:

⚡️ Bolt app is running!

</Step>

<Step title="Test the Bot">
1. **Direct Message**: Send a DM to your bot
2. **Channel Mention**: In any channel, type `/invite @YourBotName` first, then `@YourBotName hello`
</Step>

</Steps>

<AccordionGroup>
<Accordion title="Troubleshooting: Bot not responding">
**Check these in order:**

1. **Event Subscriptions enabled?** → Must be ON
2. **Bot events subscribed?** → `app_mention` and `message.im` must be listed
3. **Reinstalled after changes?** → Required after adding scopes/events
4. **App Token provided?** → `--app-token` is required for Socket Mode
5. **Bot invited to channel?** → Use `/invite @BotName` before @mentioning
</Accordion>

<Accordion title="Required Scopes Summary">
| Scope | Required For |
|-------|--------------|
| `chat:write` | Sending messages |
| `app_mentions:read` | @mention events |
| `im:history` | DM access |
| `im:read` | DM access |
| `channels:history` | Channel message access |
| `connections:write` | Socket Mode (app token) |
</Accordion>
</AccordionGroup>

</Tab>

<Tab title="WhatsApp">

<Steps>

<Step title="Create Meta App">
1. Go to [Meta for Developers](https://developers.facebook.com/)
2. Click **Create App** → Select **Business** type
3. Add the **WhatsApp** product to your app
</Step>

<Step title="Get API Credentials">
1. In the WhatsApp section, go to **API Setup**
2. Copy your **Phone Number ID** and **Access Token**
3. Create a **Verify Token** (any secret string you choose)

<Warning>
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.
</Warning>
</Step>

<Step title="Configure Webhook">
1. Go to **Configuration** → **Webhook**
2. Click **Edit** and enter:
   - **Callback URL**: `https://your-domain.com/webhook`
   - **Verify Token**: The same string you set in `WHATSAPP_VERIFY_TOKEN`
3. Subscribe to: `messages`

<Note>
For local development, use [ngrok](https://ngrok.com/) to create a public HTTPS URL:
```bash
ngrok http 8080

Then use the ngrok URL as your callback URL.

```bash export WHATSAPP_ACCESS_TOKEN="EAAx..." export WHATSAPP_PHONE_NUMBER_ID="123456789" export WHATSAPP_VERIFY_TOKEN="my-secret-verify"

praisonai bot whatsapp --token $WHATSAPP_ACCESS_TOKEN --phone-id $WHATSAPP_PHONE_NUMBER_ID


You should see:

WhatsApp webhook server starting on port 8080

</Step>

<Step title="Test the Bot">
Send a WhatsApp message to your business phone number. The bot will reply via the Cloud API.
</Step>

</Steps>

<AccordionGroup>
<Accordion title="Troubleshooting: Webhook not verifying">
1. **Verify token matches?** → Must be identical in Meta console and env var
2. **Bot running?** → Webhook server must be up before configuring in Meta
3. **HTTPS required?** → Meta only accepts HTTPS webhook URLs
4. **ngrok running?** → If using ngrok, ensure the tunnel is active
</Accordion>

<Accordion title="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 |
</Accordion>
</AccordionGroup>

</Tab>

<Tab title="WhatsApp Web Mode">

<Warning>
**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.
</Warning>

WhatsApp Web mode connects directly via the WhatsApp Web protocol — **no tokens, no Meta developer account, no webhooks needed**. Just scan a QR code.

```mermaid
graph LR
    QR["📱 Scan QR Code"] --> WA["WhatsApp Servers"]
    WA <-->|"WebSocket"| Bot["🤖 PraisonAI Bot"]
    Bot --> Agent["🧠 AI Agent"]
    
    style QR fill:#8B0000,color:#fff
    style Bot fill:#189AB4,color:#fff
    style Agent fill:#8B0000,color:#fff
    style WA fill:#189AB4,color:#fff
```bash pip install 'praisonai[bot-whatsapp-web]' ``` This installs `neonize` (WhatsApp Web client with built-in QR display). ```bash praisonai bot whatsapp --mode web ```

A QR code appears in your terminal. Open WhatsApp on your phone → SettingsLinked DevicesLink a Device → scan the QR code.

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.

```bash # Basic web mode praisonai bot whatsapp --mode web

With custom credentials directory

praisonai bot whatsapp --mode web --creds-dir ~/.myapp/wa-creds

With agent capabilities

praisonai bot whatsapp --mode web --agent agents.yaml --memory --web

</Tab>
<Tab title="Python">
```python
from praisonaiagents import Agent
from praisonai.bots import WhatsAppBot

agent = Agent(name="assistant", instructions="Be helpful")

# Web mode — no tokens needed
bot = WhatsAppBot(mode="web", agent=agent)

import asyncio
asyncio.run(bot.start())  # Shows QR → scan → running
```yaml # whatsapp-web-bot.yaml platform: whatsapp mode: web

agent: name: "WhatsApp Assistant" instructions: "You are a helpful AI assistant." llm: "gpt-4o-mini" memory: true

```bash
praisonai bot start --config whatsapp-web-bot.yaml

Cloud API vs Web Mode

Feature Cloud API (default) Web Mode (experimental)
Setup Meta developer account + tokens QR code scan only
Auth WHATSAPP_ACCESS_TOKEN Saved locally (SQLite)
Webhooks Required (public HTTPS URL) Not needed
Group chats DMs only DMs + groups
Reactions Limited Full support
Media Via upload API Direct
Stability Official API, stable Reverse-engineered, may break
Risk None Account may be banned
Best for Production Development, personal use
1. **Terminal supports Unicode?** → Use a modern terminal (iTerm2, Windows Terminal, etc.) 2. **Dependencies installed?** → Run `pip install 'praisonai[bot-whatsapp-web]'` — this includes `segno` for QR rendering 3. **Already linked?** → If a saved session exists, no QR is shown. Delete creds to re-link: ```bash rm -rf ~/.praisonai/whatsapp/ ``` 4. **QR times out?** → WhatsApp QR codes expire after ~60 seconds. Restart the bot to get a fresh one. WhatsApp Web sessions expire if your phone is offline for **14+ days**. Delete the saved session and scan again: ```bash rm -rf ~/.praisonai/whatsapp/ praisonai bot whatsapp --mode web ``` By default: `~/.praisonai/whatsapp/praisonai_whatsapp.db` (SQLite).

Override with --creds-dir or WHATSAPP_CREDS_DIR environment variable.


Bot Commands

Built-in commands available on all platforms:

Command Description
/help Show available commands and agent info
/status Show agent name, model, platform, and uptime
/new Reset conversation session — starts a fresh chat

You can register custom commands programmatically:

bot.register_command("ping", my_handler, description="Check latency")
See [Bot Chat Commands](/features/bot-commands) for full details on custom command registration and platform-specific behavior.

Common Patterns

```python from praisonaiagents import BotConfig

config = BotConfig( token="your-token", allowed_users=["user123", "user456"], allowed_channels=["channel789"] )

</Tab>

<Tab title="Webhook Mode">
```python
from praisonaiagents import BotConfig

config = BotConfig(
    token="your-token",
    webhook_url="https://your-domain.com/webhook",
    webhook_path="/telegram/webhook"
)
```python from praisonaiagents import BotConfig

config = BotConfig( token="your-token", mention_required=True, # Only respond when @mentioned command_prefix="!", # Use ! for commands )

</Tab>
</Tabs>

---

## CLI Commands

```bash
# Start Telegram bot
praisonai bot telegram --token $TOKEN

# Start Discord bot
praisonai bot discord --token $TOKEN

# Start Slack bot  
praisonai bot slack --token $TOKEN --app-token $APP_TOKEN

# Start WhatsApp bot (webhook server)
praisonai bot whatsapp --token $TOKEN --phone-id $PHONE_ID --verify-token $VERIFY

# With agent configuration
praisonai bot telegram --token $TOKEN --agent agents.yaml
The Slack bot uses [Slack Bolt](https://slack.dev/bolt-python/), Slack's official Python framework. When running, you'll see "⚡️ Bolt app is running!" - this confirms the bot is connected and listening.

WhatsApp Message Filtering (Web Mode)

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.

graph TD
    MSG["📩 Incoming Message"] --> STALE{"Older than\nconnect time?"}
    STALE -->|"Yes"| DROP["🗑️ Drop (stale)"]
    STALE -->|"No"| SELF{"Self-chat?\n(sender = chat JID)"}
    SELF -->|"Yes"| ALLOW["✅ Process"]
    SELF -->|"No"| ALLOW_LIST{"In allowlist?"}
    ALLOW_LIST -->|"Yes"| ALLOW
    ALLOW_LIST -->|"No"| IGNORE["❌ Ignore"]

    classDef stale fill:#6B7280,stroke:#7C90A0,color:#fff
    classDef check fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef allow fill:#10B981,stroke:#7C90A0,color:#fff
    classDef ignore fill:#EF4444,stroke:#7C90A0,color:#fff

    class STALE,SELF check
    class DROP,IGNORE ignore
    class ALLOW allow
    class ALLOW_LIST check
Loading
**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.

CLI Flags

```bash # Only responds when YOU message yourself praisonai bot whatsapp --mode web ``` ```bash # Also respond to specific phone numbers praisonai bot whatsapp --mode web --respond-to 1234567890,9876543210 ``` ```bash # Also respond in specific groups praisonai bot whatsapp --mode web --respond-to-groups 120363123456@g.us ``` ```bash # Specific numbers AND groups praisonai bot whatsapp --mode web \ --respond-to 1234567890 \ --respond-to-groups 120363123456@g.us ``` ```bash # Respond to every message (old behavior) praisonai bot whatsapp --mode web --respond-to-all ```

Python SDK

from praisonaiagents import Agent
from praisonai.bots import WhatsAppBot

agent = Agent(name="assistant", instructions="You are a helpful bot")

bot = WhatsAppBot(
    mode="web",
    agent=agent,
    allowed_numbers=["1234567890", "9876543210"],
    allowed_groups=["120363123456@g.us"],
    respond_to_all=False,  # default
)

import asyncio
asyncio.run(bot.start())

YAML Config

platform: whatsapp
mode: web

respond_to:
  - "1234567890"
  - "9876543210"
respond_to_groups:
  - "120363123456@g.us"
respond_to_all: false

agent:
  name: "My Assistant"
  instructions: "You are a helpful AI assistant."
  llm: "gpt-4o-mini"
praisonai bot start --config bot.yaml

Filtering Behavior Matrix

Scenario Default --respond-to 123 --respond-to-groups g@g.us --respond-to-all
Self-chat (message your own number)
Your message in someone else's chat
DM from 123
DM from 999
Group g@g.us
Other group
Old/offline messages
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.


Docker Deployment

Deploy bots using Docker for production environments:

```bash # Create .env file cat > .env << EOF OPENAI_API_KEY=your-openai-key SLACK_BOT_TOKEN=xoxb-your-slack-bot-token SLACK_APP_TOKEN=xapp-your-slack-app-token EOF

Run with docker compose

docker compose up slack-bot -d

View logs

docker compose logs -f slack-bot

</Tab>

<Tab title="Discord">
```bash
# Create .env file
cat > .env << EOF
OPENAI_API_KEY=your-openai-key
DISCORD_BOT_TOKEN=your-discord-bot-token
EOF

# Run with docker compose
docker compose up discord-bot -d
```bash # Create .env file cat > .env << EOF OPENAI_API_KEY=your-openai-key TELEGRAM_BOT_TOKEN=your-telegram-bot-token EOF

Run with docker compose

docker compose up telegram-bot -d

</Tab>
</Tabs>

**docker-compose.yml:**
```yaml
version: '3.8'
services:
  slack-bot:
    image: python:3.11-slim
    environment:
      OPENAI_API_KEY: ${OPENAI_API_KEY}
      SLACK_BOT_TOKEN: ${SLACK_BOT_TOKEN}
      SLACK_APP_TOKEN: ${SLACK_APP_TOKEN}
    command: >
      bash -c "pip install praisonai slack-bolt slack-sdk &&
               praisonai bot slack"
    restart: unless-stopped
For production, build a dedicated Docker image instead of installing dependencies at runtime. See the [docker/bots](https://github.com/MervinPraison/PraisonAI/tree/main/docker/bots) folder for ready-to-use Dockerfiles.

Production (Webhook Mode)

For production deployments with a public URL, use webhook mode instead of Socket Mode:

```python from praisonaiagents import BotConfig from praisonai.bots import SlackBot

config = BotConfig( token="xoxb-your-slack-bot-token", webhook_url="https://your-domain.com", webhook_path="/slack/events" )

bot = SlackBot(config=config) bot.start() # Listens on /slack/events


Configure in Slack API Console:
1. **Event Subscriptions** → Enable Events
2. Set Request URL: `https://your-domain.com/slack/events`
3. Subscribe to bot events: `app_mention`, `message.im`
</Tab>

<Tab title="Discord">
```python
from praisonaiagents import BotConfig
from praisonai.bots import DiscordBot

# Discord uses Gateway (WebSocket) by default
# For HTTP interactions, configure interaction endpoint:
config = BotConfig(
    token="your-discord-bot-token",
    webhook_url="https://your-domain.com",
    webhook_path="/discord/interactions"
)

bot = DiscordBot(config=config)
bot.start()

Configure in Discord Developer Portal:

  1. General Information → Interactions Endpoint URL
  2. Set: https://your-domain.com/discord/interactions
```python from praisonaiagents import BotConfig from praisonai.bots import TelegramBot

config = BotConfig( token="your-telegram-bot-token", webhook_url="https://your-domain.com", webhook_path="/telegram/webhook" )

bot = TelegramBot(config=config) bot.start() # Automatically registers webhook with Telegram


Telegram automatically configures the webhook when you start the bot.
</Tab>
</Tabs>

<Warning>
Webhook mode requires:
- **Public HTTPS URL** with valid SSL certificate
- **Port 443** (or 80/88/8443 for Telegram)
- **Firewall rules** allowing inbound connections
</Warning>

---

## Multi-Channel Gateway

Run **all bots simultaneously** with a single gateway config:

**gateway.yaml:**
```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.

graph LR
    T[Telegram]:::platform --> GW[Gateway]:::tool
    D[Discord]:::platform --> GW
    S[Slack]:::platform --> GW
    W[WhatsApp]:::platform --> GW
    GW --> A1[Personal Agent]:::agent
    GW --> A2[Support Agent]:::agent

    classDef platform fill:#189AB4,color:#fff
    classDef tool fill:#F59E0B,color:#fff
    classDef agent fill:#8B0000,color:#fff
Loading
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.

Zero-Code Mode (YAML Config)

Run a bot with a single YAML file — no Python code needed:

bot.yaml:

platform: telegram
token: "${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.

Token Types — When to Use What

Different platforms use different types of tokens. Here's when to use each:

Telegram

Token Format When to Use
Bot Token 123456:ABC-DEF... Always required. Get from @BotFather. Used for all bot operations.

Discord

Token Format When to Use
Bot Token MTIz... Always required. Get from Discord Developer Portal → Bot → Reset Token. Used for bot authentication.

Slack

Token Format When to Use
Bot Token xoxb-... Always required. Get from OAuth & Permissions → Install to Workspace. Used for sending messages and API calls.
App Token xapp-... Required for Socket Mode (default). Get from Socket Mode settings. Enables WebSocket connection without a public URL.
Client ID 12345.67890 OAuth flow only. Used when building apps that are installed by multiple workspaces (not needed for single-workspace bots).
Client Secret d119ac... OAuth flow only. Used with Client ID for the OAuth2 authorization flow. Never expose publicly.
**Common mistake:** Using Client ID/Secret instead of Bot Token + App Token. For most bots, you only need: - `SLACK_BOT_TOKEN` (xoxb-...) — for API operations - `SLACK_APP_TOKEN` (xapp-...) — for Socket Mode connection

Client ID and Client Secret are only needed if you're distributing your app to multiple Slack workspaces via OAuth.

WhatsApp

| Token | Format | When to Use | |-------|--------|-------------| | **Access Token** | `EAAx...` | **Required.** Get from Meta for Developers → WhatsApp → API Setup. Used for sending messages via Cloud API. | | **Phone Number ID** | `123456789` | **Required.** Found in API Setup page. Identifies which WhatsApp business number to send from. | | **Verify Token** | Any string | **Required for webhooks.** A secret string you create. Must match in both Meta console and your environment. | | **App Secret** | `abc123...` | **Optional.** Used to verify webhook signatures for security. Found in App Settings → Basic. | | Token | Format | When to Use | |-------|--------|-------------| | **None** | — | **No tokens needed.** Web mode authenticates via QR code scan (WhatsApp Linked Devices). |

Credentials are saved locally in SQLite at ~/.praisonai/whatsapp/. Override with --creds-dir or WHATSAPP_CREDS_DIR.

Web mode uses a reverse-engineered protocol. Your number may be banned by Meta. Use Cloud API for production.

Best Practices

Never commit bot tokens to version control. Use environment variables or secure secret management. Set `allowed_users` and `allowed_channels` to prevent unauthorized access to your bot. Set `mention_required=True` to prevent the bot from responding to every message in group chats. Configure `retry_attempts` and implement exponential backoff for API rate limits. 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](/features/approval-protocol). 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.

Multi-Agent Configuration

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.

Inbound Message Debounce

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.

sequenceDiagram
    participant U as 👤 User
    participant D as ⏱️ Debouncer
    participant A as 🧠 Agent

    U->>D: "hey"
    Note over D: Start 1500ms timer
    U->>D: "can you"
    Note over D: Reset timer
    U->>D: "search for AI news"
    Note over D: Reset timer
    Note over D: Timer expires ✓
    D->>A: "hey\ncan you\nsearch for AI news"
    A->>U: 📰 Here are the latest AI news...
Loading
```python from praisonaiagents import Agent from praisonaiagents.bots import BotConfig from praisonai.bots import Bot

agent = Agent(name="assistant", instructions="Be helpful") config = BotConfig(debounce_ms=1500) # 1.5s window

bot = Bot("telegram", agent=agent, config=config) bot.run()

  </Tab>
  <Tab title="YAML">
```yaml
agent:
  name: assistant
  instructions: Be helpful

platforms:
  telegram:
    token: ${TELEGRAM_BOT_TOKEN}
    debounce_ms: 1500
Set `debounce_ms: 0` (default) to disable debouncing for real-time response bots. Recommended: **1000–2000ms** for conversational bots.

Smart Message Chunking

Long agent responses are split at paragraph boundaries while preserving code fences — no more broken code blocks mid-message.

graph TD
    R["🧠 Agent Response<br/>(8000 chars)"] --> C{Chunker}
    C -->|"Paragraph 1"| M1["📨 Message 1<br/>Introduction"]
    C -->|"Code Block"| M2["📨 Message 2<br/>```python...```"]
    C -->|"Paragraph 3"| M3["📨 Message 3<br/>Conclusion"]

    style R fill:#8B0000,color:#fff
    style C fill:#189AB4,color:#fff
    style M1 fill:#189AB4,color:#fff
    style M2 fill:#189AB4,color:#fff
    style M3 fill:#189AB4,color:#fff
Loading
Split at blank lines (`\n\n`) first — keeps ideas together. If a paragraph is still too long, split at sentence endings (`. `). Last resort: character-level split for very long single lines. 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).

Session History

Bot agents automatically remember the last 20 messages per conversation — no extra dependencies required.

graph LR
    U1["👤 User: What is Python?"] --> A1["🧠 Agent: Python is..."]
    A1 --> U2["👤 User: Show me an example"]
    U2 --> A2["🧠 Agent: Sure! Based on<br/>our Python discussion..."]

    style U1 fill:#8B0000,color:#fff
    style A1 fill:#189AB4,color:#fff
    style U2 fill:#8B0000,color:#fff
    style A2 fill:#189AB4,color:#fff
Loading
```python from praisonaiagents import Agent from praisonai.bots import Bot

History is injected automatically — zero config needed

agent = Agent(name="assistant", instructions="Be helpful") bot = Bot("telegram", agent=agent) bot.run()

Agent now remembers last 20 messages per session

  </Tab>
  <Tab title="Custom memory">
```python
from praisonaiagents import Agent
from praisonai.bots import Bot

# Override with your own memory config
agent = 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**.

Ack Reactions

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.

sequenceDiagram
    participant U as 👤 User
    participant B as 🤖 Bot
    participant A as 🧠 Agent

    U->>B: "Summarize this article"
    B->>U: React ⏳
    B->>A: Process message
    A->>B: Response ready
    B->>U: Send response
    B->>U: Remove ⏳, React ✅
Loading
```python from praisonaiagents import Agent from praisonaiagents.bots import BotConfig from praisonai.bots import Bot

agent = Agent(name="assistant", instructions="Be helpful") config = BotConfig(ack_emoji="⏳", done_emoji="✅")

bot = Bot("telegram", agent=agent, config=config) bot.run()

  </Tab>
  <Tab title="YAML">
```yaml
agent:
  name: assistant
  instructions: Be helpful

platforms:
  telegram:
    token: ${TELEGRAM_BOT_TOKEN}
    ack_emoji: "⏳"
    done_emoji: "✅"
Set `ack_emoji: ""` (default) to disable ack reactions. Currently wired for Telegram (which supports native message reactions).

Session Reaper

Automatically prune stale sessions to free memory on long-running bots. Sessions idle longer than session_ttl seconds are reaped.

from praisonaiagents import Agent
from praisonaiagents.bots import BotConfig
from praisonai.bots import Bot

agent = Agent(name="assistant", instructions="Be helpful")
config = BotConfig(session_ttl=86400)  # Reap sessions older than 24h

bot = Bot("telegram", agent=agent, config=config)
bot.run()
Set `session_ttl: 0` (default) to disable automatic reaping. You can also call `bot._session.reap_stale(max_age_seconds)` manually.

YAML Configuration

Deploy bots entirely from YAML — including agent memory, tools, roles, and multi-platform config.

```yaml 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_web

platforms: telegram: token: ${TELEGRAM_BOT_TOKEN} debounce_ms: 1500 discord: token: ${DISCORD_BOT_TOKEN} slack: token: ${SLACK_BOT_TOKEN}

  </Tab>
  <Tab title="Python loader">
```python
from praisonai.bots import BotOS

botos = BotOS.from_config("bot.yaml")
botos.run()  # Starts all platforms concurrently
| 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 | Use `${ENV_VAR}` in YAML values — resolved at load time. ```yaml platforms: telegram: token: ${TELEGRAM_BOT_TOKEN} ```

Tool Approval via Messaging

When your bot agent uses dangerous tools (e.g. execute_command), you can route approval requests to Slack:

from praisonaiagents import Agent
from praisonai.bots import Bot, SlackApproval

agent = 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 Telegram
bot.run()
See [Approval Protocol](/features/approval-protocol#slack-approval) for full configuration options.

Related

Tool execution approval system Multi-agent coordination Event-driven integrations