Ask from Slack
Wire a `/ask` slash command to a public knowledge pack, so your team gets a cited answer without leaving Slack.
Scenario: Acme published a support handbook as a public knowledge pack. Instead of sending teammates the link, Acme wires a /ask slash command in their Slack workspace: type /ask what is our refund window?, get a cited answer back in the channel.
How it fits together
/ask answers from the mapped public pack only. Routing to a workspace's private search based on the calling Slack user's identity is not built — there's no Slack-user-to-workspace-member linking in Protobox yet. Every /ask in a connected Slack team gets the same pack-scoped answer, regardless of who asks.
1. Create the Slack app
Create a Slack app from the manifest checked into this repo at infra/slack/protobox-ask.manifest.json (api.slack.com/apps → Create New App → From an app manifest). It declares the /ask slash command pointed at https://platform.protobox.ai/api/v1/integrations/slack/ask and the minimal commands bot scope — no other scope is needed, because Protobox answers synchronously in the same HTTP response Slack's request gets (no chat:write, no response_url callback).
Install the app to your Slack workspace, then copy its Signing Secret (Basic Information → App Credentials) into the SLACK_SIGNING_SECRET Doppler secret for platform-server.
2. Connect your workspace's Slack team
Find your Slack team id (Slack client → workspace name → About → Team ID, or https://slack.com/api/team.info with a user token), then map it to a published pack:
curl -X PATCH https://platform.protobox.ai/api/v1/tools/integrations/slack/ask-mapping \
-H "x-api-key: $PROTOBOX_API_KEY" \
-H "x-workspace-id: $PROTOBOX_WORKSPACE_ID" \
-H "content-type: application/json" \
-d '{"teamId": "T0123ABCD", "packSlug": "acme-support-handbook"}'packSlug is the same slug you published the pack under (protobox kb publish <folderId> --slug ...). Pass "packSlug": null to disconnect a pack without unlinking the Slack team — /ask then replies with setup guidance instead of erroring.
Check the current mapping any time:
curl https://platform.protobox.ai/api/v1/tools/integrations/slack/ask-mapping \
-H "x-api-key: $PROTOBOX_API_KEY" \
-H "x-workspace-id: $PROTOBOX_WORKSPACE_ID"3. Ask
/ask what is our refund window?Slack posts the answer as a Block Kit message: the synthesized answer (or cited passages, on the free plan), up to three sources formatted Title › Heading, and a note when the workspace's plan doesn't support synthesis.
An unrecognized Slack team, or one connected but with no pack chosen, still gets a 200 — Slack requires a fast response — with an ephemeral (only-you-see-it) message explaining what to do next, instead of a silent failure.
Security
Every request is verified against Slack's request signing scheme: v0= HMAC-SHA256 of v0:<timestamp>:<raw body> using the signing secret, with a 5-minute replay window on the timestamp. A missing/invalid signature or a stale timestamp gets a 401 before any workspace data is touched.