Skip to main content

Channels

Connect your agent to any messaging platform with a unified adapter interface.


Table of Contents

  1. Overview
  2. All 37 Channels
  3. Setup Guides
  4. Custom Channel Adapter
  5. Message Routing
  6. Broadcast to Multiple Channels

Overview

The AgentOS Channel System normalizes every external messaging platform behind a single IChannelAdapter interface. Your agent code never speaks platform APIs directly — it emits and receives ChannelMessage objects, and the adapter handles all platform-specific serialization, authentication, and reconnection.

User (Discord / Telegram / etc.)
↕ platform SDK
IChannelAdapter
↕ ChannelRouter
Your Agent (AgentOS)

Channels are registered as messaging-channel extensions and managed by the ChannelRouter, which handles load balancing, health checks, and fallback.


All 37 Channels

Messaging & Chat

PlatformTypeRequired Env Vars
discordChatDISCORD_BOT_TOKEN, DISCORD_APPLICATION_ID
slackChatSLACK_BOT_TOKEN, SLACK_SIGNING_SECRET
telegramChatTELEGRAM_BOT_TOKEN
whatsappChatWHATSAPP_ACCESS_TOKEN, WHATSAPP_PHONE_NUMBER_ID
google-chatChatGOOGLE_CHAT_SERVICE_ACCOUNT_JSON
teamsChatTEAMS_BOT_ID, TEAMS_BOT_PASSWORD
signalChatSIGNAL_CLI_PATH or SIGNAL_API_URL
imessageChatmacOS only — no env vars
matrixChatMATRIX_HOMESERVER_URL, MATRIX_ACCESS_TOKEN
webchatChatWEBCHAT_SECRET (for webhook validation)
smsMessagingTWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_PHONE
emailMessagingSMTP_HOST, SMTP_USER, SMTP_PASS
lineChatLINE_CHANNEL_ACCESS_TOKEN, LINE_CHANNEL_SECRET
zaloChatZALO_APP_ID, ZALO_APP_SECRET
feishuChatFEISHU_APP_ID, FEISHU_APP_SECRET
mattermostChatMATTERMOST_URL, MATTERMOST_BOT_TOKEN
nextcloud-talkChatNEXTCLOUD_URL, NEXTCLOUD_TOKEN
ircChatIRC_SERVER, IRC_NICK, IRC_CHANNELS
nostrDecentralizedNOSTR_PRIVATE_KEY
tlonDecentralizedTLON_SHIP, TLON_CODE
twitchStreamingTWITCH_CLIENT_ID, TWITCH_CLIENT_SECRET, TWITCH_CHANNEL

Social Media — Broadcast

PlatformTypeRequired Env Vars
twitterSocialTWITTER_API_KEY, TWITTER_API_SECRET, TWITTER_ACCESS_TOKEN, TWITTER_ACCESS_SECRET
instagramSocialINSTAGRAM_ACCESS_TOKEN, INSTAGRAM_ACCOUNT_ID
linkedinSocialLINKEDIN_ACCESS_TOKEN, LINKEDIN_ORGANIZATION_ID
facebookSocialFACEBOOK_PAGE_ACCESS_TOKEN, FACEBOOK_PAGE_ID
threadsSocialTHREADS_ACCESS_TOKEN, THREADS_USER_ID
blueskySocialBLUESKY_IDENTIFIER, BLUESKY_PASSWORD
mastodonSocialMASTODON_INSTANCE_URL, MASTODON_ACCESS_TOKEN
redditSocialREDDIT_CLIENT_ID, REDDIT_CLIENT_SECRET, REDDIT_USERNAME, REDDIT_PASSWORD
pinterestSocialPINTEREST_ACCESS_TOKEN
tiktokSocialTIKTOK_CLIENT_KEY, TIKTOK_CLIENT_SECRET
youtubeSocialYOUTUBE_API_KEY, YOUTUBE_CHANNEL_ID
farcasterSocialFARCASTER_MNEMONIC
lemmySocialLEMMY_INSTANCE_URL, LEMMY_USERNAME, LEMMY_PASSWORD

Publishing

