mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-06-11 01:45:58 +00:00
Add user-owned IM channel connections
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
# IM Channel Connections
|
||||
|
||||
DeerFlow supports user-owned IM channel connections for Telegram, Slack, and Discord. A logged-in user connects a provider from the frontend, and incoming IM messages run under that DeerFlow user account instead of the raw platform user id.
|
||||
|
||||
## Configuration
|
||||
|
||||
Enable the top-level `channel_connections` block in `config.yaml`:
|
||||
|
||||
```yaml
|
||||
channel_connections:
|
||||
enabled: true
|
||||
public_base_url: https://deerflow.example.com
|
||||
encryption_key: $DEER_FLOW_CHANNEL_CONNECTIONS_KEY
|
||||
|
||||
telegram:
|
||||
enabled: true
|
||||
bot_token: $TELEGRAM_BOT_TOKEN
|
||||
bot_username: $TELEGRAM_BOT_USERNAME
|
||||
webhook_secret: $TELEGRAM_WEBHOOK_SECRET
|
||||
|
||||
slack:
|
||||
enabled: true
|
||||
client_id: $SLACK_CLIENT_ID
|
||||
client_secret: $SLACK_CLIENT_SECRET
|
||||
signing_secret: $SLACK_SIGNING_SECRET
|
||||
event_delivery: http
|
||||
|
||||
discord:
|
||||
enabled: true
|
||||
client_id: $DISCORD_CLIENT_ID
|
||||
client_secret: $DISCORD_CLIENT_SECRET
|
||||
bot_token: $DISCORD_BOT_TOKEN
|
||||
permissions: "274877975552"
|
||||
```
|
||||
|
||||
`public_base_url` must be the externally reachable HTTPS origin used by provider callbacks and webhooks. `encryption_key` encrypts provider tokens at rest with Fernet. Keep it stable; v1 does not support transparent key rotation, so changing it requires users to reconnect.
|
||||
|
||||
## Frontend Flow
|
||||
|
||||
The workspace sidebar shows a Channels group with Telegram, Slack, and Discord. Settings > Channels exposes the management surface for connect, disconnect, and reconnect. Browser state-changing calls use the existing CSRF-aware frontend fetch wrapper.
|
||||
|
||||
## Provider Setup
|
||||
|
||||
Telegram:
|
||||
|
||||
- Register a bot with BotFather.
|
||||
- Configure the bot username, bot token, and a random webhook secret.
|
||||
- Users connect with a deep link: `https://t.me/<bot_username>?start=<state>`.
|
||||
- Production webhook path: `POST /api/channels/webhooks/telegram`, protected by `X-Telegram-Bot-Api-Secret-Token`.
|
||||
- Local/self-hosted long polling still works through the existing Telegram channel worker.
|
||||
|
||||
Slack:
|
||||
|
||||
- Create a Slack app with OAuth V2.
|
||||
- Redirect URL: `https://<public_base_url>/api/channels/slack/callback`.
|
||||
- Event request URL: `https://<public_base_url>/api/channels/webhooks/slack/events`.
|
||||
- Required signing secret: Slack's request signing secret, not the deprecated verification token.
|
||||
- Suggested MVP bot scopes: `app_mentions:read`, `chat:write`, `channels:history`, `channels:read`.
|
||||
- Slack events are signature-verified, deduplicated by `event_id`, and then routed to a matching user connection.
|
||||
|
||||
Discord:
|
||||
|
||||
- Create a Discord application and bot.
|
||||
- Redirect URL: `https://<public_base_url>/api/channels/discord/callback`.
|
||||
- DeerFlow starts OAuth with `identify guilds bot applications.commands` and the configured bot permissions.
|
||||
- The Discord Gateway is still handled by `discord.py`; message content may require the privileged Message Content Intent depending on your bot setup.
|
||||
|
||||
## 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_credentials`: encrypted access/refresh/bot tokens.
|
||||
- `channel_oauth_states`: one-time OAuth/deep-link states.
|
||||
- `channel_conversations`: connection-scoped IM conversation to DeerFlow thread mapping.
|
||||
- `channel_webhook_deliveries`: provider webhook dedupe records.
|
||||
|
||||
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 platform user id as `channel_user_id`. Legacy operator-owned channels keep the existing JSON `ChannelStore` behavior when no `connection_id` is present.
|
||||
|
||||
## Security Notes
|
||||
|
||||
- OAuth state tokens are one-time and short-lived.
|
||||
- Provider tokens are never returned from browser APIs.
|
||||
- Public callback/webhook routes bypass cookie auth only because they validate provider state/signatures/secrets themselves.
|
||||
- Slack and Telegram webhooks skip CSRF because they are called by providers, not browsers.
|
||||
- Logs should never include access tokens, refresh tokens, bot tokens, OAuth codes, or raw signed webhook bodies.
|
||||
Reference in New Issue
Block a user