Skip to content
Guide Reference Download app

Channels API

@claxedo/channels provides channel ingress, reply rendering, approval prompts, and transport adapters for running Claxedo sessions from chat-shaped systems. createChannelsIngress mounts Hono routes and delegates each enabled provider route to a caller-provided bot or transport.

TransportSignature / secret verificationVerified by
GitHubX-Hub-Signature-256 HMAC over the raw body with the webhook secretCaller — use the verifyGitHubWebhookSignature helper before githubWebhookEnvelope
SlackProvider webhook verification (Chat SDK adapter)The mounted Chat SDK adapter
TelegramCompare incoming X-Telegram-Bot-Api-Secret-Token against the configured secret tokenCaller / mounted handler (registry only enables Telegram when a webhook secret token is configured)
DiscordProvider webhook verification (Chat SDK adapter)The mounted Chat SDK adapter
WhatsAppOfficial webhooks verified by the Chat SDK adapter; personal-mode Baileys auth state is local credential materialThe mounted Chat SDK adapter / caller-provided handler
Local fake transportsnone (demos, tests, single-process)

The shared ChannelCore can call a caller-provided authorize hook before deduplication and session creation. Use it to bind provider identities to workspace permissions, bot installation state, org membership, and least-privilege channel policy.

import {
createChannelCore,
createMemoryDedupStore,
createMemorySessionResolver,
type ChannelRuntime,
} from "@claxedo/channels"
declare const runtime: ChannelRuntime
const core = createChannelCore({
runtime,
dedup: createMemoryDedupStore(),
sessions: createMemorySessionResolver(runtime),
authorize: async (envelope) => {
if (envelope.channel !== "github") return { ok: false, message: "Unsupported channel." }
if (envelope.repo?.owner !== "acme") return { ok: false, message: "Repository is not linked." }
return { ok: true }
},
})

Verify X-Hub-Signature-256 with the webhook secret before passing the payload to githubWebhookEnvelope.

import { githubWebhookEnvelope, verifyGitHubWebhookSignature } from "@claxedo/channels"
const body = await request.text()
if (
!verifyGitHubWebhookSignature({
body,
secret: process.env.GITHUB_WEBHOOK_SECRET!,
signature: request.headers.get("x-hub-signature-256"),
})
) {
return new Response("invalid signature", { status: 401 })
}
const envelope = githubWebhookEnvelope({
event: request.headers.get("x-github-event") ?? "",
delivery: request.headers.get("x-github-delivery") ?? "",
payload: JSON.parse(body),
})

Use a GitHub App with only the repository permissions needed for the workflows you expose. Do not run channel commands from untrusted repos without an authorization hook.

Approval tokens identify pending prompts in a channel thread. They are not a standalone authorization proof. The approval bridge binds prompts to threadKey when present and removes tokens after a decision. Deployments that need expiry, nonce persistence across processes, or cross-channel approval policy should provide a durable ApprovalBridge. The in-memory stores are single-process helpers — use durable storage for multi-instance deployments.


For the channel core architecture, session resolution, and install instructions, see the channels package page.