PlatformTypeRequired Env Vars
devtoBlogDEVTO_API_KEY
hashnodeBlogHASHNODE_TOKEN, HASHNODE_PUBLICATION_ID
mediumBlogMEDIUM_INTEGRATION_TOKEN
wordpressBlogWORDPRESS_URL, WORDPRESS_USERNAME, WORDPRESS_PASSWORD
google-businessBusinessGOOGLE_BUSINESS_ACCOUNT_ID, GOOGLE_SERVICE_ACCOUNT_JSON

Setup Guides

Discord

1. Create a Discord Application

  1. Go to discord.com/developers/applications
  2. Create a new application
  3. Under "Bot", create a bot and copy the token
  4. Under "OAuth2 → URL Generator", select scopes: bot, applications.commands
  5. Select permissions: Send Messages, Read Message History, Use Slash Commands
  6. Invite the bot to your server using the generated URL

2. Set environment variables

export DISCORD_BOT_TOKEN=your-bot-token
export DISCORD_APPLICATION_ID=your-application-id
export DISCORD_GUILD_ID=your-server-id # optional: restrict to one guild

3. Register the adapter

import { ChannelRouter } from '@framers/agentos/channels';
import { DiscordAdapter } from '@framers/agentos-extensions/channels/discord';

const router = new ChannelRouter();
const discord = new DiscordAdapter();

await discord.initialize({
credential: process.env.DISCORD_BOT_TOKEN!,
metadata: { applicationId: process.env.DISCORD_APPLICATION_ID },
});

router.register(discord);

// Listen for incoming messages
discord.on('message', async (message) => {
const response = await agent.reply(message.text);
await discord.sendMessage(message.conversationId, {
blocks: [{ type: 'text', text: response }],
});
});

Slack

1. Create a Slack App

  1. Go to api.slack.com/apps → Create New App → From Scratch
  2. Enable "Event Subscriptions" with Request URL pointing to your webhook endpoint
  3. Subscribe to message.channels, message.im, app_mention events
  4. Under "OAuth & Permissions", add scopes: chat:write, channels:history, im:history
  5. Install the app to your workspace, copy the Bot User OAuth Token
export SLACK_BOT_TOKEN=xoxb-...
export SLACK_SIGNING_SECRET=your-signing-secret

2. Register the adapter

import { SlackAdapter } from '@framers/agentos-extensions/channels/slack';

const slack = new SlackAdapter();
await slack.initialize({
credential: process.env.SLACK_BOT_TOKEN!,
metadata: { signingSecret: process.env.SLACK_SIGNING_SECRET },
});

router.register(slack);

Telegram

1. Create a bot

  1. Message @BotFather on Telegram
  2. Send /newbot and follow the prompts
  3. Copy the bot token
export TELEGRAM_BOT_TOKEN=123456789:ABC-...

2. Register the adapter

import { TelegramAdapter } from '@framers/agentos-extensions/channels/telegram';

const telegram = new TelegramAdapter();
await telegram.initialize({
credential: process.env.TELEGRAM_BOT_TOKEN!,
});

router.register(telegram);

Twitter / X

1. Create a Twitter Developer Project

  1. Go to developer.twitter.com → Create Project → Create App
  2. In the App settings, enable "Read and Write" permissions
  3. Generate Access Token and Secret under "Keys and Tokens"
export TWITTER_API_KEY=your-api-key
export TWITTER_API_SECRET=your-api-secret
export TWITTER_ACCESS_TOKEN=your-access-token
export TWITTER_ACCESS_SECRET=your-access-secret

2. Register the adapter

import { TwitterAdapter } from '@framers/agentos-extensions/channels/twitter';

const twitter = new TwitterAdapter();
await twitter.initialize({
credential: JSON.stringify({
apiKey: process.env.TWITTER_API_KEY,
apiSecret: process.env.TWITTER_API_SECRET,
accessToken: process.env.TWITTER_ACCESS_TOKEN,
accessSecret: process.env.TWITTER_ACCESS_SECRET,
}),
});

WhatsApp

1. Set up WhatsApp Business API

  1. Create a Meta Business account at business.facebook.com
  2. Add a WhatsApp Business App in Meta for Developers
  3. Configure a phone number and copy the Access Token and Phone Number ID
export WHATSAPP_ACCESS_TOKEN=your-access-token
export WHATSAPP_PHONE_NUMBER_ID=your-phone-number-id

2. Register the adapter

