feat(messaging): introduce comprehensive setup docs for Telegram, WhatsApp, Slack, and Discord messaging channels

This commit is contained in:
Anish Sarkar 2026-06-02 00:25:49 +05:30
parent 20994671bc
commit ebddf4506a
14 changed files with 530 additions and 54 deletions

View file

@ -0,0 +1,76 @@
---
title: Discord
description: Enable the SurfSense bot for in-Discord agent chat
---
# Discord Messaging Channel
The Discord messaging channel lets users mention the SurfSense bot in Discord
and chat with the SurfSense backend agent from a Discord channel.
This is separate from the Discord connector. The messaging channel handles bot
mentions and replies; the connector gives the agent Discord channel/message read
tools.
## Discord Application Settings
Create or reuse a Discord application in the
[Discord Developer Portal](https://discord.com/developers/applications).
In **OAuth2 > Redirects**, add both callback URLs if the same application powers
the connector and messaging channel:
```bash
https://your-backend.example.com/api/v1/auth/discord/connector/callback
https://your-backend.example.com/api/v1/gateway/discord/callback
```
For local OAuth testing, replace the host with your local or public tunnel URL,
and make sure `DISCORD_REDIRECT_URI` and `GATEWAY_DISCORD_REDIRECT_URI` match
the Discord dashboard exactly.
## Bot Permissions And Intents
In **Bot > Privileged Gateway Intents**, enable:
- **Message Content Intent** so SurfSense can read text after a bot mention.
When installing the bot, grant:
- View Channels
- Send Messages
- Send Messages in Threads
- Read Message History
## Environment Variables
For Docker installs, add these to `docker/.env`. For manual installs, add them to
`surfsense_backend/.env`.
```bash
DISCORD_CLIENT_ID=your_discord_client_id
DISCORD_CLIENT_SECRET=your_discord_client_secret
DISCORD_BOT_TOKEN=your_discord_bot_token
GATEWAY_DISCORD_ENABLED=TRUE
GATEWAY_DISCORD_REDIRECT_URI=https://your-backend.example.com/api/v1/gateway/discord/callback
```
The messaging channel uses the same Discord app credentials as the Discord
connector. `DISCORD_REDIRECT_URI` remains the connector callback;
`GATEWAY_DISCORD_REDIRECT_URI` is the separate messaging channel install
callback.
## Runtime Behavior
1. Discord sends a `MESSAGE_CREATE` event over its WebSocket API.
2. SurfSense stores the event in the durable gateway inbox.
3. SurfSense resolves the Discord user binding to a SurfSense user and search space.
4. SurfSense runs the backend agent with that user's permissions.
5. The agent reply is posted back to the same Discord channel.
## Deployment Note
Only one running backend process should connect to Discord with a
given bot token. For multi-replica deployments, enable
`GATEWAY_DISCORD_ENABLED=TRUE` in a single backend process and leave it disabled
in other API replicas.

View file

@ -0,0 +1,60 @@
---
title: Docker Setup
description: Configure messaging channels for Docker and one-line installs
---
# Docker Setup
For Docker and one-line installs, configure messaging channels in the generated
`docker/.env` file. You do not need to edit `surfsense_backend/.env.example`.
The Compose stack passes `docker/.env` into the backend, worker, and beat
containers. Database, Redis, SearXNG, and internal Docker networking are already
wired by Compose.
## Public URLs
For localhost-only testing, the defaults are enough for the SurfSense UI, but
public webhooks from Telegram, WhatsApp, and Slack require a public HTTPS backend
URL. Use your deployed backend URL or a tunnel such as Cloudflare Tunnel or
ngrok.
When using a custom domain or tunnel, set:
```bash
BACKEND_URL=https://api.example.com
GATEWAY_BASE_URL=https://api.example.com
NEXT_FRONTEND_URL=https://app.example.com
NEXT_PUBLIC_FASTAPI_BACKEND_URL=https://api.example.com
```
## Environment Variables
Uncomment only the channel you are enabling in `docker/.env`.
| Channel | Main variables |
| --- | --- |
| Telegram | `TELEGRAM_SHARED_BOT_TOKEN`, `TELEGRAM_SHARED_BOT_USERNAME`, `TELEGRAM_WEBHOOK_SECRET`, `GATEWAY_BASE_URL`, `GATEWAY_TELEGRAM_INTAKE_MODE` |
| WhatsApp Cloud API | `GATEWAY_WHATSAPP_INTAKE_MODE`, `WHATSAPP_SHARED_BUSINESS_TOKEN`, `WHATSAPP_SHARED_PHONE_NUMBER_ID`, `WHATSAPP_SHARED_DISPLAY_PHONE_NUMBER`, `WHATSAPP_SHARED_WABA_ID`, `WHATSAPP_WEBHOOK_VERIFY_TOKEN`, `WHATSAPP_WEBHOOK_APP_SECRET` |
| WhatsApp Baileys | `GATEWAY_WHATSAPP_INTAKE_MODE`, `WHATSAPP_BRIDGE_URL`, `WHATSAPP_MODE` |
| Slack | `SLACK_CLIENT_ID`, `SLACK_CLIENT_SECRET`, `GATEWAY_SLACK_ENABLED`, `GATEWAY_SLACK_SIGNING_SECRET`, `GATEWAY_SLACK_REDIRECT_URI` |
| Discord | `DISCORD_CLIENT_ID`, `DISCORD_CLIENT_SECRET`, `DISCORD_BOT_TOKEN`, `GATEWAY_DISCORD_ENABLED`, `GATEWAY_DISCORD_REDIRECT_URI` |
After editing `docker/.env`, restart the stack:
```bash
docker compose up -d
```
For WhatsApp Baileys, start the Compose profile:
```bash
docker compose --profile whatsapp up -d
```
Then follow the per-channel setup pages:
- [Telegram](/docs/messaging-channels/telegram)
- [WhatsApp](/docs/messaging-channels/whatsapp)
- [Slack](/docs/messaging-channels/slack)
- [Discord](/docs/messaging-channels/discord)

View file

@ -0,0 +1,42 @@
---
title: Messaging Channels
description: Chat with SurfSense from Telegram, WhatsApp, Slack, and Discord
---
import { Card, Cards } from 'fumadocs-ui/components/card';
Choose the external chat app you want to connect to SurfSense. Each guide shows
the required app setup, environment variables, and pairing flow.
<Cards>
<Card
title="Telegram"
description="Enable SurfSense chat from Telegram"
href="/docs/messaging-channels/telegram"
/>
<Card
title="WhatsApp"
description="Enable SurfSense chat from WhatsApp"
href="/docs/messaging-channels/whatsapp"
/>
<Card
title="Slack"
description="Enable the SurfSense bot for in-Slack agent chat"
href="/docs/messaging-channels/slack"
/>
<Card
title="Discord"
description="Enable the SurfSense bot for in-Discord agent chat"
href="/docs/messaging-channels/discord"
/>
<Card
title="Docker Setup"
description="Configure messaging channels for Docker and one-line installs"
href="/docs/messaging-channels/docker"
/>
<Card
title="Troubleshooting"
description="Common pairing, webhook, and bot reply issues"
href="/docs/messaging-channels/troubleshooting"
/>
</Cards>

View file

@ -0,0 +1,13 @@
{
"title": "Messaging Channels",
"icon": "MessageCircle",
"pages": [
"telegram",
"whatsapp",
"slack",
"discord",
"docker",
"troubleshooting"
],
"defaultOpen": false
}

View file

@ -0,0 +1,84 @@
---
title: Slack
description: Enable the SurfSense bot for in-Slack agent chat
---
# Slack Messaging Channel
The Slack messaging channel lets users mention the SurfSense bot in Slack and
chat with the SurfSense backend agent from a Slack thread.
This is separate from the Slack connector. The messaging channel handles bot
mentions and replies; the connector gives the agent Slack search/read tools.
## Required Slack App Scopes
Add these **Bot Token Scopes** in Slack OAuth & Permissions:
| Scope | Purpose |
| --- | --- |
| `app_mentions:read` | Receive bot mention events |
| `chat:write` | Reply in Slack threads |
| `channels:read` | Read public channel metadata |
| `groups:read` | Read private channel metadata where the bot is present |
| `im:write` | Send onboarding or direct replies |
| `users:read` | Resolve Slack users |
| `team:read` | Resolve workspace metadata |
Optional scopes:
- `im:history` if you support direct message chat with the bot.
- `commands` if you add slash commands.
Avoid `channels:history` and `groups:history` for the messaging channel unless
you specifically need gateway-side context reads. Slack workspace search should
stay with the Slack connector.
## Event Subscriptions
Enable Slack Events API and subscribe to:
- `app_mention`
Set the request URL to:
```bash
https://your-backend.example.com/api/v1/gateway/webhooks/slack
```
Slack must be able to reach this URL. Do not use `localhost` for event
subscriptions.
## OAuth Redirect URLs
If the same Slack app powers both the connector and messaging channel, add both
redirect URLs in **OAuth & Permissions**:
```bash
https://your-backend.example.com/api/v1/auth/slack/connector/callback
https://your-backend.example.com/api/v1/gateway/slack/callback
```
## Environment Variables
For Docker installs, add these to `docker/.env`. For manual installs, add them to
`surfsense_backend/.env`.
```bash
SLACK_CLIENT_ID=your_slack_client_id
SLACK_CLIENT_SECRET=your_slack_client_secret
GATEWAY_SLACK_ENABLED=TRUE
GATEWAY_SLACK_SIGNING_SECRET=your_slack_signing_secret
GATEWAY_SLACK_REDIRECT_URI=https://your-backend.example.com/api/v1/gateway/slack/callback
```
After changing Slack scopes, redirect URLs, or event subscriptions, reinstall
the Slack app to your workspace so Slack grants the updated permissions.
## Runtime Behavior
1. Slack sends an `app_mention` event to SurfSense.
2. SurfSense verifies the Slack signature and stores the event in the gateway inbox.
3. SurfSense resolves the Slack user binding to a SurfSense user and search space.
4. SurfSense runs the backend agent with that user's permissions.
5. The agent reply is posted back in the same Slack thread.

View file

@ -0,0 +1,62 @@
---
title: Telegram
description: Enable SurfSense chat from Telegram
---
# Telegram Messaging Channel
Telegram lets users chat with the SurfSense agent from a Telegram bot. Users pair
their Telegram chat from **User Settings > Messaging Channels**.
## Environment Variables
For Docker installs, add these to `docker/.env`. For manual installs, add them to
`surfsense_backend/.env`.
```bash
TELEGRAM_SHARED_BOT_TOKEN=123456:bot-token-from-botfather
TELEGRAM_SHARED_BOT_USERNAME=your_bot_username
TELEGRAM_WEBHOOK_SECRET=generate-a-long-random-secret
GATEWAY_BASE_URL=https://api.example.com
GATEWAY_TELEGRAM_INTAKE_MODE=webhook
```
`TELEGRAM_WEBHOOK_SECRET` must be 1-256 characters and contain only `A-Z`, `a-z`,
`0-9`, `_`, or `-`.
## Intake Modes
| Mode | Use when |
| --- | --- |
| `webhook` | Production or any deployment with a public HTTPS backend URL |
| `longpoll` | Single-replica self-host installs that cannot expose a public HTTPS webhook |
| `disabled` | You do not want Telegram intake enabled |
For SaaS-style or multi-replica deployments, use `webhook`. Long polling should
only run in a single backend process.
## Webhook URL
Telegram webhooks use this shape:
```text
${GATEWAY_BASE_URL}/api/v1/gateway/webhooks/telegram/{account_id}
```
After deploying the backend, register the webhook:
```bash
cd surfsense_backend
uv run python scripts/register_webhook.py
```
If switching a bot from long polling to webhooks, delete any existing Telegram
webhook or pending `getUpdates` session before relying on the new mode.
## Pairing Flow
1. The user opens **User Settings > Messaging Channels**.
2. The user starts Telegram pairing.
3. SurfSense provides a pairing code or bot link.
4. The user sends the pairing command to the Telegram bot.
5. SurfSense binds that Telegram chat to the selected search space.

View file

@ -0,0 +1,66 @@
---
title: Troubleshooting
description: Common messaging channel pairing, webhook, and bot reply issues
---
# Messaging Channels Troubleshooting
## The Bot Does Not Reply
Check that:
- The channel is enabled in the backend environment.
- The backend restarted after the environment change.
- The external platform can reach your public HTTPS backend URL.
- The user paired the channel from **User Settings > Messaging Channels**.
- Redis is running, because gateway inbox processing uses backend coordination
and rate-limit state.
## Telegram
Check that:
- `TELEGRAM_SHARED_BOT_TOKEN` and `TELEGRAM_SHARED_BOT_USERNAME` are correct.
- `GATEWAY_TELEGRAM_INTAKE_MODE` is one of `webhook`, `longpoll`, or `disabled`.
- `TELEGRAM_WEBHOOK_SECRET` contains only `A-Z`, `a-z`, `0-9`, `_`, or `-`.
- Webhook mode uses a public HTTPS `GATEWAY_BASE_URL`.
- Long polling runs in only one backend process.
## WhatsApp
For Meta Cloud API, check that:
- `GATEWAY_WHATSAPP_INTAKE_MODE=cloud`.
- The Meta webhook URL is `${GATEWAY_BASE_URL}/api/v1/gateway/webhooks/whatsapp`.
- The Meta verify token matches `WHATSAPP_WEBHOOK_VERIFY_TOKEN`.
- `WHATSAPP_SHARED_DISPLAY_PHONE_NUMBER` contains the public WhatsApp number
users should message.
For Baileys, check that:
- `GATEWAY_WHATSAPP_INTAKE_MODE=baileys`.
- The `whatsapp` Compose profile is running.
- The bridge is paired and healthy.
- You are messaging the account's Message Yourself chat.
## Slack
Check that:
- `GATEWAY_SLACK_ENABLED=TRUE`.
- The Slack signing secret matches `GATEWAY_SLACK_SIGNING_SECRET`.
- Slack Events API is enabled and subscribed to `app_mention`.
- The Slack event request URL is public HTTPS and points to
`/api/v1/gateway/webhooks/slack`.
- The Slack app was reinstalled after scope or redirect URL changes.
## Discord
Check that:
- `GATEWAY_DISCORD_ENABLED=TRUE`.
- The bot token is valid.
- Message Content Intent is enabled.
- The bot can view and send messages in the channel.
- Exactly one backend process is running the Discord listener.
- The Discord user is paired to a SurfSense user and search space.

View file

@ -0,0 +1,75 @@
---
title: WhatsApp
description: Enable SurfSense chat from WhatsApp
---
# WhatsApp Messaging Channel
WhatsApp supports two intake modes:
- `cloud` uses the official Meta WhatsApp Cloud API with a SurfSense-owned system
WhatsApp Business Account.
- `baileys` uses the unofficial Baileys WebSocket bridge for self-hosted,
one-tenant Message Yourself installs.
Use `cloud` for production and shared deployments.
## Meta Cloud API
Create a Meta app, provision a WhatsApp Business Account and phone number, and
create a long-lived system user token with WhatsApp permissions.
Point the Meta app webhook to:
```text
${GATEWAY_BASE_URL}/api/v1/gateway/webhooks/whatsapp
```
Set the webhook verify token in Meta to the same value as
`WHATSAPP_WEBHOOK_VERIFY_TOKEN`.
For Docker installs, add these to `docker/.env`. For manual installs, add them to
`surfsense_backend/.env`.
```bash
GATEWAY_WHATSAPP_INTAKE_MODE=cloud
WHATSAPP_SHARED_BUSINESS_TOKEN=your-system-user-token
WHATSAPP_SHARED_PHONE_NUMBER_ID=your-meta-phone-number-id
WHATSAPP_SHARED_DISPLAY_PHONE_NUMBER=15551234567
WHATSAPP_SHARED_WABA_ID=your-waba-id
WHATSAPP_GRAPH_API_VERSION=v25.0
WHATSAPP_WEBHOOK_VERIFY_TOKEN=generate-a-long-random-secret
WHATSAPP_WEBHOOK_APP_SECRET=your-meta-app-secret
```
Users open **User Settings > Messaging Channels**, click **Pair WhatsApp**, and
open the returned `wa.me` link. WhatsApp pre-fills `/start CODE`; the user must
press send to bind the chat.
## Baileys Self-Hosted Mode
Baileys is unofficial. Use it only for single-tenant self-hosted installs where
the operator accepts the risk of a personal WhatsApp session bridge.
```bash
GATEWAY_WHATSAPP_INTAKE_MODE=baileys
WHATSAPP_BRIDGE_URL=http://whatsapp-bridge:9929
WHATSAPP_MODE=self-chat
docker compose --profile whatsapp up -d
```
After pairing, use WhatsApp's Message Yourself chat. The bridge only forwards
messages from your own self-chat and ignores groups, other chats, and other
people.
The `whatsapp-bridge` container stores Baileys auth state in the
`surfsense-whatsapp-sessions` Docker volume. That volume contains account
takeover material. Treat it like a secret.
To intentionally reset pairing:
```bash
docker compose --profile whatsapp down
docker volume rm surfsense-whatsapp-sessions
docker compose --profile whatsapp up -d
```