Skip to main content
Channels are WASM components that handle communication with external messaging platforms (Telegram, WhatsApp, Slack, etc.). They run in a sandboxed environment and communicate with the host via the WIT (WebAssembly Interface Types) interface.

Prerequisites

Install Rust and add the WASM target:
Optional but useful for component conversion workflows:

1. Create the project structure

Create a new crate under channels-src/ (or another location) with this layout:
After building, deploy to:

2. Configure Cargo.toml

Cargo.toml

3. Implement the channel interface

Now that the crate is ready, implement the channel guest interface exposed by wit/channel.wit, and implement the guest trait methods to handle incoming messages and send responses.

Required Imports

Implementing the Guest Trait

on_start configures how the host calls your channel. on_http_request and on_poll ingest external messages; on_respond delivers replies to an existing conversation; on_broadcast sends proactive messages; on_status lets channels surface thinking indicators and other progress updates.

4. Preserve routing metadata (critical)

Once your channel can receive messages, keep enough metadata to send responses back to the right chat and sender. The most important pattern: Store routing info in message metadata so responses can be delivered.
response.metadata_json contains the metadata from the original inbound message. Treat it as the source of truth for reply routing.

5. Add secure credential placeholders

Now that the message path is set, configure API credentials using placeholders instead of hardcoded tokens.
Never hardcode credentials! Use placeholders that the host replaces

URL Placeholders (Telegram-style)

Header Placeholders (WhatsApp-style)

The placeholder format is {SECRET_NAME} where SECRET_NAME matches the credential name in uppercase with underscores (e.g., whatsapp_access_token{WHATSAPP_ACCESS_TOKEN}).

6. Define capabilities

The capabilities file declares setup prompts, allowlists, and rate limits.
my-channel.capabilities.json

7. Build and install

With code and capabilities in place, build the channel and copy the two required artifacts.

Generic channel build

The channels shipped in channels-src/ use small build.sh wrappers that do exactly this component-conversion step. If your channel lives in the repo, following that pattern is the safest option.

Telegram channel example

If you are contributing a channel to the public repository, do not commit compiled WASM binaries. They are a supply chain risk — the binary in a PR may not match the source. IronClaw builds channels from source.

8. Host functions you can call

Channel modules get a small host API for logging, storage, HTTP, and message emission:
Real channels also use a few additional host APIs:
Use store_attachment_data when you download binary payloads such as voice notes or images during webhook or polling callbacks. Use the pairing APIs when your channel supports owner approval for unknown direct-message senders.

9. Common patterns

Polling with stored offsets

Ignore status-only payloads

Ignore bot senders


10. Testing and troubleshooting

Add basic parsing and metadata round-trip tests:
If you see byte index N is not a char boundary, avoid byte slicing and truncate by characters:
If credential placeholders are not resolved:
  1. Verify secret names match the declared placeholders.
  2. Confirm the secret is permitted in allowed_names.
  3. Check runtime logs for unresolved placeholder warnings.