# How OpenHuman Handles Channel Integrations for Messaging Providers and Native Email

> Discover how OpenHuman unifies messaging channels like email, Telegram, Discord, and WhatsApp using a trait system and JSON-RPC controllers for seamless communication.

- Repository: [Tiny Humans/openhuman](https://github.com/tinyhumansai/openhuman)
- Tags: how-to-guide
- Published: 2026-09-01

---

**OpenHuman unifies messaging providers—including native email, Telegram, Discord, and WhatsApp—behind a feature-gated trait system that routes all communication through a runtime dispatch engine and JSON-RPC controllers.**

The `tinyhumansai/openhuman` repository implements a modular channel integration layer located in `src/openhuman/channels/`. This architecture abstracts diverse messaging services into a unified interface where native email and third-party providers share identical APIs and security policies.

## Feature-Gated Architecture and Core Traits

### Compile-Time Feature Gates

The entire channel domain is wrapped by `#[cfg(feature = "channels")]` at the top of [`src/openhuman/channels/mod.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/channels/mod.rs). This makes the functionality optional at compile time, reducing binary size when messaging capabilities are not required. Two carve-outs—`traits` and `cli`—remain available even when the gate is disabled, allowing the interactive agent harness to reference channel contracts without pulling in provider-specific dependencies.

### The Channel Trait Contract

[`src/openhuman/channels/traits.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/channels/traits.rs) re-exports the fundamental abstractions from the `tinychannels` contract crate:

```rust
pub use tinychannels::Channel;
pub use tinychannels::SendMessage;

```

Every provider implements these traits, guaranteeing that methods like `send_message` accept identical payload structures regardless of whether the underlying transport is SMTP, Discord webhooks, or Telegram bots.

## Provider Implementations and Native Email

### Modular Provider Structure

Each messaging service occupies a dedicated file under `src/openhuman/channels/providers/`:

- **Native Email**: [`src/openhuman/channels/providers/email_channel.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/channels/providers/email_channel.rs)
- **Discord**: [`src/openhuman/channels/providers/discord.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/channels/providers/discord.rs)
- **Telegram**: [`src/openhuman/channels/providers/telegram/mod.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/channels/providers/telegram/mod.rs)
- **WhatsApp**: [`src/openhuman/channels/providers/whatsapp.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/channels/providers/whatsapp.rs)

Providers encapsulate authentication logic, connection management, and protocol translation within their respective modules.

### How Native Email Works

The native email channel is treated exactly like any third-party provider. In [`src/openhuman/channels/providers/email_channel.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/channels/providers/email_channel.rs), the implementation:

- Accepts `EmailChannelConfig` (SMTP host, port, username, password) via the `connect` RPC method
- Implements `SendMessage` by constructing MIME payloads and transmitting via the `lettre` Rust email library
- Operates as an output-only sink, meaning it sends messages but does not support inbound email processing

Because the email provider lives in the same `providers/` namespace, it automatically utilizes the dispatch, bus, and RPC plumbing without special-case code.

## Runtime Dispatch and RPC Interface

### The Dispatch Engine

The runtime dispatch processor at [`src/openhuman/channels/runtime/dispatch/processor.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/channels/runtime/dispatch/processor.rs) routes incoming RPC calls to the correct provider instance based on the `ChannelId`. Before executing any tool call, the processor enforces **approval-gate** and **sandbox** policies to ensure agent actions comply with security constraints.

### JSON-RPC Controllers

[`src/openhuman/channels/controllers/ops.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/channels/controllers/ops.rs) exposes the external API surface with three primary operations:

- `list_channels`: Enumerate all configured channels and their connection status
- `connect`: Create or update provider configuration, such as registering SMTP credentials for the native email channel
- `send_message`: Dispatch a message payload through a selected channel by ID

These controllers register in [`src/core/all.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/core/all.rs) under the Channels domain group, making them accessible via the core JSON-RPC endpoint.

## Event Bus and Host Integration

### Internal Communication Layer

[`src/openhuman/channels/bus.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/channels/bus.rs) defines the internal event bus used for inbound messages, status updates, and provider health pings. The host implementation in [`src/openhuman/channels/host/host.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/channels/host/host.rs) serves as glue between the core agent process and the channel runtime, forwarding inbound events from providers and managing bidirectional data flow.

### Proactive Messaging and Debugging

[`src/openhuman/channels/proactive.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/channels/proactive.rs) implements server-side event handling for providers supporting push notifications, such as the Discord gateway. For operational maintenance, [`src/openhuman/channels/commands.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/channels/commands.rs) supplies CLI utilities like `doctor_channels`, which health-checks the subsystem without requiring external API authentication.

## Example: Configuring and Sending Native Email

The following pattern demonstrates how to connect the native email channel and send a message using the shared trait interface:

```rust
use openhuman::channels::{EmailChannel, Channel, SendMessage};
use openhuman::core::rpc::CoreRpcClient;

// 1. Configure the email channel via RPC
let rpc = CoreRpcClient::new("http://127.0.0.1:12345/rpc")?;
rpc.call("channels_connect", json!({
    "type": "email",
    "config": {
        "smtp_host": "smtp.example.com",
        "smtp_port": 587,
        "username": "user@example.com",
        "password": "********"
    }
}))?;

// 2. Instantiate and send
let email = EmailChannel::new("email-channel-id".into());
email.send_message(json!({
    "to": ["recipient@example.com"],
    "subject": "Hello from OpenHuman",
    "body": "This is a test email sent via the native channel."
}))?;

```

This same pattern applies to any provider implementing the `Channel` trait, whether sending Discord DMs or Telegram messages.

## Summary

- OpenHuman uses a **feature-gated** architecture (`channels` feature in [`Cargo.toml`](https://github.com/tinyhumansai/openhuman/blob/main/Cargo.toml)) to optionally compile provider code while keeping trait definitions always available
- All providers implement the **`Channel`** and **`SendMessage`** traits from `tinychannels`, ensuring API uniformity across native email, Discord, Telegram, and WhatsApp
- The **native email** provider in [`email_channel.rs`](https://github.com/tinyhumansai/openhuman/blob/main/email_channel.rs) uses the `lettre` library for SMTP transport and shares the same dispatch pipeline as external APIs
- **Runtime dispatch** in [`processor.rs`](https://github.com/tinyhumansai/openhuman/blob/main/processor.rs) routes RPC calls by `ChannelId` and enforces approval-gate security policies before execution
- **Event bus** ([`bus.rs`](https://github.com/tinyhumansai/openhuman/blob/main/bus.rs)) and **host glue** ([`host/host.rs`](https://github.com/tinyhumansai/openhuman/blob/main/host/host.rs)) coordinate bidirectional communication between the core agent runtime and channel implementations
- **JSON-RPC controllers** in [`ops.rs`](https://github.com/tinyhumansai/openhuman/blob/main/ops.rs) provide the external interface for listing, connecting, and sending messages through any configured channel

## Frequently Asked Questions

### What messaging providers does OpenHuman support?

OpenHuman supports Telegram, Discord, WhatsApp, Slack, Signal, and a built-in native email transport. Each provider resides as a separate Rust module under `src/openhuman/channels/providers/` and implements the shared `Channel` trait from `tinychannels`.

### How does OpenHuman handle authentication for different channel integrations?

Authentication logic is encapsulated within each provider module. For native email, the `connect` RPC method accepts `EmailChannelConfig` containing SMTP credentials, while Discord uses OAuth flows and Telegram uses bot tokens. All authentication schemes are abstracted behind the uniform RPC interface defined in [`src/openhuman/channels/controllers/ops.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/channels/controllers/ops.rs).

### Can OpenHuman receive incoming emails through the native channel?

No, the native email implementation in [`src/openhuman/channels/providers/email_channel.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/channels/providers/email_channel.rs) is currently output-only. It supports sending messages via SMTP but does not implement inbound message handlers or webhook listeners, unlike bidirectional providers such as Discord or Telegram which support full conversation threads.

### How do I verify that the channel subsystem is functioning correctly?

Execute the `doctor_channels` command defined in [`src/openhuman/channels/commands.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/channels/commands.rs). This utility performs health checks on the runtime dispatch processor, event bus connectivity, and provider configurations without requiring valid external API credentials or sending actual messages.