Prerequisites
Install Rust and add the WASM target:1. Create the project structure
Create a new crate underchannels-src/ (or another location) with this layout:
2. Configure Cargo.toml
Cargo.toml
3. Implement the channel interface
Now that the crate is ready, implement the channel guest interface exposed bywit/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.URL Placeholders (Telegram-style)
Header Placeholders (WhatsApp-style)
{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: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:byte index N is not a char boundary, avoid byte slicing and truncate by characters:
- Verify secret names match the declared placeholders.
- Confirm the secret is permitted in
allowed_names. - Check runtime logs for unresolved placeholder warnings.