Messaging Channels for AI Agents
Configure Telegram, Slack, Discord, Feishu/Lark, WeChat, DingTalk, WeCom, and other messaging channels for local AI agent continuation and remote control.
Connecting an IM channel takes three steps everywhere: create the bot on the platform, put its credentials under channels.<kind> in settings.json, and let VibeAround start the plugin. This page covers the VibeAround side and the general pattern; platform-side specifics (bot registration screens, permission scopes, webhook URLs) live in each plugin's own README.
The pattern
-
Install the plugin. Desktop onboarding installs channel plugins into
~/.vibearound/plugins/<kind>/; the desktop plugin manager adds or updates them later. A plugin that exists but has no configuration stays disabled. -
Configure the channel. Add a
channels.<kind>object to~/.vibearound/settings.json. The keys are plugin-specific — VibeAround passes the object through to the plugin verbatim. Two representative examples:
{
"channels": {
"telegram": {
"bot_token": "123456:ABC-DEF..."
},
"feishu": {
"app_id": "cli_a1b2c3...",
"app_secret": "..."
}
}
}- Start it. The daemon starts configured plugins at boot. After editing settings while running, reconcile with:
va channel sync # start newly configured, stop removed, restart changedor use the desktop channel controls. va channels shows runtime status for every plugin.
Choosing defaults per channel
The remote section assigns a default agent and profile per channel kind, used when a chat's first message creates a thread:
{
"remote": {
"channels": {
"telegram": { "agent_id": "claude", "profile_id": "moonshot" },
"feishu": { "agent_id": "codex" }
}
}
}Users can still /switch per thread; these are just starting values.
Supported channels
Every channel has a dedicated setup page with platform-side steps and a code-verified config block:
| Channel | Setup page |
|---|---|
| Telegram | channels/telegram |
| Feishu / Lark | channels/feishu — permission JSON, long-connection subscriptions |
| Slack | channels/slack — one-paste app manifest, Socket Mode |
| Discord | channels/discord |
| DingTalk | channels/dingtalk |
| WeCom | channels/wecom |
| QQ Bot | channels/qqbot |
| channels/wechat — QR login | |
| channels/whatsapp — QR login |
Kind ids and repository links are also in the supported matrix. Each plugin README additionally documents:
- how to create the bot and obtain credentials,
- required platform permissions/scopes,
- webhook vs long-poll modes where the platform offers both,
- platform capabilities and limits (card layouts, attachment size, rate limits).
Health and lifecycle
Plugins are supervised: crash means respawn after a short delay, and a plugin that stops emitting heartbeats for 90 seconds is killed and respawned. Practical implications:
- A misconfigured credential typically shows as a crash-respawn loop — check
va channelsand the daemon logs, fix the config, thenva channel restart <kind>. - Undelivered system messages and permission cards are queued and re-sent after a plugin restart, so a flapping plugin does not eat approvals.
- Stopping a channel (
va channel stop <kind>) does not close its threads; conversations resume when the plugin starts again.
Verifying a new channel
va channels— the plugin shows as running.- Message the bot: expect a reply from the default agent (first contact creates the thread).
/statusin the chat — confirms thread, workspace, agent, profile.- Trigger a permission (ask the agent to run a shell command) — confirm the card renders and the tap resolves it.
Source anchors: src/core/src/config.rs (channel_names, channel raw config, RemoteConfig), src/core/src/plugins/ (plugin directories), src/core/src/channels/ (sync, supervision, outbox), src/cli/src/args.rs (channel commands).
Last verified: v0.7.11
Per-channel setup
The fastest channel to set up: one token from BotFather, one config block.
Platform setup
- Open @BotFather in Telegram.
- Send
/newbotand follow the prompts. - Copy the bot token.
Configuration
Required fields: bot_token.
{
"channels": {
"telegram": {
"bot_token": "123456789:ABCdefGHIjklMNOpqrSTUvwxYZ",
"verbose": { "show_thinking": true, "show_tool_use": true }
}
}
}Apply with va channel sync (the pattern). The optional verbose object works on every channel: show_thinking and show_tool_use (both default false) include the agent's thinking and tool-use blocks in chat output.
Feishu and Lark share one open-platform model, but the portal and API domain must match your tenant: mainland Feishu uses the Feishu Open Platform (open.feishu.cn); overseas Lark uses Lark Developer (open.larksuite.com). Keep the app, its permissions, event/callback subscriptions, and the credentials you paste into VibeAround all on the same platform — a Feishu app against the Lark domain (or the reverse) fails to connect.
VibeAround uses long connection (WebSocket initiated from your machine) for both events and callbacks, so no public callback URL or tunnel is required.
Platform setup
- Open the matching developer portal and create an enterprise internal app.
- Enable the bot capability, then copy the App ID and App Secret.
- In Development Configuration → Permissions & Scopes, use batch import with the permission JSON below.
- In Development Configuration → Events and Callbacks → Event Configuration, choose long connection and add
im.message.receive_v1(delivers user messages to VibeAround). - In Callback Configuration, choose long connection and add
card.action.trigger(delivers card button taps — approve/deny, session selection). - In Version Management, create and publish a version — permissions, events, and callbacks usually take effect only after publishing, and enterprise tenants may require admin approval.
- Add the bot to a controlled private chat or small group first; verify message delivery and card buttons before broad rollout.
Permission batch-import JSON:
{
"scopes": {
"tenant": [
"aily:file:read",
"aily:file:write",
"application:application.app_message_stats.overview:readonly",
"application:application:self_manage",
"application:bot.menu:write",
"cardkit:card:write",
"contact:user.employee_id:readonly",
"corehr:file:download",
"event:ip_list",
"im:chat.access_event.bot_p2p_chat:read",
"im:chat.members:bot_access",
"im:message",
"im:message.group_at_msg:readonly",
"im:message.p2p_msg:readonly",
"im:message:readonly",
"im:message:send_as_bot",
"im:resource"
],
"user": [
"aily:file:read",
"aily:file:write",
"im:chat.access_event.bot_p2p_chat:read"
]
}
}Configuration
Required fields: app_id, app_secret.
{
"channels": {
"feishu": {
"app_id": "cli_xxxxxxxxxxxx",
"app_secret": "your-app-secret",
"verbose": { "show_thinking": true, "show_tool_use": true }
}
}
}Behavior
- Replies render as V2 interactive cards that update in place while the agent streams; permission requests arrive as tappable card buttons.
- Group chats and DMs are separate conversation routes; multiple bots in one group each keep their own thread.
Troubleshooting
| Symptom | Check |
|---|---|
| No incoming messages | Event Configuration uses long connection and includes im.message.receive_v1 |
| Card buttons do nothing | Callback Configuration uses long connection and includes card.action.trigger |
| Imported permissions still fail | Publish a new app version; confirm admin approval went through |
| Long-connection validation fails | Start VibeAround first (the plugin initiates the connection); confirm the machine reaches the matching open-platform domain |
| Credentials fail to connect | App ID/Secret, developer portal, and API domain must all belong to the same platform (Feishu vs Lark) |
Official references: API permissions · Events over long connection · Callbacks over long connection · Receive message event · Card interactions
Slack runs over Socket Mode — no public callback URL needed. The whole app definition fits in one manifest paste.
Platform setup
- Create an app at api.slack.com/apps via Create New App → From an app manifest.
- Paste this manifest:
{
"display_information": { "name": "VibeAround" },
"features": {
"bot_user": { "display_name": "VibeAround", "always_online": true },
"slash_commands": [
{
"command": "/va",
"description": "VibeAround command (e.g. /va help, /va switch claude)",
"should_escape": false
},
{
"command": "/vibearound",
"description": "VibeAround command",
"should_escape": false
}
]
},
"oauth_config": {
"scopes": {
"bot": [
"files:read", "app_mentions:read", "chat:write", "commands",
"im:history", "im:read", "im:write"
]
},
"pkce_enabled": false
},
"settings": {
"event_subscriptions": { "bot_events": ["app_mention", "message.im"] },
"interactivity": { "is_enabled": true },
"org_deploy_enabled": false,
"socket_mode_enabled": true,
"token_rotation_enabled": false,
"is_mcp_enabled": false
}
}- Generate an App-Level Token (
xapp-…) with theconnections:writescope for Socket Mode. - Install the app to your workspace and copy the Bot User OAuth Token (
xoxb-…). - In a channel: invite the app and @mention it. In DMs: just message it.
Configuration
Required fields: bot_token (xoxb) and app_token (xapp).
{
"channels": {
"slack": {
"bot_token": "xoxb-...",
"app_token": "xapp-...",
"verbose": { "show_thinking": true, "show_tool_use": true }
}
}
}Behavior
- Slack reserves bare slash commands, so VibeAround commands use the
/vaprefix:/va new,/va switch claude,/va status(command reference — every command works behind the prefix). - Connection dies immediately? Check that Socket Mode is enabled and
app_tokenis thexapp-token, not the bot token.
Bot token plus two portal switches; the bot answers where it is @mentioned.
Platform setup
- Create an application in the Discord Developer Portal and generate a token under Bot.
- Enable Privileged Gateway Intents: Message Content Intent ON (required); Server Members Intent optional.
- Under OAuth2 → URL Generator, select scope
botwith permissionsSend Messages,Read Message History,Embed Links. - Open the generated invite URL to add the bot to your server.
Configuration
Required fields: bot_token.
{
"channels": {
"discord": {
"bot_token": "your-discord-bot-token",
"verbose": { "show_thinking": true, "show_tool_use": true }
}
}
}Behavior
- In server channels the bot only responds when @mentioned; each channel where it is mentioned becomes its own conversation route.
- No incoming messages at all? Message Content Intent is the usual culprit.
DingTalk uses Stream Mode (WebSocket) — no public callback URL needed.
Platform setup
- Create an app at the DingTalk Open Platform.
- Enable Stream Mode in the app settings.
- Copy the Client ID and Client Secret.
- Grant message-event permissions in the app permission list.
Configuration
Required fields: client_id, client_secret.
{
"channels": {
"dingtalk": {
"client_id": "your-client-id",
"client_secret": "your-client-secret",
"verbose": { "show_thinking": true, "show_tool_use": true }
}
}
}Older guides named these fields
app_key/app_secret— the plugin requiresclient_id/client_secret.
Behavior
- Nothing arrives? Stream Mode not enabled is the usual cause.
Platform setup
- Create a bot in the WeCom admin console.
- Copy the bot id and secret.
Configuration
Required fields: bot_id, secret.
{
"channels": {
"wecom": {
"bot_id": "your-bot-id",
"secret": "your-bot-secret",
"verbose": { "show_thinking": true, "show_tool_use": true }
}
}
}Older guides named the second field
bot_secret— the plugin requiressecret.
Platform setup
- Create a bot at the QQ Open Platform.
- Copy the App ID and secret.
- Add the bot to the target guild and channels.
Configuration
Required fields: app_id, secret.
{
"channels": {
"qqbot": {
"app_id": "your-app-id",
"secret": "your-secret",
"verbose": { "show_thinking": false, "show_tool_use": false }
}
}
}Older guides named the second field
app_token— the plugin requiressecret.
Behavior
- Replies are send-only within QQ guild channels (no in-place streaming edits).
WeChat connects through an OpenClaw-compatible bridge with QR login — no credentials in settings.
Setup
- Add the config block below (it can be empty apart from
verbose) and start VibeAround. - The plugin shows a QR code in the terminal or desktop app.
- Scan it with the WeChat mobile app.
Configuration
Required fields: none (authentication happens at runtime via QR).
{
"channels": {
"weixin-openclaw-bridge": {
"verbose": { "show_thinking": false, "show_tool_use": false }
}
}
}Note the kind id is weixin-openclaw-bridge, not wechat.
Behavior
- Replies are plain text and send-only — no streaming edits, no interactive cards (permission requests degrade to text).
WhatsApp connects through Baileys (an unofficial WhatsApp Web client) with QR login on first run; the session persists to disk afterwards.
Setup
- Add the config block below and start VibeAround.
- Scan the QR code shown on first run with the WhatsApp mobile app (Linked devices).
Configuration
Required fields: none (QR authentication at runtime).
{
"channels": {
"whatsapp": {
"verbose": { "show_thinking": false, "show_tool_use": false }
}
}
}Behavior
- Unofficial-client caveat: WhatsApp does not offer an official bot API for this use; treat the connection as best-effort and keep the linked device list tidy.
Last verified: v0.7.11