Channels
Compare the included Slack, Telegram, WhatsApp, email, Linq, and Photon adapters and their delivery capabilities.
Channels translate provider-specific messages into one event model. Choose a channel based on the interaction your product needs, not just where the webhook is easiest.
| Adapter | Import | Approvals | Threads | Files | Streaming |
|---|---|---|---|---|---|
| Slack | channels/slack | buttons | yes | yes | edits |
| Telegram | channels/telegram | buttons | yes | yes | edits |
| WhatsApp Cloud API | channels/whatsapp | buttons | no | yes | no |
| AgentMail email | channels/email | text | yes | yes | no |
| Linq iMessage/SMS | channels/linq | text | no | yes | no |
| Photon | channels/photon | text | no | yes | no |
All included webhook adapters verify provider authenticity, bound request bodies, preserve event IDs, normalize actor and conversation identity, and map retryable HTTP failures into Noir errors.
Telegram
import { telegram } from '@noir-agent/agent/channels/telegram'
channels: { telegram: telegram() }Uses TELEGRAM_BOT_TOKEN and TELEGRAM_WEBHOOK_SECRET by default. The default route is /webhooks/telegram.
import { whatsApp } from '@noir-agent/agent/channels/whatsapp'Configure the access token, app secret, verification token, and phone number ID. The adapter handles messages, media, button approvals, reactions, and delivery callbacks.
import { agentMail } from '@noir-agent/agent/channels/email'AgentMail-compatible email preserves threads and attachments. Approval is text-based because email has no trusted interactive button callback in the generic contract.
Linq and Photon
These adapters support conversational iMessage/SMS surfaces, media, delivery events, output sanitization, and opt-out suppression. Keep suppression enabled for production messaging. Photon accepts a user-supplied transport, keeping the provider implementation in application code.
Multiple channels
channels: {
slack: slack(),
telegram: telegram(),
}The normalized identity includes the channel and installation, so the same provider user ID in two channels is not automatically the same person. Add an explicit account-linking layer if memory or authorization should cross channels.