import { WhatsAppAdapter } from '@framers/agentos-extensions/channels/whatsapp';

const whatsapp = new WhatsAppAdapter();
await whatsapp.initialize({
credential: process.env.WHATSAPP_ACCESS_TOKEN!,
metadata: { phoneNumberId: process.env.WHATSAPP_PHONE_NUMBER_ID },
});

Custom Channel Adapter

Implement IChannelAdapter to add any platform not in the built-in set:

import type {
IChannelAdapter,
ChannelAuthConfig,
ChannelSendResult,
MessageContent,
ChannelEventHandler,
ChannelEventType,
ChannelConnectionInfo,
} from '@framers/agentos/channels';

class MyPlatformAdapter implements IChannelAdapter {
readonly platform = 'my-platform';
readonly displayName = 'My Platform';
readonly capabilities = ['text', 'images'] as const;

private client: MyPlatformClient | null = null;
private handlers = new Map<ChannelEventType, ChannelEventHandler[]>();

async initialize(auth: ChannelAuthConfig): Promise<void> {
this.client = new MyPlatformClient(auth.credential);
await this.client.connect();

this.client.on('message', (raw) => {
const normalizedMessage = {
id: raw.messageId,
conversationId: raw.channelId,
text: raw.body,
senderId: raw.userId,
timestamp: raw.ts,
platform: 'my-platform',
};
this.emit('message', normalizedMessage);
});
}

async shutdown(): Promise<void> {
await this.client?.disconnect();
this.client = null;
}

async sendMessage(
conversationId: string,
content: MessageContent,
): Promise<ChannelSendResult> {
const text = content.blocks.find((b) => b.type === 'text')?.text ?? '';
const sent = await this.client!.send({ channelId: conversationId, body: text });
return { messageId: sent.id };
}

on(event: ChannelEventType, handler: ChannelEventHandler): void {
const existing = this.handlers.get(event) ?? [];
this.handlers.set(event, [...existing, handler]);
}

off(event: ChannelEventType, handler: ChannelEventHandler): void {
const existing = this.handlers.get(event) ?? [];
this.handlers.set(event, existing.filter((h) => h !== handler));
}

async getConnectionInfo(): Promise<ChannelConnectionInfo> {
return { status: this.client ? 'connected' : 'disconnected' };
}

private emit(event: ChannelEventType, payload: unknown): void {
for (const handler of this.handlers.get(event) ?? []) {
handler(payload as any);
}
}
}

Register and use:

const myAdapter = new MyPlatformAdapter();
await myAdapter.initialize({ credential: 'my-api-key' });
router.register(myAdapter);

Message Routing

ChannelRouter manages all registered adapters and routes messages by platform:

import { ChannelRouter } from '@framers/agentos/channels';

const router = new ChannelRouter();

// Register all desired adapters
router.register(discordAdapter);
router.register(slackAdapter);
router.register(telegramAdapter);

// Route a message to a specific platform
await router.send('discord', channelId, {
blocks: [{ type: 'text', text: 'Hello from AgentOS!' }],
});

// Listen for messages across all platforms
router.onMessage(async (message, platform) => {
console.log(`[${platform}] ${message.senderId}: ${message.text}`);
const reply = await myAgent.reply(message.text);
await router.send(platform, message.conversationId, {
blocks: [{ type: 'text', text: reply }],
});
});

// Health check all adapters
const health = await router.healthCheck();
console.log(health);
// { discord: 'connected', slack: 'connected', telegram: 'error' }

Broadcast to Multiple Channels

Send the same message to multiple platforms simultaneously:

import { ChannelRouter } from '@framers/agentos/channels';

const router = new ChannelRouter();
// ... register adapters ...

// Broadcast to a fixed list of channels
await router.broadcast(
['discord', 'slack', 'telegram'],
{
blocks: [
{ type: 'text', text: '🚀 AgentOS v2.0 is now live!' },
],
},
{
// Map platform to its target conversation/channel ID
conversationIds: {
discord: '1234567890',
slack: 'C01234ABCDE',
telegram: '-100123456789',
},
}
);

For social media broadcast (Twitter, Bluesky, LinkedIn, etc.), see SOCIAL_POSTING.md which provides the MultiChannelPostTool with content adaptation per platform.