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
|
# ONLY set these if you are serving SurfSense on a real domain via a reverse
|
||||||
# proxy (e.g. Caddy, Nginx, Cloudflare Tunnel).
|
# 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.
|
# they are automatically derived from the port settings above.
|
||||||
#
|
#
|
||||||
# NEXT_FRONTEND_URL=https://app.yourdomain.com
|
# 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.
|
# Only change this if you manage publications manually.
|
||||||
# ZERO_APP_PUBLICATIONS=zero_publication
|
# 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.
|
# 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
|
# Each sync worker needs at least 1 connection from both the UPSTREAM and CVR
|
||||||
# pools, so these constraints must hold:
|
# 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
|
# SSL mode for database connections: disable, require, verify-ca, verify-full
|
||||||
# DB_SSLMODE=disable
|
# 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.
|
# DB_USER / DB_PASSWORD / DB_NAME / DB_HOST / DB_PORT settings above.
|
||||||
# Use this for managed databases (AWS RDS, GCP Cloud SQL, Supabase, etc.)
|
# 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
|
# 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
|
# 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
|
# 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_TOKEN_BUYING_ENABLED=FALSE
|
||||||
# STRIPE_PREMIUM_TOKEN_PRICE_ID=price_...
|
# STRIPE_PREMIUM_TOKEN_PRICE_ID=price_...
|
||||||
# STRIPE_CREDIT_MICROS_PER_UNIT=1000000
|
# 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)
|
# 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
|
# 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_TOKEN=
|
||||||
# TELEGRAM_SHARED_BOT_USERNAME=
|
# TELEGRAM_SHARED_BOT_USERNAME=
|
||||||
# TELEGRAM_WEBHOOK_SECRET=
|
# TELEGRAM_WEBHOOK_SECRET=
|
||||||
# GATEWAY_BASE_URL=http://localhost:8929
|
# GATEWAY_BASE_URL=http://localhost:8929
|
||||||
# GATEWAY_TELEGRAM_INTAKE_MODE=webhook
|
# GATEWAY_TELEGRAM_INTAKE_MODE=webhook
|
||||||
|
|
||||||
# -- WhatsApp Gateway --
|
# -- WhatsApp --
|
||||||
# GATEWAY_WHATSAPP_INTAKE_MODE=disabled
|
# GATEWAY_WHATSAPP_INTAKE_MODE=disabled
|
||||||
# WHATSAPP_SHARED_BUSINESS_TOKEN=
|
# WHATSAPP_SHARED_BUSINESS_TOKEN=
|
||||||
# WHATSAPP_SHARED_PHONE_NUMBER_ID=
|
# WHATSAPP_SHARED_PHONE_NUMBER_ID=
|
||||||
|
|
@ -288,14 +288,14 @@ STT_SERVICE=local/base
|
||||||
# WHATSAPP_WEBHOOK_APP_SECRET=
|
# WHATSAPP_WEBHOOK_APP_SECRET=
|
||||||
# WHATSAPP_BRIDGE_URL=http://whatsapp-bridge:9929
|
# WHATSAPP_BRIDGE_URL=http://whatsapp-bridge:9929
|
||||||
|
|
||||||
# -- Slack Gateway --
|
# -- Slack --
|
||||||
# Uses SLACK_CLIENT_ID and SLACK_CLIENT_SECRET from the Slack connector section.
|
# Uses SLACK_CLIENT_ID and SLACK_CLIENT_SECRET from the Slack connector section.
|
||||||
#
|
#
|
||||||
# GATEWAY_SLACK_ENABLED=FALSE
|
# GATEWAY_SLACK_ENABLED=FALSE
|
||||||
# GATEWAY_SLACK_SIGNING_SECRET=
|
# GATEWAY_SLACK_SIGNING_SECRET=
|
||||||
# GATEWAY_SLACK_REDIRECT_URI=http://localhost:8929/api/v1/gateway/slack/callback
|
# 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
|
# Uses DISCORD_CLIENT_ID, DISCORD_CLIENT_SECRET, and DISCORD_BOT_TOKEN from the
|
||||||
# Discord connector section.
|
# Discord connector section.
|
||||||
#
|
#
|
||||||
|
|
@ -303,7 +303,7 @@ STT_SERVICE=local/base
|
||||||
# GATEWAY_DISCORD_REDIRECT_URI=http://localhost:8929/api/v1/gateway/discord/callback
|
# 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.
|
# SearXNG provides web search to all search spaces automatically.
|
||||||
# To access the SearXNG UI directly: http://localhost:8888
|
# To access the SearXNG UI directly: http://localhost:8888
|
||||||
|
|
@ -313,7 +313,7 @@ STT_SERVICE=local/base
|
||||||
# SEARXNG_SECRET=surfsense-searxng-secret
|
# 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
|
# Set DAYTONA_SANDBOX_ENABLED=TRUE and provide credentials to give the agent
|
||||||
# an isolated code execution environment via the Daytona cloud API.
|
# 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
|
# Premium turns are debited at the actual per-call provider cost reported
|
||||||
# by LiteLLM. Only applies to models with billing_tier=premium.
|
# by LiteLLM. Only applies to models with billing_tier=premium.
|
||||||
# PREMIUM_CREDIT_MICROS_LIMIT=5000000
|
# 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).
|
# Safety ceiling on per-call premium reservation, in micro-USD ($1.00 default).
|
||||||
# QUOTA_MAX_RESERVE_MICROS=1000000
|
# QUOTA_MAX_RESERVE_MICROS=1000000
|
||||||
|
|
@ -416,10 +416,10 @@ SURFSENSE_ENABLE_DOOM_LOOP=true
|
||||||
# QUOTA_DEFAULT_PODCAST_RESERVE_MICROS=200000
|
# QUOTA_DEFAULT_PODCAST_RESERVE_MICROS=200000
|
||||||
|
|
||||||
# Per-video-presentation reservation for the video Celery task ($1.00 default).
|
# 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
|
# 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
|
# Set TRUE to enable /free pages and anonymous chat API
|
||||||
NOLOGIN_MODE_ENABLED=FALSE
|
NOLOGIN_MODE_ENABLED=FALSE
|
||||||
# ANON_TOKEN_LIMIT=1000000
|
# 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` |
|
| 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` |
|
| 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)
|
### Observability (optional)
|
||||||
|
|
||||||
| Variable | Description |
|
| Variable | Description |
|
||||||
|
|
@ -187,9 +200,9 @@ Postgres. Before this design, a silent migration failure would leave
|
||||||
|
|
||||||
The backend exposes two endpoints:
|
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).
|
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
|
Returns 503 if not. The compose `backend.healthcheck` uses `/ready` so the
|
||||||
container only reports `healthy` once the schema is actually usable by
|
container only reports `healthy` once the schema is actually usable by
|
||||||
zero-cache.
|
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)
|
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`
|
### 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
|
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
|
service blocks `zero-cache` from starting. If you see it, your stack
|
||||||
predates the fix or you brought up `zero-cache` manually with `docker
|
predates the fix or you brought up `zero-cache` manually with `docker
|
||||||
compose up zero-cache` before the migrations service ran.
|
compose up zero-cache` before the migrations service ran.
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ icon: BookOpen
|
||||||
---
|
---
|
||||||
|
|
||||||
import { Card, Cards } from 'fumadocs-ui/components/card';
|
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.
|
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"
|
description="Integrate with third-party services"
|
||||||
href="/docs/connectors"
|
href="/docs/connectors"
|
||||||
/>
|
/>
|
||||||
|
<Card
|
||||||
|
icon={<MessageCircle />}
|
||||||
|
title="Messaging Channels"
|
||||||
|
description="Chat with SurfSense from Telegram, WhatsApp, Slack, and Discord"
|
||||||
|
href="/docs/messaging-channels"
|
||||||
|
/>
|
||||||
<Card
|
<Card
|
||||||
icon={<BookOpen />}
|
icon={<BookOpen />}
|
||||||
title="How-To Guides"
|
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:
|
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:
|
See [Messaging Channels](/docs/messaging-channels) for the channel-specific
|
||||||
|
setup guides.
|
||||||
```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.
|
|
||||||
|
|
||||||
### 1. Environment Configuration
|
### 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 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.
|
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
|
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
|
## Frontend Setup
|
||||||
|
|
||||||
|
|
@ -708,7 +684,7 @@ To verify your installation:
|
||||||
1. Open your browser and navigate to `http://localhost:3000`
|
1. Open your browser and navigate to `http://localhost:3000`
|
||||||
2. Sign in with your Google account (or local credentials if `AUTH_TYPE=LOCAL`)
|
2. Sign in with your Google account (or local credentials if `AUTH_TYPE=LOCAL`)
|
||||||
3. Create a search space and try uploading a document
|
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
|
5. Test the chat functionality with your uploaded content
|
||||||
|
|
||||||
## Troubleshooting
|
## 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",
|
"installation",
|
||||||
"manual-installation",
|
"manual-installation",
|
||||||
"docker-installation",
|
"docker-installation",
|
||||||
|
"messaging-channels",
|
||||||
"connectors",
|
"connectors",
|
||||||
"how-to",
|
"how-to",
|
||||||
"---Developers---",
|
"---Developers---",
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import {
|
||||||
Download,
|
Download,
|
||||||
FlaskConical,
|
FlaskConical,
|
||||||
Heart,
|
Heart,
|
||||||
|
MessageCircle,
|
||||||
Radar,
|
Radar,
|
||||||
Unplug,
|
Unplug,
|
||||||
Wrench,
|
Wrench,
|
||||||
|
|
@ -27,6 +28,7 @@ const DOCS_ICONS: Record<string, React.ComponentType> = {
|
||||||
Download,
|
Download,
|
||||||
FlaskConical,
|
FlaskConical,
|
||||||
Heart,
|
Heart,
|
||||||
|
MessageCircle,
|
||||||
Radar,
|
Radar,
|
||||||
Unplug,
|
Unplug,
|
||||||
Wrench,
|
Wrench,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue