Skip to content
Documentation Slack bot setup ▾

Install & self-host

Docs / Install & self-host / Slack bot setup

Set up your own Slack bot

Register a Slack app, connect it to your RecallHQ API through a tunnel, run the worker, and install it into a workspace.

Register and run locally

Complete the local backend setup first. You will also need cloudflared or another HTTPS tunnel.

  1. Create a disposable free workspace at slack.com/get-started.
  2. At api.slack.com/apps, choose Create New App → From scratch, name it RecallHQ, and select the workspace.
  3. Copy slack/env.example to .env.slack. From Basic Information → App Credentials, copy the client ID, client secret, and signing secret into it. Keep OPENAI_API_KEY in .env.
  4. Migrate the database, then start the API and a tunnel in separate terminals:
Shell
uv sync --locked
docker compose up -d db
uv run python -m recallhq.cli migrate

uv run uvicorn recallhq.api:app --host 127.0.0.1 --port 8001 --reload
cloudflared tunnel --url http://127.0.0.1:8001 --no-autoupdate
  1. With the HTTPS URL the tunnel prints, set the public URL and encryption key, generate the manifest, and start the worker:
Shell
uv run python -m recallhq.cli slack-init --base-url https://your-tunnel.trycloudflare.com
uv run python -m recallhq.cli slack-manifest --base-url https://your-tunnel.trycloudflare.com > manifest.json
uv run python -m recallhq.cli slack-worker
  1. Paste manifest.json into the app’s App Manifest page and save. It configures OAuth, events, interactivity, and /recall. Keep the API running so Slack can verify the request URL.
  2. Visit https://your-tunnel.trycloudflare.com/slack/install and authorize. Use this link even if you already installed from Slack’s dashboard: the OAuth callback is what stores the installation in your database.
  3. Invite @RecallHQ to a test channel, run /recall status, post a test fact, and ask about it with /recall ask.

Commands

CommandResult
/recall ask <question> [in:#channel]Grounded answer with source links
/recall search <terms> [in:#channel]Ranked message excerpts
/recall catchup YYYY-MM-DD YYYY-MM-DD [in:#channel]Recap updates, decisions, blockers, and next steps
/recall summarize <Slack-message-link>Summary of the indexed thread
/recall decisions [in:#channel]Explicit decisions from the last seven days
/recall statusChannels, message counts, history coverage, embedding backlog, errors
/recall sync #channelAdmin/owner: Retry a full history import
/recall forget #channelAdmin/owner: Confirm disabling ingestion and purging channel data
/recall helpUsage and access rules

Channel mentions are resolved to IDs. Searches default to all ingested channels the requester belongs to, including private channels. Results are private, and current membership is checked before retrieval and again before delivery. Full details are in the command reference.

Limits and what is imported

  • Default command limits: 5 per user per minute and 200 per workspace per UTC day (SLACK_USER_COMMANDS_PER_MINUTE, SLACK_WORKSPACE_COMMANDS_PER_DAY).
  • Commercially distributed apps outside the Marketplace get one conversations.history and one conversations.replies request per minute per workspace, with up to 15 messages per page. The defaults match that, and the scheduler honours Retry-After. Large imports take time.
  • Imported: channel text and thread replies, including text from other bots. Not imported: RecallHQ’s own output, system events, file contents, DMs, Slack Connect channels, and org-wide installs.

Production

Apply migrations as the schema owner before starting the new API and worker. The migration owner must be able to create the NOLOGIN roles recallhq_reader and recallhq_ingestor. Then grant them to separate runtime logins:

SQL
GRANT recallhq_reader TO your_query_login;
GRANT recallhq_ingestor TO your_slack_service_login;

Runtime logins must not be superusers, schema owners, or have BYPASSRLS. Set DATABASE_URL to the query login, DATABASE_WRITE_URL to the Slack service login, and DATABASE_MIGRATION_URL only when migrating. Keep Slack secrets and the encryption key in the server’s runtime environment file, outside the repository.

One image runs both the API and the worker:

Shell
docker build -t recallhq-slack .
docker run --rm --env-file /path/to/migration.env recallhq-slack python -m recallhq.cli migrate
# API container: default image command
# Worker container: python -m recallhq.cli slack-worker

# Or, locally after migrating:
docker compose --profile slack up -d --build api slack-worker

Keep the API behind a reverse proxy and the worker internal. Generate the manifest from the externally visible API base URL (including a path prefix such as /recallhq/api if the proxy strips it), and update the manifest and SLACK_PUBLIC_URL together.

Distribution

To install into workspaces other than the one where the app was created, enable Manage Distribution → Activate Public Distribution, complete Slack’s requirements, and share your hosted /slack/install link. Workspace admins may still need to approve it. Before a Marketplace submission, publish privacy and support pages that describe external model processing and deletion and backup behaviour.