From ad24c3a36996cf45ce6daf4e3cb095bb19b867ef Mon Sep 17 00:00:00 2001 From: Anish Sarkar <104695310+AnishSarkar22@users.noreply.github.com> Date: Mon, 1 Jun 2026 12:37:35 +0530 Subject: [PATCH] feat(web): add Slack messaging channel setup --- surfsense_web/.env.example | 5 ++ .../components/MessagingChannelsContent.tsx | 54 ++++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/surfsense_web/.env.example b/surfsense_web/.env.example index 12d81ee3f..032bb48ea 100644 --- a/surfsense_web/.env.example +++ b/surfsense_web/.env.example @@ -6,7 +6,12 @@ FASTAPI_BACKEND_INTERNAL_URL=https://your-internal-backend.example.com NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE=LOCAL or GOOGLE NEXT_PUBLIC_ETL_SERVICE=UNSTRUCTURED or LLAMACLOUD or DOCLING NEXT_PUBLIC_ZERO_CACHE_URL=http://localhost:4848 + +# Messaging gateway options +# WhatsApp UI toggle: disabled, cloud, or baileys NEXT_PUBLIC_GATEWAY_WHATSAPP_INTAKE_MODE=disabled +# Slack gateway UI toggle: true or false +NEXT_PUBLIC_GATEWAY_SLACK_ENABLED=false # Contact Form Vars (optional) DATABASE_URL=postgresql://postgres:[YOUR-PASSWORD]@db.sdsf.supabase.co:5432/postgres diff --git a/surfsense_web/app/dashboard/[search_space_id]/user-settings/components/MessagingChannelsContent.tsx b/surfsense_web/app/dashboard/[search_space_id]/user-settings/components/MessagingChannelsContent.tsx index b44f3ecbb..57dfe321e 100644 --- a/surfsense_web/app/dashboard/[search_space_id]/user-settings/components/MessagingChannelsContent.tsx +++ b/surfsense_web/app/dashboard/[search_space_id]/user-settings/components/MessagingChannelsContent.tsx @@ -18,6 +18,7 @@ type Binding = { external_display_name?: string | null; external_username?: string | null; suspended_reason?: string | null; + external_metadata?: Record | null; }; type Platform = { @@ -50,6 +51,7 @@ export function MessagingChannelsContent() { const params = useParams<{ search_space_id: string }>(); const searchSpaceId = Number(params.search_space_id); const whatsappMode = process.env.NEXT_PUBLIC_GATEWAY_WHATSAPP_INTAKE_MODE ?? "disabled"; + const slackGatewayEnabled = process.env.NEXT_PUBLIC_GATEWAY_SLACK_ENABLED === "true"; const [bindings, setBindings] = useState([]); const [platforms, setPlatforms] = useState([]); const [pairing, setPairing] = useState(null); @@ -96,6 +98,17 @@ export function MessagingChannelsContent() { await refresh(); } + async function installSlackGateway() { + const res = await authenticatedFetch( + `${BACKEND_URL}/api/v1/gateway/slack/install?search_space_id=${searchSpaceId}` + ); + if (!res.ok) return; + const data = (await res.json()) as { auth_url?: string }; + if (data.auth_url) { + window.location.href = data.auth_url; + } + } + function refreshBaileys() { startTransition(async () => { await refreshBaileysHealth(); @@ -119,8 +132,13 @@ export function MessagingChannelsContent() { const telegram = platforms.find((p) => p.platform === "telegram"); const whatsapp = platforms.find((p) => p.platform === "whatsapp"); + const slack = platforms.find((p) => p.platform === "slack"); const baileysQr = baileysHealth?.qr || null; - const activeBindings = bindings.filter((binding) => binding.search_space_id === searchSpaceId); + const activeBindings = bindings.filter( + (binding) => + binding.search_space_id === searchSpaceId && + binding.external_metadata?.kind !== "slack_thread" + ); const renderPairingPanel = (platform: PairingPlatform) => { if (!pairing || pairingPlatform !== platform) return null; @@ -170,6 +188,40 @@ export function MessagingChannelsContent() { + {slackGatewayEnabled ? ( + + +
+ + + Slack Bot + + + {slack ? "enabled" : "not enabled"} + +
+

+ Enable the SurfSense Slack bot so teammates can mention it in Slack. This is separate + from the Slack search connector. +

+
+ +
+ + +
+

+ Slack search remains controlled by the Slack connector in the connector popup. +

+
+
+ ) : null} + {whatsappMode !== "disabled" ? (