mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-06-02 19:55:18 +02:00
feat(messaging): introduce comprehensive setup docs for Telegram, WhatsApp, Slack, and Discord messaging channels
This commit is contained in:
parent
20994671bc
commit
ebddf4506a
14 changed files with 530 additions and 54 deletions
|
|
@ -70,7 +70,7 @@ EMBEDDING_MODEL=sentence-transformers/all-MiniLM-L6-v2
|
|||
# ------------------------------------------------------------------------------
|
||||
# ONLY set these if you are serving SurfSense on a real domain via a reverse
|
||||
# proxy (e.g. Caddy, Nginx, Cloudflare Tunnel).
|
||||
# For standard localhost deployments, leave all of these commented out —
|
||||
# For standard localhost deployments, leave all of these commented out.
|
||||
# they are automatically derived from the port settings above.
|
||||
#
|
||||
# NEXT_FRONTEND_URL=https://app.yourdomain.com
|
||||
|
|
@ -92,7 +92,7 @@ EMBEDDING_MODEL=sentence-transformers/all-MiniLM-L6-v2
|
|||
# Only change this if you manage publications manually.
|
||||
# ZERO_APP_PUBLICATIONS=zero_publication
|
||||
|
||||
# Sync worker tuning — zero-cache defaults ZERO_NUM_SYNC_WORKERS to the number
|
||||
# Sync worker tuning. zero-cache defaults ZERO_NUM_SYNC_WORKERS to the number
|
||||
# of CPU cores, which can exceed the connection pool limits on high-core machines.
|
||||
# Each sync worker needs at least 1 connection from both the UPSTREAM and CVR
|
||||
# pools, so these constraints must hold:
|
||||
|
|
@ -137,7 +137,7 @@ EMBEDDING_MODEL=sentence-transformers/all-MiniLM-L6-v2
|
|||
# SSL mode for database connections: disable, require, verify-ca, verify-full
|
||||
# DB_SSLMODE=disable
|
||||
|
||||
# Full DATABASE_URL override — when set, takes precedence over the individual
|
||||
# Full DATABASE_URL override. When set, this takes precedence over the individual
|
||||
# DB_USER / DB_PASSWORD / DB_NAME / DB_HOST / DB_PORT settings above.
|
||||
# Use this for managed databases (AWS RDS, GCP Cloud SQL, Supabase, etc.)
|
||||
# DATABASE_URL=postgresql+asyncpg://user:password@your-rds-host:5432/surfsense?sslmode=require
|
||||
|
|
@ -152,7 +152,7 @@ EMBEDDING_MODEL=sentence-transformers/all-MiniLM-L6-v2
|
|||
# REDIS_URL=redis://redis:6379/0
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Stripe (pay-as-you-go page packs — disabled by default)
|
||||
# Stripe (pay-as-you-go page packs, disabled by default)
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
# Set TRUE to allow users to buy additional page packs via Stripe Checkout
|
||||
|
|
@ -171,7 +171,7 @@ STRIPE_PAGE_BUYING_ENABLED=FALSE
|
|||
# STRIPE_TOKEN_BUYING_ENABLED=FALSE
|
||||
# STRIPE_PREMIUM_TOKEN_PRICE_ID=price_...
|
||||
# STRIPE_CREDIT_MICROS_PER_UNIT=1000000
|
||||
# DEPRECATED — STRIPE_TOKENS_PER_UNIT=1000000
|
||||
# DEPRECATED: STRIPE_TOKENS_PER_UNIT=1000000
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# TTS & STT (Text-to-Speech / Speech-to-Text)
|
||||
|
|
@ -266,18 +266,18 @@ STT_SERVICE=local/base
|
|||
# COMPOSIO_REDIRECT_URI=http://localhost:8000/api/v1/auth/composio/connector/callback
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Messaging Gateways (optional)
|
||||
# Messaging Channels (optional)
|
||||
# ------------------------------------------------------------------------------
|
||||
# Configure only the gateways you want to use.
|
||||
# Configure only the external chat channels you want to use.
|
||||
|
||||
# -- Telegram Gateway --
|
||||
# -- Telegram --
|
||||
# TELEGRAM_SHARED_BOT_TOKEN=
|
||||
# TELEGRAM_SHARED_BOT_USERNAME=
|
||||
# TELEGRAM_WEBHOOK_SECRET=
|
||||
# GATEWAY_BASE_URL=http://localhost:8929
|
||||
# GATEWAY_TELEGRAM_INTAKE_MODE=webhook
|
||||
|
||||
# -- WhatsApp Gateway --
|
||||
# -- WhatsApp --
|
||||
# GATEWAY_WHATSAPP_INTAKE_MODE=disabled
|
||||
# WHATSAPP_SHARED_BUSINESS_TOKEN=
|
||||
# WHATSAPP_SHARED_PHONE_NUMBER_ID=
|
||||
|
|
@ -288,14 +288,14 @@ STT_SERVICE=local/base
|
|||
# WHATSAPP_WEBHOOK_APP_SECRET=
|
||||
# WHATSAPP_BRIDGE_URL=http://whatsapp-bridge:9929
|
||||
|
||||
# -- Slack Gateway --
|
||||
# -- Slack --
|
||||
# Uses SLACK_CLIENT_ID and SLACK_CLIENT_SECRET from the Slack connector section.
|
||||
#
|
||||
# GATEWAY_SLACK_ENABLED=FALSE
|
||||
# GATEWAY_SLACK_SIGNING_SECRET=
|
||||
# GATEWAY_SLACK_REDIRECT_URI=http://localhost:8929/api/v1/gateway/slack/callback
|
||||
|
||||
# -- Discord Gateway --
|
||||
# -- Discord --
|
||||
# Uses DISCORD_CLIENT_ID, DISCORD_CLIENT_SECRET, and DISCORD_BOT_TOKEN from the
|
||||
# Discord connector section.
|
||||
#
|
||||
|
|
@ -303,7 +303,7 @@ STT_SERVICE=local/base
|
|||
# GATEWAY_DISCORD_REDIRECT_URI=http://localhost:8929/api/v1/gateway/discord/callback
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# SearXNG (bundled web search — works out of the box, no config needed)
|
||||
# SearXNG (bundled web search, works out of the box with no config needed)
|
||||
# ------------------------------------------------------------------------------
|
||||
# SearXNG provides web search to all search spaces automatically.
|
||||
# To access the SearXNG UI directly: http://localhost:8888
|
||||
|
|
@ -313,7 +313,7 @@ STT_SERVICE=local/base
|
|||
# SEARXNG_SECRET=surfsense-searxng-secret
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Daytona Sandbox (optional — cloud code execution for the deep agent)
|
||||
# Daytona Sandbox (optional cloud code execution for the deep agent)
|
||||
# ------------------------------------------------------------------------------
|
||||
# Set DAYTONA_SANDBOX_ENABLED=TRUE and provide credentials to give the agent
|
||||
# an isolated code execution environment via the Daytona cloud API.
|
||||
|
|
@ -404,7 +404,7 @@ SURFSENSE_ENABLE_DOOM_LOOP=true
|
|||
# Premium turns are debited at the actual per-call provider cost reported
|
||||
# by LiteLLM. Only applies to models with billing_tier=premium.
|
||||
# PREMIUM_CREDIT_MICROS_LIMIT=5000000
|
||||
# DEPRECATED — PREMIUM_TOKEN_LIMIT=5000000
|
||||
# DEPRECATED: PREMIUM_TOKEN_LIMIT=5000000
|
||||
|
||||
# Safety ceiling on per-call premium reservation, in micro-USD ($1.00 default).
|
||||
# QUOTA_MAX_RESERVE_MICROS=1000000
|
||||
|
|
@ -416,10 +416,10 @@ SURFSENSE_ENABLE_DOOM_LOOP=true
|
|||
# QUOTA_DEFAULT_PODCAST_RESERVE_MICROS=200000
|
||||
|
||||
# Per-video-presentation reservation for the video Celery task ($1.00 default).
|
||||
# Override path bypasses QUOTA_MAX_RESERVE_MICROS clamp — raise with care.
|
||||
# Override path bypasses QUOTA_MAX_RESERVE_MICROS clamp. Raise with care.
|
||||
# QUOTA_DEFAULT_VIDEO_PRESENTATION_RESERVE_MICROS=1000000
|
||||
|
||||
# No-login (anonymous) mode — public users can chat without an account
|
||||
# No-login (anonymous) mode. Public users can chat without an account
|
||||
# Set TRUE to enable /free pages and anonymous chat API
|
||||
NOLOGIN_MODE_ENABLED=FALSE
|
||||
# ANON_TOKEN_LIMIT=1000000
|
||||
|
|
|
|||
|
|
@ -124,6 +124,19 @@ Uncomment the connectors you want to use. Redirect URIs follow the pattern `http
|
|||
| Microsoft (Teams & OneDrive) | `MICROSOFT_CLIENT_ID`, `MICROSOFT_CLIENT_SECRET`, `TEAMS_REDIRECT_URI`, `ONEDRIVE_REDIRECT_URI` |
|
||||
| Dropbox | `DROPBOX_APP_KEY`, `DROPBOX_APP_SECRET`, `DROPBOX_REDIRECT_URI` |
|
||||
|
||||
### Messaging Channels
|
||||
|
||||
Configure these in the same `docker/.env` file when you want users to chat with
|
||||
SurfSense from external apps. See [Messaging Channels](/docs/messaging-channels)
|
||||
for full setup.
|
||||
|
||||
| Channel | Variables |
|
||||
|---------|-----------|
|
||||
| Telegram | `TELEGRAM_SHARED_BOT_TOKEN`, `TELEGRAM_SHARED_BOT_USERNAME`, `TELEGRAM_WEBHOOK_SECRET`, `GATEWAY_BASE_URL`, `GATEWAY_TELEGRAM_INTAKE_MODE` |
|
||||
| WhatsApp | `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` |
|
||||
| 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` |
|
||||
|
||||
### Observability (optional)
|
||||
|
||||
| Variable | Description |
|
||||
|
|
@ -187,9 +200,9 @@ Postgres. Before this design, a silent migration failure would leave
|
|||
|
||||
The backend exposes two endpoints:
|
||||
|
||||
- `GET /health` — lightweight liveness probe (always returns 200 if the
|
||||
- `GET /health`: lightweight liveness probe (always returns 200 if the
|
||||
process is up).
|
||||
- `GET /ready` — readiness probe that confirms `zero_publication` exists.
|
||||
- `GET /ready`: readiness probe that confirms `zero_publication` exists.
|
||||
Returns 503 if not. The compose `backend.healthcheck` uses `/ready` so the
|
||||
container only reports `healthy` once the schema is actually usable by
|
||||
zero-cache.
|
||||
|
|
@ -247,7 +260,7 @@ docker compose exec db psql -U surfsense -d surfsense \
|
|||
```
|
||||
|
||||
The default migration timeout is 900 seconds. Slow disks (Windows / WSL2)
|
||||
may need more — set `MIGRATION_TIMEOUT` in `.env` to increase it.
|
||||
may need more. Set `MIGRATION_TIMEOUT` in `.env` to increase it.
|
||||
|
||||
### Zero-cache stuck on `Unknown or invalid publications`
|
||||
|
||||
|
|
@ -258,7 +271,7 @@ Error: Unknown or invalid publications. Specified: [zero_publication]. Found: []
|
|||
```
|
||||
|
||||
This means `zero-cache` started before `zero_publication` was created. With
|
||||
the current compose files this should be impossible — the `migrations`
|
||||
the current compose files this should be impossible. The `migrations`
|
||||
service blocks `zero-cache` from starting. If you see it, your stack
|
||||
predates the fix or you brought up `zero-cache` manually with `docker
|
||||
compose up zero-cache` before the migrations service ran.
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ icon: BookOpen
|
|||
---
|
||||
|
||||
import { Card, Cards } from 'fumadocs-ui/components/card';
|
||||
import { ClipboardCheck, Download, Container, Wrench, Cable, BookOpen, FlaskConical, Heart } from 'lucide-react';
|
||||
import { ClipboardCheck, Download, Container, Wrench, Cable, BookOpen, FlaskConical, Heart, MessageCircle } from 'lucide-react';
|
||||
|
||||
Welcome to **SurfSense's Documentation!** Here, you'll find everything you need to get the most out of SurfSense. Dive in to explore how SurfSense can be your AI-powered research companion.
|
||||
|
||||
|
|
@ -40,6 +40,12 @@ Welcome to **SurfSense's Documentation!** Here, you'll find everything you need
|
|||
description="Integrate with third-party services"
|
||||
href="/docs/connectors"
|
||||
/>
|
||||
<Card
|
||||
icon={<MessageCircle />}
|
||||
title="Messaging Channels"
|
||||
description="Chat with SurfSense from Telegram, WhatsApp, Slack, and Discord"
|
||||
href="/docs/messaging-channels"
|
||||
/>
|
||||
<Card
|
||||
icon={<BookOpen />}
|
||||
title="How-To Guides"
|
||||
|
|
|
|||
|
|
@ -39,38 +39,14 @@ Complete all the [setup steps](/docs), including:
|
|||
|
||||
The backend is the core of SurfSense. Follow these steps to set it up:
|
||||
|
||||
### Optional: Telegram External Chat Surface
|
||||
### Optional: Messaging Channels
|
||||
|
||||
SurfSense can expose the same canonical chat agent through Telegram. The `external_chat_*` tables store adapter identity, delivery configuration, and durable inbox rows. The actual chat thread and messages remain in `new_chat_threads` and `new_chat_messages`, with first-party web/desktop chats marked as `source="surfsense"` and external surfaces marked by platform, such as `source="telegram"`. All chat-message sources are eligible for Zero replication so a future SurfSense UI layer can render external chat surfaces. The web app initially shows pairing, health, revoke, and resume controls under **User Settings > Messaging Channels**.
|
||||
SurfSense can expose the same backend agent through Telegram, WhatsApp, Slack,
|
||||
and Discord. For manual installs, configure the relevant channel variables in
|
||||
`surfsense_backend/.env`.
|
||||
|
||||
Add these variables to `surfsense_backend/.env` when enabling the Telegram surface:
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
`GATEWAY_TELEGRAM_INTAKE_MODE` must be `webhook`, `longpoll`, or `disabled`. Use `webhook` for production/SaaS deployments, `longpoll` only for single-replica self-host installs that cannot expose a public HTTPS webhook, and `disabled` to skip Telegram intake. `TELEGRAM_WEBHOOK_SECRET` must use only `A-Z`, `a-z`, `0-9`, `_`, and `-` characters. `REDIS_APP_URL` is reused for external chat rate limits and per-thread locks. The webhook URL shape is:
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
Keep the FastAPI backend, Celery worker, and Celery beat running. Telegram webhooks write inbound updates into `external_chat_inbound_events`. The FastAPI process owns external chat inbox processing and runs the same SurfSense agent used by web UI chats, then replies back to Telegram. Celery remains maintenance-only for external chat reconciliation, health checks, and retention sweeps. There is no separate gateway service, `SERVICE_ROLE=gateway` process, or Celery agent-processing path.
|
||||
|
||||
For self-hosted BYO Telegram bots without a public HTTPS URL, set `GATEWAY_TELEGRAM_INTAKE_MODE=longpoll`. The FastAPI process starts one lifespan long-poll supervisor per non-system Telegram account and writes updates into the same durable inbox. The FastAPI inbox worker then processes those rows in-process through the canonical `new_chat_*` surface. This fallback is intended for single-replica self-hosted installs. For SaaS-style multi-replica deployments, prefer public webhooks and keep `GATEWAY_TELEGRAM_INTAKE_MODE=webhook` so API replicas skip BYO polling entirely. Telegram does not allow `get_updates()` while a webhook is active, so delete any existing webhook for a BYO bot before relying on long polling.
|
||||
|
||||
When upgrading from an older gateway-runner deployment, apply the rewritten migration 144 external chat schema, deploy the new backend, worker, and beat images, then stop the old `gateway` service. Wait about 30 seconds for any old Telegram `getUpdates` long-poll request to release its advisory lock before starting the new API process. Register each webhook again with the account-id URL above and the per-account `webhook_secret`. If you roll back before using the migration in production, restore the old image and downgrade the schema first.
|
||||
See [Messaging Channels](/docs/messaging-channels) for the channel-specific
|
||||
setup guides.
|
||||
|
||||
### 1. Environment Configuration
|
||||
|
||||
|
|
@ -490,7 +466,7 @@ If everything is set up correctly, you should see output indicating the server i
|
|||
|
||||
## Zero-Cache Setup
|
||||
|
||||
**zero-cache** is the Rocicorp Zero server that sits between PostgreSQL and the browser. It streams real-time updates (notifications, document indexing status, chat comments, collaboration indicators) to all connected clients via WebSocket. The frontend connects to it on startup — without zero-cache running, you will not see live updates and many parts of the UI will sit on stale data.
|
||||
**zero-cache** is the Rocicorp Zero server that sits between PostgreSQL and the browser. It streams real-time updates (notifications, document indexing status, chat comments, collaboration indicators) to all connected clients via WebSocket. The frontend connects to it on startup. Without zero-cache running, you will not see live updates and many parts of the UI will sit on stale data.
|
||||
|
||||
For an overview of how Zero works and the list of synced tables, see the [Real-Time Sync with Zero](/docs/how-to/zero-sync) guide.
|
||||
|
||||
|
|
@ -572,7 +548,7 @@ cd ../docker
|
|||
docker compose -f docker-compose.deps-only.yml up -d
|
||||
```
|
||||
|
||||
The deps-only stack exposes zero-cache on port `4848` (default) — keep `NEXT_PUBLIC_ZERO_CACHE_URL=http://localhost:4848` in your `surfsense_web/.env`.
|
||||
The deps-only stack exposes zero-cache on port `4848` by default. Keep `NEXT_PUBLIC_ZERO_CACHE_URL=http://localhost:4848` in your `surfsense_web/.env`.
|
||||
|
||||
## Frontend Setup
|
||||
|
||||
|
|
@ -708,7 +684,7 @@ To verify your installation:
|
|||
1. Open your browser and navigate to `http://localhost:3000`
|
||||
2. Sign in with your Google account (or local credentials if `AUTH_TYPE=LOCAL`)
|
||||
3. Create a search space and try uploading a document
|
||||
4. Watch the upload status update live without refreshing — this confirms zero-cache is wired up correctly
|
||||
4. Watch the upload status update live without refreshing. This confirms zero-cache is wired up correctly
|
||||
5. Test the chat functionality with your uploaded content
|
||||
|
||||
## Troubleshooting
|
||||
|
|
|
|||
76
surfsense_web/content/docs/messaging-channels/discord.mdx
Normal file
76
surfsense_web/content/docs/messaging-channels/discord.mdx
Normal 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.
|
||||
60
surfsense_web/content/docs/messaging-channels/docker.mdx
Normal file
60
surfsense_web/content/docs/messaging-channels/docker.mdx
Normal 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)
|
||||
42
surfsense_web/content/docs/messaging-channels/index.mdx
Normal file
42
surfsense_web/content/docs/messaging-channels/index.mdx
Normal 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>
|
||||
13
surfsense_web/content/docs/messaging-channels/meta.json
Normal file
13
surfsense_web/content/docs/messaging-channels/meta.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"title": "Messaging Channels",
|
||||
"icon": "MessageCircle",
|
||||
"pages": [
|
||||
"telegram",
|
||||
"whatsapp",
|
||||
"slack",
|
||||
"discord",
|
||||
"docker",
|
||||
"troubleshooting"
|
||||
],
|
||||
"defaultOpen": false
|
||||
}
|
||||
84
surfsense_web/content/docs/messaging-channels/slack.mdx
Normal file
84
surfsense_web/content/docs/messaging-channels/slack.mdx
Normal 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.
|
||||
62
surfsense_web/content/docs/messaging-channels/telegram.mdx
Normal file
62
surfsense_web/content/docs/messaging-channels/telegram.mdx
Normal 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.
|
||||
|
|
@ -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.
|
||||
75
surfsense_web/content/docs/messaging-channels/whatsapp.mdx
Normal file
75
surfsense_web/content/docs/messaging-channels/whatsapp.mdx
Normal 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
|
||||
```
|
||||
|
|
@ -9,6 +9,7 @@
|
|||
"installation",
|
||||
"manual-installation",
|
||||
"docker-installation",
|
||||
"messaging-channels",
|
||||
"connectors",
|
||||
"how-to",
|
||||
"---Developers---",
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import {
|
|||
Download,
|
||||
FlaskConical,
|
||||
Heart,
|
||||
MessageCircle,
|
||||
Radar,
|
||||
Unplug,
|
||||
Wrench,
|
||||
|
|
@ -27,6 +28,7 @@ const DOCS_ICONS: Record<string, React.ComponentType> = {
|
|||
Download,
|
||||
FlaskConical,
|
||||
Heart,
|
||||
MessageCircle,
|
||||
Radar,
|
||||
Unplug,
|
||||
Wrench,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue