Skip to main content
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.
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. Five registration paths reach the same adapter class: three that need Python (built-ins, entry point, register_platform()) and two zero-code paths (YAML adapter: ref and .praisonai/channels/ drop-in files). See Custom Gateway Channel (Zero-Code) for the full zero-code story.

Quick Start

1

Programmatic Registration

Register a bot platform directly in your code:
2

Entry-point Plugin

Create a pip-installable plugin using pyproject.toml:
After installation, use the bot platform:

Zero-Code Paths

Two paths register a channel with no packaging and no bootstrap Python — both self-register the adapter before startup. YAML adapter: import ref. Point a channel at a dotted "module:Class" string; the gateway imports, validates, and registers it.
Filesystem drop-in. Any BasePlatformAdapter subclass in ./.praisonai/channels/*.py (project, gated by PRAISONAI_ALLOW_PROJECT_PLUGINS=true) or ~/.praisonai/channels/*.py (user-global, trusted) registers under its platform_name.
See Custom Gateway Channel (Zero-Code) for the trust model, error surface, and copy-paste recipes.

How It Works

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

Configuration

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

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
  • webhook - Generic HTTP webhook trigger (declarative routes) — see Webhook Channel

Entry-point Groups

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)

Plugin channels on praisonai gateway start (from PR #3579, merged 2026-08-01): the gateway’s _create_bot path now delegates to the same resolve_adapter() seam that Bot() and probe_channels use, so channels registered via register_platform() or a praisonai.channels entry point are launched by the gateway exactly like a built-in. Older gateway builds hardcoded seven built-in platforms and silently skipped everything else with a single WARNING — plugin channels never actually started under the gateway even though Bot() could construct them. Update to the post-#3579 wrapper if you rely on plugin channels in gateway.yaml.
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:
After pip install praisonai-irc:
List all registered platforms — built-in, entry-point, and custom — with the CLI:
Or in Python:
list_platforms() also returns anything registered by register_platform() in the current process. The entry-point group is loaded lazily on first registry access, so a plugin that is installed but never imported still appears after the first resolve_adapter() call.
praisonai.channels is preferred over praisonai.bots for new packages. Both entry-point groups continue to work.

Plugin channel on the gateway runtime

Register a plugin platform, then reference it in gateway.yaml:
The gateway walks the same path a built-in channel does: When resolution fails, the gateway calls self._mark_degraded_owner("channel", "mattermost", reason="unresolved_platform") instead of raising — the channel is skipped but stays visible in health / doctor.

How the gateway constructs a plugin channel

The gateway builds every channel adapter through one resolution seam and a three-step kwarg assembly. Adapter resolution. resolve_adapter(channel_type) is the single lookup, resolved in ladder order: a registered platform (built-in / entry point / register_platform) wins, then a YAML adapter: import ref, then a .praisonai/channels/ drop-in file. Only when none resolve does the gateway mark the channel unresolved_platform. Kwarg assembly. The gateway layers three sources in order; later sources override earlier ones: The gateway then calls adapter_cls(**init_kwargs). ch_cfg wins over env backfill, and platform / token are stripped so they never double up. This mirrors probe_channels and Bot._build_adapter. Token env-var fallback. When the token from channels: YAML is falsy, the gateway consults _TOKEN_FALLBACK_ENV — the first non-empty value wins: Other platforms have no token fallback here — Slack’s app-token env still comes from step 2 (_EXTRA_ENV_MAP), not this map. Where a plugin author sets each value:

Degraded channels: what happens when a plugin fails

A channel that cannot resolve or construct is recorded as degraded, not silently dropped. Two exact reason strings surface via _mark_degraded_owner("channel", <channel_type>, reason=...): Both paths return None from _create_bot, so the two call sites (start_channels and hot-reload) keep their existing None contract. The failure is queryable via the degraded-owner surface (health / doctor) — see Gateway Degraded Channels — instead of vanishing into logs.

Common Patterns

Declare Platform Capabilities

Capabilities let PraisonAI’s shared delivery layer chunk, stream, and rate-limit messages correctly for your platform — see Bot Platform Capabilities for the full field list.

Register a Native Presentation Renderer

Channel plugins that ship a PresentationRenderer should call register_presentation_renderer(platform, MyRenderer) from praisonaiagents.bots at setup time, so interactive UI (buttons, selects, approvals) renders natively instead of degrading to plain text.
This is the same extension point built-in channels use. See Presentation Renderers for the renderer contract and validation rules.

Use the Canonical Admission Primitive

Reuse resolve_ingress_admission() in your adapter’s message handler so your custom channel inherits the same allowlist / blocklist / group-policy semantics as every built-in — and drops become inspectable (reason_code) instead of silent logger.debug lines.
The ladder (first matching gate wins): block-list → allow-list → pairing → direct-chat bypass → group policy. An unset group_policy defaults to mention_only — the live BotConfig default — so a forwarded unset policy fails safe rather than replying to everything in a group. Reason codes an operator can grep for: allowed, blocked, not_in_allowlist, pairing_required, group_mention_only, command_only, observe. IngressDecision fields:
The primitive is pure and dependency-free — same inputs, same verdict. That means built-in and plugin channels cannot drift, and adopting it does not couple your adapter to any transport, config-loading, or session module.

Override a Built-in Platform

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

Lazy Heavy Imports

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

Multi-tenant Isolation

Construct your own BotPlatformRegistry to avoid leaking between tenants:

Best Practices

Never import heavy networking SDKs at module top level:
Follow the expected bot lifecycle pattern:
Use logging instead of raising on initialization:

Delivery lifecycle

Bot plugin authors are the primary consumers of the enriched message identity — platform and channel_id on inbound messages, plus successful and failed delivery signals on outbound. Override message_sent and message_undelivered in a Plugin subclass to add delivery telemetry or dead-letter escalation without patching adapters.
See Plugins → Message-Lifecycle Plugins for the enriched payload keys and runnable per-user, per-channel, and dead-letter examples.

Custom Gateway Channel (Zero-Code)

Add a channel from YAML adapter: or a .praisonai/channels/ drop-in file

Message-Lifecycle Plugins

React to inbound, outbound, delivered, and undelivered messages

Bot Platform Capabilities

Declare streaming, chunking, and rate-limit behaviour

Bot Gateway

See how group_policy, allowed_users, and pairing are configured in YAML

Gateway Degraded Channels

See where unresolved_platform and adapter_construction_failed surface in health/doctor

Presentation Renderers

Register a native renderer so buttons, selects, and approvals render natively

Framework Adapter Plugins

Learn about extending PraisonAI with custom execution frameworks

Messaging Channels Strategy

See our roadmap for supported messaging platforms