> ## Documentation Index
> Fetch the complete documentation index at: https://docs.praison.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Messaging Bots

> Deploy AI agents to Telegram, Discord, Slack, and WhatsApp

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

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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
    
    subgraph "Task Platforms"
        LN[📋 Linear]
    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
    LN --> B
    
    B --> A[🧠 Agent]
    
    classDef platform fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef comm fill:#2E8B57,stroke:#7C90A0,color:#fff
    classDef task fill:#189AB4,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 LN task
    class B bot
    class A agent
```

## Quick Start

<Tabs>
  <Tab title="CLI (No Code)">
    Start a bot with a single command - no Python code required:

    <Steps>
      <Step title="Set Environment Variables">
        ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
        # 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"

        # Linear (OAuth token or API key)
        export LINEAR_OAUTH_TOKEN="your-linear-oauth-token"
        export LINEAR_WEBHOOK_SECRET="your-webhook-secret"
        ```
      </Step>

      <Step title="Start the Bot">
        ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
        # 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

        # Linear (AgentSession webhooks)
        praisonai bot linear --token $LINEAR_OAUTH_TOKEN --signing-secret $LINEAR_WEBHOOK_SECRET

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

      <Step title="(Optional) Custom Agent">
        ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
        # Use a custom agent configuration
        praisonai bot slack --token $SLACK_BOT_TOKEN --app-token $SLACK_APP_TOKEN --agent agents.yaml
        ```

        **agents.yaml:**

        ```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
        name: support-bot
        instructions: |
          You are a customer support assistant.
          Be helpful and concise.
        llm: gpt-4o-mini
        tools:
          - search_web
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="Python SDK">
    Full programmatic control with Python:

    <Steps>
      <Step title="Create Agent">
        ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
        from praisonaiagents import Agent

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

      <Step title="Configure Bot">
        ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
        from praisonaiagents import BotConfig

        config = BotConfig(
            token="your-bot-token",
            command_prefix="/",
            typing_indicator=True,
            reply_in_thread=False,  # Inline replies
        )
        ```
      </Step>

      <Step title="Start Bot">
        ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
        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="Linear Bot Example">
        ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
        from praisonai.bots import LinearBot

        bot = LinearBot(
            token="your-linear-oauth-token",
            signing_secret="your-webhook-secret",
            agent=agent,
            webhook_port=8080
        )
        asyncio.run(bot.start())
        ```
      </Step>

      <Step title="Email Bot Example">
        ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
        from praisonai.bots import EmailBot

        bot = EmailBot(
            address="bot@gmail.com",
            password="xxxx xxxx xxxx xxxx",
            agent=agent
        )
        asyncio.run(bot.start())
        ```
      </Step>
    </Steps>
  </Tab>
</Tabs>

***

## 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`                 |    ✅   |
| `LinearBot`    | Linear (AgentSession webhooks) | `LINEAR_OAUTH_TOKEN` (or `LINEAR_API_KEY`), `LINEAR_WEBHOOK_SECRET` |    ✅   |
| `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 |

<Tip>
  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`
</Tip>

***

## How It Works

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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
```

| 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.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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
```

### 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                           |

<Note>
  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.
</Note>

***

## Smart Defaults

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

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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
```

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 |

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

<Info>
  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.
</Info>

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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()
```

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Same result — no YAML tool list needed
praisonai bot telegram --token $TELEGRAM_BOT_TOKEN
```

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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...
```

***

## Socket Mode vs Webhook

PraisonAI bots support two connection modes:

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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
```

| Mode             | Use Case                           | Requirements          |
| ---------------- | ---------------------------------- | --------------------- |
| **Socket Mode**  | Local development, behind firewall | App Token only        |
| **Webhook Mode** | Production, high scale             | Public URL with HTTPS |

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

***

## Configuration Options

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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)
    unknown_user_policy="pair",     # "deny" (default) | "pair" | "allow"
    owner_user_id="123456789",      # Platform-specific owner ID (Telegram numeric, Discord snowflake, Slack U-id)
)
```

| 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). |
| `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)                                                                                                                                                                     |

<Note>
  **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
</Note>

<Note>
  **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`
</Note>

<Note>
  For the full owner-approval workflow (inline buttons on Telegram / Discord / Slack, HMAC signing, CLI fallback), see [Bot Unknown-User Pairing](/docs/features/bot-unknown-user-pairing).
</Note>

***

## CLI Capabilities

Enable powerful agent features directly from the command line:

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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
```

<CardGroup cols={2}>
  <Card title="Memory" icon="brain">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    praisonai bot slack --memory
    ```

    Bot remembers previous conversations
  </Card>

  <Card title="Knowledge/RAG" icon="book">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    praisonai bot slack --knowledge \
      --knowledge-sources docs.pdf manual.txt
    ```

    Answer from your documents
  </Card>

  <Card title="Skills" icon="wand-magic">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    praisonai bot slack --skills researcher writer
    ```

    Load named skill modules
  </Card>

  <Card title="Extended Thinking" icon="lightbulb">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    praisonai bot slack --thinking high
    ```

    Enable reflection mode (off/minimal/low/medium/high)
  </Card>
</CardGroup>

<Accordion title="Full CLI Options Reference">
  | 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`               |
</Accordion>

***

## Platform Setup

<Tabs>
  <Tab title="Telegram">
    1. Message [@BotFather](https://t.me/BotFather) on Telegram
    2. Send `/newbot` and follow prompts
    3. Copy the bot token

    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    export TELEGRAM_BOT_TOKEN="123456:ABC-DEF..."
    praisonai bot telegram --token $TELEGRAM_BOT_TOKEN
    ```
  </Tab>

  <Tab title="Discord">
    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

    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    export DISCORD_BOT_TOKEN="MTIz..."
    praisonai bot discord --token $DISCORD_BOT_TOKEN
    ```
  </Tab>

  <Tab title="Slack">
    <Steps>
      <Step title="Create Slack App">
        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
      </Step>

      <Step title="Configure OAuth & Permissions">
        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 |

        4. Click **Install to Workspace** at the top
        5. Copy the **Bot User OAuth Token** (`xoxb-...`)
      </Step>

      <Step title="Enable Socket Mode">
        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-...`)
      </Step>

      <Step title="Subscribe to Events">
        <Warning>
          **This step is critical!** Without event subscriptions, the bot won't receive messages.
        </Warning>

        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     |

        5. Click **Save Changes**
        6. **Reinstall the app** when prompted (or go to OAuth & Permissions → Reinstall)
      </Step>

      <Step title="Enable Messages Tab">
        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**
      </Step>

      <Step title="Start the Bot">
        ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
        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 theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
          ngrok http 8080
          ```

          Then use the ngrok URL as your callback URL.
        </Note>
      </Step>

      <Step title="Start the Bot">
        ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
        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 theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    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
    ```

    <Steps>
      <Step title="Install Dependencies">
        ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
        pip install 'praisonai[bot-whatsapp-web]'
        ```

        This installs `neonize` (WhatsApp Web client with built-in QR display).
      </Step>

      <Step title="Start the Bot">
        ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
        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.
      </Step>

      <Step title="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.
      </Step>
    </Steps>

    <Tabs>
      <Tab title="CLI">
        ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
        # 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 theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
        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
        ```
      </Tab>

      <Tab title="YAML">
        ```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
        # 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 theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
        praisonai bot start --config whatsapp-web-bot.yaml
        ```
      </Tab>
    </Tabs>

    ### 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     |

    <AccordionGroup>
      <Accordion title="Troubleshooting: QR code not showing">
        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 theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
        rm -rf ~/.praisonai/whatsapp/
        ```

        4. **QR times out?** → WhatsApp QR codes expire after \~60 seconds. Restart the bot to get a fresh one.
      </Accordion>

      <Accordion title="Troubleshooting: Session expired">
        WhatsApp Web sessions expire if your phone is offline for **14+ days**. Delete the saved session and scan again:

        ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
        rm -rf ~/.praisonai/whatsapp/
        praisonai bot whatsapp --mode web
        ```
      </Accordion>

      <Accordion title="Where are credentials stored?">
        By default: `~/.praisonai/whatsapp/praisonai_whatsapp.db` (SQLite).

        Override with `--creds-dir` or `WHATSAPP_CREDS_DIR` environment variable.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

***

## 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:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
bot.register_command("ping", my_handler, description="Check latency")
```

<Tip>
  See [Bot Chat Commands](/features/bot-commands) for full details on custom command registration and platform-specific behavior.
</Tip>

***

## Common Patterns

<Tabs>
  <Tab title="Restricted Access">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import BotConfig

    config = BotConfig(
        token="your-token",
        allowed_users=["user123", "user456"],
        allowed_channels=["channel789"]
    )
    ```
  </Tab>

  <Tab title="Webhook Mode">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import BotConfig

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

  <Tab title="Group Settings">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    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 theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# 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
```

<Note>
  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.
</Note>

***

## 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.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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
```

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

### CLI Flags

<Tabs>
  <Tab title="Self-Only (Default)">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # Only responds when YOU message yourself
    praisonai bot whatsapp --mode web
    ```
  </Tab>

  <Tab title="Allowed Numbers">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # Also respond to specific phone numbers
    praisonai bot whatsapp --mode web --respond-to 1234567890,9876543210
    ```
  </Tab>

  <Tab title="Allowed Groups">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # Also respond in specific groups
    praisonai bot whatsapp --mode web --respond-to-groups 120363123456@g.us
    ```
  </Tab>

  <Tab title="Combined">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # Specific numbers AND groups
    praisonai bot whatsapp --mode web \
      --respond-to 1234567890 \
      --respond-to-groups 120363123456@g.us
    ```
  </Tab>

  <Tab title="Respond to All">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # Respond to every message (old behavior)
    praisonai bot whatsapp --mode web --respond-to-all
    ```
  </Tab>
</Tabs>

### Python SDK

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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

```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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"
```

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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](mailto:g@g.us)       |    ❌    |          ❌         |               ✅              |          ✅         |
| Other group                         |    ❌    |          ❌         |               ❌              |          ✅         |
| Old/offline messages                |    ❌    |          ❌         |               ❌              |          ❌         |

