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.
Transports
Section titled “Transports”| Transport | Signature / secret verification | Verified by |
|---|---|---|
| GitHub | X-Hub-Signature-256 HMAC over the raw body with the webhook secret | Caller — use the verifyGitHubWebhookSignature helper before githubWebhookEnvelope |
| Slack | Provider webhook verification (Chat SDK adapter) | The mounted Chat SDK adapter |
| Telegram | Compare incoming X-Telegram-Bot-Api-Secret-Token against the configured secret token | Caller / mounted handler (registry only enables Telegram when a webhook secret token is configured) |
| Discord | Provider webhook verification (Chat SDK adapter) | The mounted Chat SDK adapter |
| Official webhooks verified by the Chat SDK adapter; personal-mode Baileys auth state is local credential material | The mounted Chat SDK adapter / caller-provided handler | |
| Local fake transports | none (demos, tests, single-process) | — |
Authorization hook
Section titled “Authorization hook”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 } },})GitHub signature verification
Section titled “GitHub signature verification”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
Section titled “Approval tokens”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.