Skip to main content
Channels connect NullClaw to messaging platforms. Each channel implements the Channel interface using vtable-based polymorphism for runtime dispatch.

Supported Channels

NullClaw supports 18+ messaging platforms:
  • CLI — Built-in stdin/stdout interface
  • Telegram — Long-polling bot API
  • Discord — WebSocket gateway
  • Slack — Socket mode + HTTP events
  • WhatsApp — Webhook-based integration
  • Matrix — Long-polling /sync API
  • Mattermost — WebSocket + REST API
  • IRC — TLS socket connection
  • iMessage — AppleScript + SQLite (macOS only)
  • Email — IMAP/SMTP protocols
  • Lark/Feishu — HTTP callback
  • DingTalk — WebSocket stream mode
  • Signal — signal-cli JSON-RPC + SSE
  • Nostr — Decentralized relay protocol
  • LINE — Messaging API
  • OneBot — QQ bot protocol
  • QQ — Native QQ integration
  • MaiXCam — Hardware device messaging
  • Web — HTTP/WebSocket gateway

Channel Interface

All channels implement the Channel vtable interface defined in src/channels/root.zig:

VTable Methods

function
Start the channel (connect, begin listening for messages)
function
Stop the channel (disconnect, clean up resources)
function
Send a message to a target (user, channel, room, etc.)
function
Return the channel name (e.g., “telegram”, “discord”)
function
Health check — return true if the channel is operational
function
default:"optional"
Optional staged outbound event delivery (chunk/final). If null, runtime falls back to send() for .final and ignores .chunk
function
default:"no-op"
Start processing indicator for a recipient (e.g., typing status)
function
default:"no-op"
Stop processing indicator for a recipient

Channel Messages

Channels emit and receive ChannelMessage structs:

Configuration Pattern

Channels are configured using the accounts pattern in config.json:
This allows multiple accounts per channel type, each with independent configuration.

Permission Policies

Channels support fine-grained permission policies:

DM Policy

enum
default:"allow"
Direct message permission policy:
  • allow — Allow all DMs
  • deny — Deny all DMs
  • allowlist — Only allow DMs from senders in the allowlist

Group Policy

enum
default:"open"
Group/channel message permission policy:
  • open — Allow all group messages
  • mention_only — Only respond when explicitly mentioned
  • allowlist — Only allow messages from senders in the allowlist

Allowlist

string[]
default:"[]"
List of allowed sender identifiers. Supports "*" wildcard for allow-all. Case-insensitive matching.

Message Splitting

Channels automatically split long messages at platform limits while respecting UTF-8 character boundaries:
Examples:
  • Telegram: 4096 bytes
  • Discord: 2000 bytes
  • IRC: 512 bytes (minus prefix overhead)

Next Steps

Telegram

Long-polling bot with media support

Discord

WebSocket gateway integration

Slack

Socket mode and HTTP events

Signal

Private messaging via signal-cli

Nostr

Decentralized protocol support

IRC

Classic IRC protocol