Slack
Introduction
The Slack connector handles direct messages with the owner and threaded conversations in any channel where the bot has been mentioned. It uses Slack's Events API.
Webhook Authentication
Every request to /slack/webhook is verified by the VerifySlackSignature middleware before any Laraclaw code touches it. The middleware:
- Reads
X-Slack-Request-TimestampandX-Slack-Signaturefrom the request headers. Missing either header returns 403. - Rejects any request whose timestamp is more than 300 seconds (5 minutes) off from the server clock — this is Slack's recommended replay window.
- Computes
v0=hash_hmac('sha256', "v0:{timestamp}:{body}", $signingSecret)and compares it to the supplied signature withhash_equals(timing-safe).
If the signing secret is wrong or missing, every Slack webhook will 403. There is no fallback path. Make sure LARACLAW_SLACK_SIGNING_SECRET is set in production.
Setup
Create a Slack app at api.slack.com/apps and add the following bot token scopes:
chat:writereactions:addfiles:readfiles:writeim:writeim:historychannels:history
Then run:
php artisan laraclaw:setup-connector slack
The wizard asks for the bot token, signing secret, bot user ID, and your Slack user ID, and writes:
LARACLAW_SLACK_ENABLED=true
LARACLAW_SLACK_BOT_TOKEN=xoxb-...
LARACLAW_SLACK_SIGNING_SECRET=...
LARACLAW_SLACK_BOT_USER_ID=U...
In your Slack app settings, point the Event Subscriptions request URL at:
https://your-app.com/slack/webhook
Subscribe to the following bot events:
message.channelsmessage.im
Direct Messages
Slack DMs have a channel ID starting with D. Only the registered owner may DM the bot. Each DM is one persistent conversation, keyed by the user's Slack ID. Replies don't thread.
Channels and Threads
In channels, the bot only responds when:
- It's
@mentionedin the message, or - The message is a reply in a thread the bot has already participated in.
Each channel conversation is keyed by channel:thread_ts, so every thread has its own context. Replies are always posted back into the same thread.
Attachments
Inbound files are downloaded with the bot token and saved to inbound/{message_uuid}/. Outbound files go through Slack's external upload flow: files.getUploadURLExternal, then a POST to the signed URL, then files.completeUploadExternal.
Confirmation Flow
Confirmation prompts are stored in Redis. When the user replies in the same thread, their answer is parsed as the response and the tool either runs or is cancelled.