# IM Channel Connections DeerFlow supports user-owned IM channel bindings for Telegram, Slack, Discord, Feishu/Lark, DingTalk, WeChat, and WeCom. The feature reuses the existing `channels.*` runtime configuration, so it works in local and private deployments with the same outbound transports already supported by DeerFlow. No public IP, OAuth callback URL, or provider webhook is required in this implementation. ## Configuration Configure the actual IM bots under the existing `channels` block: ```yaml channels: telegram: enabled: true bot_token: $TELEGRAM_BOT_TOKEN slack: enabled: true bot_token: $SLACK_BOT_TOKEN app_token: $SLACK_APP_TOKEN discord: enabled: true bot_token: $DISCORD_BOT_TOKEN feishu: enabled: true app_id: $FEISHU_APP_ID app_secret: $FEISHU_APP_SECRET dingtalk: enabled: true client_id: $DINGTALK_CLIENT_ID client_secret: $DINGTALK_CLIENT_SECRET wechat: enabled: true bot_token: $WECHAT_BOT_TOKEN wecom: enabled: true bot_id: $WECOM_BOT_ID bot_secret: $WECOM_BOT_SECRET ``` Then enable user bindings in `channel_connections`: ```yaml channel_connections: enabled: true telegram: enabled: true bot_username: $TELEGRAM_BOT_USERNAME slack: enabled: true discord: enabled: true feishu: enabled: true dingtalk: enabled: true wechat: enabled: true wecom: enabled: true ``` `channel_connections` does not duplicate provider secrets. It only controls the browser-facing connect UI and stores per-user binding records. Telegram needs `bot_username` only so the frontend can open a deep link. ## Connect Flow Telegram: - The frontend creates a short one-time code. - The Connect button opens `https://t.me/?start=`. - The existing Telegram long-polling worker receives `/start ` and binds that Telegram chat/user to the current DeerFlow user. Slack: - The frontend creates a short one-time code. - The UI shows `Send /connect to the DeerFlow Slack bot.` - The existing Slack Socket Mode worker receives the message and binds the Slack user/team to the current DeerFlow user. Discord: - The frontend creates a short one-time code. - The UI shows `Send /connect to the DeerFlow Discord bot.` - The existing Discord Gateway worker receives the message and binds the Discord user/guild to the current DeerFlow user. Feishu/Lark, DingTalk, WeChat, and WeCom: - The frontend creates a short one-time code. - The UI shows `Send /connect to the DeerFlow bot.` - The already-running long-connection or polling worker receives the message and binds the platform user/workspace identity to the current DeerFlow user. Codes expire after 10 minutes and are single-use. ## Runtime Model Connection records live in SQL tables under `deerflow.persistence.channel_connections`: - `channel_connections`: owner user, provider identity, workspace/guild/team, status, metadata. - `channel_oauth_states`: one-time connect codes and Telegram deep-link state. - `channel_conversations`: connection-scoped IM conversation to DeerFlow thread mapping. - `channel_credentials`: reserved for future provider-token flows, not used by the local/private binding flow. Incoming messages that resolve to a connection carry `connection_id`, `owner_user_id`, and `workspace_id`. `ChannelManager` uses `owner_user_id` as the DeerFlow run user id and preserves the raw platform user id as `channel_user_id`. ## Security Notes - Browser APIs remain authenticated and CSRF-protected. - Connect codes are random, short-lived, and single-use. - Provider bot tokens remain in `channels.*` and are never returned to the browser. - This implementation does not add public provider callback or webhook routes.