← back to Claude Slack
README.md
42 lines
# claude-slack
Two-way Slack chat channel for Claude — the Slack sibling of `claude-mail`.
A launchd job polls configured channels every 10s, runs the local `claude` CLI
on any message addressed to the bot, and posts the reply **in-thread**.
- **Bot:** `dw_reports_bot` (`U0BC1PWB1SS`) in the Designerwallcoverings workspace.
- **Channels** (`SLACK_CHANNELS` in `.env`):
- `slack-steve` → `#claude-programming` (`C09QUHKM20L`), `requireMention:false` — your 1:1 line; every message gets answered.
- `slack-general` → `#general` (`C03T1SQNJBH`), `requireMention:true` — shared team channel; Claude only answers messages that say `claude …` / `@claude`.
## How it works
`poller.js` (one pass per launchd fire):
1. `auth.test` → resolve the bot's own user id (loop guard).
2. For each channel: `conversations.history` since a saved per-channel cursor.
On **first sight** of a channel the cursor is anchored to "now" — it never
replies to backlog.
3. `gate()` drops bot/own/system messages, off-allowlist authors, and (in
`requireMention` channels) anything not addressed to Claude.
4. `runClaude()` runs `claude -p` headless with Slack-tuned rails.
5. Reply posted with `chat.postMessage` + `thread_ts`.
`health.js` pages Steve (CNCP + macOS notification + George email — all
independent of the Slack token) after 3 consecutive failed passes, and again
when it recovers.
## Go-live blockers (one-time, Steve)
The bot token is currently **send-only**. To enable two-way chat:
1. **Add scopes** at api.slack.com → your app → OAuth & Permissions → Bot Token Scopes:
`channels:history` (public), `groups:history` (private), optionally `users:read`.
2. **Reinstall** the app to the workspace (re-issues the token). If the token
changes, re-run the secrets route so `~/.claude.json` + this `.env` update.
3. **Invite the bot** into each channel: `/invite @dw_reports_bot` in
`#claude-programming` and `#general` (reading history requires membership).
4. Verify: `node --env-file=.env probe.js` — every channel should read "OK".
5. Go live: `cp com.steve.claude-slack.plist ~/Library/LaunchAgents/ && \
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.steve.claude-slack.plist`
## Commands
- `npm run probe` — read-only auth + per-channel history/membership check.
- `npm run poll` — run one pass by hand.