Slack Bot
Ask ZenSearch questions directly from Slack. The bot responds in-thread with cited answers, source references, and follow-up suggestions.
The Slack bot is separate from the Slack data connector. The connector indexes your Slack messages for search. The bot lets you query ZenSearch from within Slack.
Using the Bot
Mention in a Channel
Mention the bot in any channel it's been added to:
@ZenSearch how do I configure SSO?
The bot responds in a thread with:
- A cited answer based on your indexed knowledge
- Source references (up to 5)
- Follow-up suggestion buttons
Direct Message
Send a DM to the bot — no @ mention needed:
What data sources are supported?
Slash Command
Use the slash command for a private response visible only to you:
/zensearch what are the API rate limits?
Slash command responses are ephemeral (private). Follow-up suggestions are not available in ephemeral mode — use @ mentions or DMs for interactive conversations.
Conversations
The bot maintains conversation context within a Slack thread. Follow-up questions in the same thread use previous context for better answers.
- Thread scope: Each Slack thread maps to a ZenSearch conversation
- Session duration: 24 hours of inactivity starts a new conversation
- Cross-platform: Conversations started in Slack can be continued in the web app
Follow-up Suggestions
After each answer, the bot may suggest related questions as clickable buttons. Clicking a suggestion posts a new message in the same thread.
Work Object Previews (Unfurl + Flexpane)
When a ZenSearch-indexed URL appears in Slack — either pasted by a user or rendered as a citation in an agent answer — Slack shows a rich preview card below the message. Clicking the card opens a per-viewer flexpane (right-side detail panel) with full document content if the viewer has permission to see it.
What renders in the unfurl card (broadcast-safe)
The unfurl card is visible to every member of the channel, so it intentionally shows only metadata that's safe to broadcast:
- Document title
- Source system (Confluence, Jira, Notion, GitHub, Salesforce, etc.)
- Last-modified timestamp ("Updated 3 days ago")
- A View in ZenSearch deep link
The card never shows document body, snippet, or summary content — those are per-viewer and live in the flexpane.
What renders in the flexpane (per-viewer)
Clicking the unfurl opens the flexpane on the right side of Slack. ZenSearch resolves the viewer's Slack identity to their ZenSearch user and renders one of four states:
| State | What the viewer sees |
|---|---|
| Linked + permitted | Title + source + freshness + category + summary + action buttons |
| Linked + denied | "You don't have access to this document. Ask the owner to share it." |
| Unlinked | "Link your account" CTA — DM the bot once or sign in to ZenSearch to auto-link |
| Document removed | "This document isn't available in ZenSearch anymore." |
Two-key safety gate
A document only unfurls when both conditions are met:
- Its collection has
allow_slack_unfurl = true(admin opt-in, default off) - It has an "anyone-can-access" permission row from the source system (broadcast-safe)
Either gate alone is insufficient — a misconfigured upstream "shared with anyone" doesn't accidentally broadcast titles to whole Slack workspaces.
Agent citations
The same pipeline applies to citations the agent emits in its DM/thread answers. Each cited source URL becomes a clickable Work Object card with the same flexpane behavior — so a Confluence link cited in an agent answer is just as flexpane-clickable as one a user pastes.
Agent Approvals
When an agent action in a Slack conversation requires policy approval, the bot posts an approval card in the originating thread with Approve and Deny buttons.
- Only team Admins and Owners can approve or deny
- The card updates to show who took action and the decision
- Approved actions resume automatically; denied actions stop the agent
Delegated delegate_to_human approvals use the same approval system, but their proactive Slack notification is a direct message to the resolved approver when the workspace and user identity are linked. They also remain available from the Governance dashboard.
Setup (Admin)
Prerequisites
- A Slack workspace where you have admin permissions
- A ZenSearch team with data sources configured
1. Create a Slack App
- Go to api.slack.com/apps and click Create New App > From scratch
- Name it (e.g., "ZenSearch") and select your workspace
Bot Token Scopes
Under OAuth & Permissions > Scopes > Bot Token Scopes, add:
| Scope | Purpose |
|---|---|
app_mentions:read | Respond to @mentions |
chat:write | Post messages |
channels:history | Read channel messages (for thread follow-ups) |
groups:history | Read private channel messages |
im:history | Read DM messages |
mpim:history | Read group DM messages |
users:read | Read user profiles |
users:read.email | Read user emails (for automatic identity matching) |
commands | Handle slash commands |
links:read | Receive link_shared events for ZenSearch-indexed URLs (Work Object previews) |
links:write | Render unfurl cards via chat.unfurl (Work Object previews) |
OAuth Redirect URL
Under OAuth & Permissions > Redirect URLs, add:
https://YOUR_API_DOMAIN/api/v1/integrations/slack/auth/callback
Event Subscriptions
Under Event Subscriptions, enable events and set the request URL to:
https://YOUR_API_DOMAIN/api/v1/surfaces/slack/events
Subscribe to these bot events:
app_mention— Respond to @mentionsmessage.im— Respond to DMsmessage.channels— Thread follow-ups in channelsmessage.groups— Thread follow-ups in private channelslink_shared— Render Work Object unfurl cards for ZenSearch-indexed URLsentity_details_requested— Open per-viewer flexpane when a user clicks an unfurl
Under App unfurl domains, add the patterns ZenSearch can route to a document:
*.atlassian.net *.notion.so docs.google.com drive.google.com
*.sharepoint.com *.zendesk.com service-now.com *.salesforce.com
*.hubspot.com github.com
Add any customer-owned domains for connectors you index (web crawler, Confluence Data Center, self-hosted Jira, etc.).
Interactivity
Under Interactivity & Shortcuts, enable and set the request URL to:
https://YOUR_API_DOMAIN/api/v1/surfaces/slack/interactions
Slash Commands (Optional)
Under Slash Commands, create a /zensearch command pointing to:
https://YOUR_API_DOMAIN/api/v1/surfaces/slack/commands
Work Object Previews
Under Features > Work Object Previews, toggle the feature on, then click Add entity type and register:
slack#/entities/file
This is the entity_type our app sends in entity.presentDetails responses. Without it, Slack ignores entity_details_requested events and the flexpane stays dark even though unfurls still render.
Per-collection opt-in
Work Object unfurls are off-by-default per collection. After connecting a Slack workspace, enable unfurls on the collections that should participate:
UPDATE collections SET allow_slack_unfurl = true WHERE id = '<collection-uuid>';
A dedicated admin UI toggle is on the roadmap.
2. Configure ZenSearch
Set these environment variables on the core-api service:
| Variable | Description |
|---|---|
SLACK_SIGNING_SECRET | From your Slack app's Basic Information page |
SLACK_CLIENT_ID | From Basic Information > App Credentials |
SLACK_CLIENT_SECRET | From Basic Information > App Credentials |
SLACK_BOT_ENABLED | Set to true to enable the bot |
SLACK_OAUTH_REDIRECT_URL | https://YOUR_API_DOMAIN/api/v1/integrations/slack/auth/callback |
Restart the core-api service after setting these values.
3. Connect the Workspace
- Go to Settings > Integrations > Slack in the ZenSearch web app
- Click Add to Slack
- Authorize the app in the Slack popup
- The workspace appears as connected
4. User Identity Linking
ZenSearch automatically matches Slack users to ZenSearch accounts by email on first message (using the users:read.email scope). No manual setup is needed if user emails match.
If automatic matching fails, users can be linked manually via the identity links API:
curl -X POST https://YOUR_API_DOMAIN/api/v1/identity-links \
-H "Authorization: Bearer <token>" \
-d '{
"platform": "slack",
"external_user_id": "U1234ABCD",
"external_team_id": "T1234ABCD",
"user_id": "<zensearch-user-uuid>",
"team_id": "<zensearch-team-uuid>"
}'
Users without a linked identity (and no matching email) will see: "Your identity is not linked to ZenSearch. Ask your admin to link your account."
Troubleshooting
Bot Not Responding
- Verify
SLACK_BOT_ENABLED=trueis set - Check that the bot is added to the channel
- Verify the Events API URL is reachable from Slack
- Check core-api logs for errors
Identity Not Linked
- Ensure the Slack user has a verified email that matches their ZenSearch account
- Or create an explicit identity link via the API
"Still processing your previous message..."
- The bot processes one message per thread at a time
- Wait for the current response to complete before sending another