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

# Bot Platform Plugins

> Add custom messaging-platform bots to PraisonAI via Python entry points

<Note>
  Bot platform adapters now ship in the `praisonai-bot` package. `praisonai bot serve` still works exactly as documented here; for a standalone install see [praisonai-bot Migration](/docs/guides/praisonai-bot-migration).
</Note>

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent

agent = Agent(name="platform-bot", instructions="Use platform-specific bot plugins.")
agent.start("Enable Telegram and Discord plugins for this bot.")
```

Third-party bot packages can register via Python entry points to extend PraisonAI with custom messaging platforms.

The user installs a third-party bot package; entry points register new platforms alongside built-in channels.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    A[📦 Third-party Bot Package] --> B[🔌 Entry Point<br/>praisonai.bots]
    B --> C[📝 BotPlatformRegistry]
    C --> D[💬 Bot - mattermost - agent=...]

    classDef agent fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef tool fill:#189AB4,stroke:#7C90A0,color:#fff

    class D agent
    class A,B,C tool
```

## Quick Start

<Steps>
  <Step title="Programmatic Registration">
    Register a bot platform directly in your code:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonai.bots._registry import register_platform

    class MyBot:
        def __init__(self, **kwargs):
            self.kwargs = kwargs
        
        async def start(self):
            print("Starting MyBot...")
        
        async def stop(self):
            print("Stopping MyBot...")

    register_platform("mybot", MyBot)
    ```
  </Step>

  <Step title="Entry-point Plugin">
    Create a pip-installable plugin using `pyproject.toml`:

    ```toml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # pyproject.toml
    [project.entry-points."praisonai.channels"]
    mybot = "my_pkg.bot:MyBot"
    ```

    After installation, use the bot platform:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonai.bots import Bot

    bot = Bot("mybot", agent=my_agent)
    await bot.start()
    ```
  </Step>
</Steps>

***

## How It Works

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant User
    participant Bot
    participant Registry
    participant Plugin
    
    User->>Bot: Bot("mybot", agent=...)
    Bot->>Registry: resolve_adapter("mybot")
    Registry->>Plugin: lazy load via entry point
    Plugin-->>Registry: MyBot class
    Registry-->>Bot: MyBot
    Bot-->>User: bot instance
```

The bot platform registry provides a central point for managing bot implementations:

| Operation    | Description                                 | When Called         |
| ------------ | ------------------------------------------- | ------------------- |
| Discovery    | Entry points auto-loaded on registry access | Import time         |
| Registration | Bot platforms registered by name            | Plugin installation |
| Creation     | Bot instances created on demand             | `Bot()` constructor |
| Availability | Platform dependencies checked               | Before execution    |

***

## Configuration

The bot platform registry supports both programmatic and entry-point registration:

| Function                                          | Purpose                                                          |
| ------------------------------------------------- | ---------------------------------------------------------------- |
| `register_platform(name, cls, capabilities=None)` | Register at runtime (optional `PlatformCapabilities` descriptor) |
| `get_platform_capabilities(name)`                 | Get the capabilities descriptor for a registered platform        |
| `list_platforms()`                                | List all registered platform names                               |
| `resolve_adapter(name)`                           | Get class for a platform name                                    |
| `get_platform_registry()`                         | Backward-compat: returns `dict[name, class]` of all platforms    |
| `get_default_bot_registry()`                      | Get the process-default `BotPlatformRegistry` (advanced)         |

### Built-in Platforms

PraisonAI includes these built-in bot platforms:

* `telegram` - Telegram bot integration
* `discord` - Discord bot integration
* `slack` - Slack bot integration
* `whatsapp` - WhatsApp bot integration
* `linear` - Linear issues integration
* `email` - Email bot integration
* `agentmail` - AgentMail integration

### Entry-point Groups

| Group                | Purpose                                                                                |
| -------------------- | -------------------------------------------------------------------------------------- |
| `praisonai.channels` | **Recommended** for new packaged connectors — idiomatic, zero-config auto-registration |
| `praisonai.bots`     | Legacy group — still scanned for backward compatibility                                |

Both groups are scanned by `BotPlatformRegistry` on startup. A connector that would shadow a built-in platform is skipped with a warning.

### Discovery via entry points (`praisonai.channels`)

The `praisonai.channels` entry-point group is the idiomatic way to distribute a bot connector as a pip-installable package. Once installed, the platform is available with no extra Python code:

```toml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# pyproject.toml of your connector package
[project.entry-points."praisonai.channels"]
irc = "praisonai_irc:IRCBot"
```

After `pip install praisonai-irc`:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.bots import Bot

bot = Bot("irc", agent=my_agent, server="irc.libera.chat")
await bot.start()
```

List all registered platforms — built-in, entry-point, and custom — with the CLI:

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
praisonai gateway channels --available
# => telegram, discord, slack, whatsapp, linear, email, agentmail, irc
```

Or in Python:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.bots._registry import list_platforms

print(sorted(list_platforms()))
```

<Note>
  `praisonai.channels` is preferred over `praisonai.bots` for new packages. Both entry-point groups continue to work.
</Note>

***

## Common Patterns

### Declare Platform Capabilities

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.bots import PlatformCapabilities
from praisonai.bots._registry import register_platform

register_platform(
    "mybot",
    MyBot,
    capabilities=PlatformCapabilities(
        max_message_length=2000,
        length_unit="codepoints",
        supports_edit=True,
        markdown_dialect="markdown",
    ),
)
```

Capabilities let PraisonAI's shared delivery layer chunk, stream, and rate-limit messages correctly for your platform — see [Bot Platform Capabilities](/docs/features/bot-platform-capabilities) for the full field list.

### Override a Built-in Platform

Registry uses last-write-wins with lower-cased keys:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.bots._registry import register_platform

class CustomSlackBot:
    def __init__(self, **kwargs):
        self.token = kwargs.get('token')
    
    async def start(self):
        # Custom Slack implementation
        pass
    
    async def stop(self):
        pass

# Override built-in Slack bot
register_platform("slack", CustomSlackBot)
```

### Lazy Heavy Imports

Follow the pattern used by built-ins to avoid import-time failures:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
class HeavyFrameworkBot:
    def __init__(self, **kwargs):
        self.config = kwargs
        self._client = None
    
    async def start(self):
        # Only import when actually starting
        import heavy_networking_sdk
        self._client = heavy_networking_sdk.Client(
            token=self.config.get('token')
        )
        await self._client.connect()
    
    async def stop(self):
        if self._client:
            await self._client.disconnect()
```

### Multi-tenant Isolation

Construct your own `BotPlatformRegistry` to avoid leaking between tenants:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.bots._registry import BotPlatformRegistry

# Each tenant gets their own registry
tenant_registry = BotPlatformRegistry()
tenant_registry.register("custom-slack", TenantSpecificSlackBot)
```

***

## Best Practices

<AccordionGroup>
  <Accordion title="Use Lazy Imports">
    Never import heavy networking SDKs at module top level:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # ❌ Bad - imports at module level
    import heavy_sdk

    class BadBot:
        def __init__(self, **kwargs):
            self.client = heavy_sdk.Client()

    # ✅ Good - lazy imports
    class GoodBot:
        async def start(self):
            import heavy_sdk
            self.client = heavy_sdk.Client()
    ```
  </Accordion>

  <Accordion title="Implement Proper Protocol">
    Follow the expected bot lifecycle pattern:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    class ProperBot:
        def __init__(self, **kwargs):
            # Store config, don't establish connections yet
            self.config = kwargs
            self.running = False
        
        async def start(self):
            # Establish connections, start listening
            self.running = True
        
        async def stop(self):
            # Clean shutdown
            self.running = False
    ```
  </Accordion>

  <Accordion title="Handle Errors Gracefully">
    Use logging instead of raising on initialization:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    import logging
    logger = logging.getLogger(__name__)

    class RobustBot:
        def __init__(self, **kwargs):
            self.config = kwargs
            
        async def start(self):
            try:
                # Connection logic here
                pass
            except Exception as e:
                logger.error(f"Failed to start bot: {e}")
                # Don't re-raise, let caller handle
    ```
  </Accordion>
</AccordionGroup>

***

## Related

<CardGroup cols={2}>
  <Card title="Bot Platform Capabilities" icon="sliders" href="/docs/features/bot-platform-capabilities">
    Declare streaming, chunking, and rate-limit behaviour
  </Card>

  <Card title="Framework Adapter Plugins" icon="puzzle-piece" href="/docs/features/framework-adapter-plugins">
    Learn about extending PraisonAI with custom execution frameworks
  </Card>

  <Card title="Messaging Channels Strategy" icon="message-circle" href="/docs/features/messaging-channels-strategy">
    See our roadmap for supported messaging platforms
  </Card>
</CardGroup>