<Note>
  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.
</Note>

***

## Docker Deployment

Deploy bots using Docker for production environments:

<Tabs>
  <Tab title="Slack">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # 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 theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # 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
    ```
  </Tab>

  <Tab title="Telegram">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # 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 theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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
```

<Tip>
  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.
</Tip>

***

## Production (Webhook Mode)

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

<Tabs>
  <Tab title="Slack">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    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 theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    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`
  </Tab>

  <Tab title="Telegram">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    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 theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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"
```

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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
```

<Tip>
  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.
</Tip>

***

## Zero-Code Mode (YAML Config)

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

**bot.yaml:**

```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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]
```

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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.

<Tip>
  The `.env` file in the current directory is auto-loaded, so you can store tokens there and reference them with `${VAR_NAME}` syntax.
</Tip>

***

## 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](https://t.me/BotFather). Used for all bot operations. |

### Discord

| Token         | Format    | When to Use                                                                                                                                             |
| ------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Bot Token** | `MTIz...` | **Always required.** Get from [Discord Developer Portal](https://discord.com/developers/applications) → 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.                             |

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

### WhatsApp

<Tabs>
  <Tab title="Cloud API (default)">
    | 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.                 |
  </Tab>

  <Tab title="Web Mode (experimental)">
    | 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`.

    <Warning>
      Web mode uses a reverse-engineered protocol. Your number may be banned by Meta. Use Cloud API for production.
    </Warning>
  </Tab>
</Tabs>

***

## Best Practices

