BotForge

Build

Channels

Every messaging platform is a single ChannelAdapter object implementing one interface — the dashboard, dispatcher and Workflow Builder never special-case a platform by name.

The ChannelAdapter interface

Defined once in src/channels/types.ts and registered per-platform in src/channels/registry.ts.

verifyWebhook(req, secret)Verify request authenticity (header secret or HMAC) before trusting the payload.
parseUpdate(body)Translate the platform's raw payload into a NormalizedUpdate.
send(channelId, msg, token)Send an outbound message via the platform's own API.
setWebhook(token, url, secret)Register the webhook URL for a bot.
validateToken(token)Validate a bot token/credential set, returning a ChannelIdentity — throws if invalid.
getIdentity(token)Return bot identity (name, username, id) without validating.

Looking up an adapter

import { getAdapter, isAdapterReady } from "@/channels/registry";

const adapter = getAdapter("TELEGRAM");
if (isAdapterReady("REDDIT")) { /* not yet — stub adapter */ }

Normalized types

Every adapter translates its platform's payload into the same shapes, so modules and the dispatcher stay channel-agnostic: NormalizedUpdate, NormalizedMessage, NormalizedCallback, NormalizedUser, NormalizedChannel, NormalizedAttachment, NormalizedButton and NormalizedOutbound. Existing Telegram-specific handlers keep working unchanged — the dispatcher tries normalized handlers first, falling back to Telegram-specific ones only when platform === "TELEGRAM".