<AccordionGroup>
  <Accordion title="Secure your bot token">
    Never commit bot tokens to version control. Use environment variables or secure secret management.
  </Accordion>

  <Accordion title="Use allowlists in production">
    Set `allowed_users` and `allowed_channels` to prevent unauthorized access to your bot.
  </Accordion>

  <Accordion title="Enable mention requirement for groups">
    Set `mention_required=True` to prevent the bot from responding to every message in group chats.
  </Accordion>

  <Accordion title="Handle rate limits gracefully">
    Configure `retry_attempts` and implement exponential backoff for API rate limits.
  </Accordion>

  <Accordion title="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](/features/approval-protocol).
  </Accordion>

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

## Multi-Agent Configuration

You can also define multiple agents in an `agents.yaml` file for complex workflows:

**agents.yaml:**

```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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...
```

<Tabs>
  <Tab title="Python">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    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 theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    agent:
      name: assistant
      instructions: Be helpful

    platforms:
      telegram:
        token: ${TELEGRAM_BOT_TOKEN}
        debounce_ms: 1500
    ```
  </Tab>
</Tabs>

<Tip>
  Set `debounce_ms: 0` (default) to disable debouncing for real-time response bots.
  Recommended: **1000–2000ms** for conversational bots.
</Tip>

***

## Smart Message Chunking

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

````mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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
````

<AccordionGroup>
  <Accordion title="How splitting works">
    <Steps>
      <Step title="Paragraph boundaries">
        Split at blank lines (`\n\n`) first — keeps ideas together.
      </Step>

      <Step title="Sentence boundaries">
        If a paragraph is still too long, split at sentence endings (`. `).
      </Step>

      <Step title="Hard split">
        Last resort: character-level split for very long single lines.
      </Step>
    </Steps>
  </Accordion>

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

<Info>
  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).
</Info>

***

## Session History

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

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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
```

<Tabs>
  <Tab title="Automatic (default)">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    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 theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    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()
    ```
  </Tab>
</Tabs>

<Warning>
  Setting `memory=True` (full memory with ChromaDB) requires `pip install praisonaiagents[memory]`.
  The default `history=True` injection uses **zero extra dependencies**.
</Warning>

***

## 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.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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 ✅
```

<Tabs>
  <Tab title="Python">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    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 theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    agent:
      name: assistant
      instructions: Be helpful

    platforms:
      telegram:
        token: ${TELEGRAM_BOT_TOKEN}
        ack_emoji: "⏳"
        done_emoji: "✅"
    ```
  </Tab>
</Tabs>

<Tip>
  Set `ack_emoji: ""` (default) to disable ack reactions.
  Currently wired for Telegram (which supports native message reactions).
</Tip>

***

## Session Reaper

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

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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()
```

<Info>
  Set `session_ttl: 0` (default) to disable automatic reaping.
  You can also call `bot._session.reap_stale(max_age_seconds)` manually.
</Info>

***

## YAML Configuration

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

<Tabs>
  <Tab title="Full YAML">
    ```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    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 theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonai.bots import BotOS

    botos = BotOS.from_config("bot.yaml")
    botos.run()  # Starts all platforms concurrently
    ```
  </Tab>
</Tabs>

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

  <Accordion title="Environment variable syntax">
    Use `${ENV_VAR}` in YAML values — resolved at load time.

    ```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    platforms:
      telegram:
        token: ${TELEGRAM_BOT_TOKEN}
    ```
  </Accordion>
</AccordionGroup>

***

## Tool Approval via Messaging

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

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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()
```

<Info>
  See [Approval Protocol](/features/approval-protocol#slack-approval) for full configuration options.
</Info>

***

## Related

<CardGroup cols={2}>
  <Card title="Approval Protocol" icon="shield-check" href="/features/approval-protocol">
    Tool execution approval system
  </Card>

  <Card title="Gateway" icon="tower-broadcast" href="/features/gateway">
    Multi-agent coordination
  </Card>

  <Card title="Webhooks" icon="webhook" href="/features/webhooks">
    Event-driven integrations
  </Card>
</CardGroup>
