Claude
Skills
Sign in
Back

egghead-slack

Included with Lifetime
$97 forever

Joel's private egghead.io Slack integration — channel taxonomy, token config, passive monitoring, and message intelligence pipeline.

Productivityslackeggheadchannelsintelligence

What this skill does


# egghead Slack Intelligence

Joel's private intelligence layer over the egghead.io Slack workspace. **Joel-only** — never participates in channels, never replies to anyone but Joel, never surfaces private data publicly.

## Tokens

Three tokens in agent-secrets (values unchanged across scope updates):

| Secret | Type | Purpose |
|--------|------|---------|
| `slack_bot_token` | `xoxb-*` | Bot: Socket Mode, send DMs to Joel, reactions |
| `slack_app_token` | `xapp-*` | Socket Mode WebSocket connection |
| `slack_user_token` | `xoxp-*` | User: read all channels, DMs, files, search |

### User Token Scopes (current)
`admin`, `identify`, `channels:history`, `channels:read`, `groups:history`, `groups:read`, `im:history`, `im:read`, `mpim:history`, `users:read`, `users:read.email`, `chat:write`, `canvases:read`, `canvases:write`, `files:read`, `search:read`, `search:read.public`, `search:read.private`, `search:read.mpim`, `search:read.im`, `search:read.files`, `search:read.users`

### Bot Token Scopes
`files:read`, `files:write`, `remote_files:read`, `remote_files:share`, `remote_files:write`, `search:read.files`, `users.profile:read`, `chat:write`, `channels:history`, `channels:read`, `groups:history`, `groups:read`, `im:history`, `im:read`, `mpim:history`, `reactions:write`, `app_mentions:read`, `connections:write`

## Workspace IDs

All Slack IDs stored here (private skill, NOT in any git repo):
- **Workspace**: egghead.io (`T030CS0QL`)
- **Joel user**: `U030BJ3CK`
- **Bot user**: `U0AGRUMQXPF` (joelclaw bot)
- **Joel DM channel**: `D0AHPM2NPJL`

## VIP DM Channels

| Person | User ID | DM Channel | Notes |
|--------|---------|------------|-------|
| Kent C. Dodds | `U030CU0CN` | `D030BJ3D1` | MEGA instructor, EpicWeb |
| Grzegorz Róg | `U03G1P81FBJ` | `D098ZQELPLM` | Slack Connect, MEGA producer |
| Matt Pocock | `U0211NP2ZN1` | (lookup needed) | Total TypeScript, AI Hero |
| John Lindquist | `U030CS0R0` | (lookup needed) | egghead cofounder, Script Kit |

22 external Slack Connect DMs total. Notable external users discovered:
Tony Holdstock-Brown, Antonio Erdeljac, Sean Grove, Dave Kiss, Charly Poly, Matthew Rathbone, Janelle Allen, Justin Gordon

## Channel Taxonomy

729 channels total. Canonical ID→name mapping: `~/Vault/Resources/slack/channels.json` (729 entries, pulled 2026-02-26).

Prefix-based auto-categorization:

| Prefix | Category | Count (approx) | Description |
|--------|----------|-----------------|-------------|
| `lc-*` | Launch Control | ~50 | Course launch channels |
| `cc-*` | Creator Channel | ~200 | 1:1 with creators/instructors |
| `dd-*` | Ding Ding | ~15 | Revenue reporting (mostly noise) |
| `brain-*` | Brain | 3 | Team thinking/strategy spaces |
| `project-*` | Projects | ~15 | Active project channels |
| `*-chat` | Legacy | many | Legacy individual chats |
| `sp-*` | Sales/Partner | few | Sales partner channels |
| `pm-*` | Product Mgmt | few | Product management |
| `skill-*` | Skill | few | Skill Recordings ops |
| `egghead-*` | egghead Ops | several | Various egghead channels |

### Priority Channels (ADR-0131)

**High** (cc-*/lc-* with Contact materialization):
- `cc-matt-p` (`C0211NSK3TP`) — Matt Pocock
- `cc-john` (`G70JH2Y7P`) — John Lindquist  
- `cc-ashley-hindle` — active
- `cc-alex-hillman` — active
- `epic-instructors` (`C06P7TD6VMM`) — **Private, 14 members.** Kent, Artem, and other Epic Web instructors. Workshop app features, video pipeline, course-builder updates.
- `cc-kcd` (`G01NK427ZE2`) — **Private.** Kent C. Dodds creator channel (NOT lc-just-javascript)
- `cc-artem-zakharchenko` (`C044J7QEDRA`) — **Private, 11 members.** Artem's creator channel
- `lc-total-typescript` (`C03JWTULTN0`) — **Private, 10 members.** Matt's course
- `lc-ai-hero` (`C07CURG8YB1`) — **Private, 9 members.** Matt's AI platform
- `lc-course-builder` (`C06KP859BUM`) — **Private, 11 members.** Course builder tool
- `lc-badass` (`C02PXV4BR61`) — **Private, 12 members.** Badass Courses
- `lc-epic-web` (`C03QFFWHT7D`) — **Private, 11 members.** Epic Web launch

**Medium** (project-*/brain-*/skill-*):
- `brain-john` (`C0A2ZA94M0V`) — **Public, 6 members.** Strategy with John
- `brain-joel` (`C09LKT871PE`) — **Public, 8 members.** Joel's strategy space
- `project-support-agent` (`C0ACP6SDN73`) — **Public, 8 members.** Support agent project
- `project-gremlin` (`C0AE33HH9C3`) — **Public, 8 members.** Gremlin project
- `skill-life` (`C04JPQS5ZUZ`) — **Private, 9 members.** Skill Recordings ops

**Low/noise** (dd-*/sp-*/legacy):
- `dd-*` — revenue signals, topic-only extraction
- `*-chat` — legacy, rarely active

## API Patterns

### Search messages
```bash
SLACK_USER=$(secrets lease slack_user_token --ttl 1h)
curl -s "https://slack.com/api/search.messages?query=QUERY&count=20&sort=timestamp&sort_dir=desc" \
  -H "Authorization: Bearer $SLACK_USER"
```

### List DM channels
```bash
curl -s "https://slack.com/api/conversations.list?types=im&limit=500" \
  -H "Authorization: Bearer $SLACK_USER"
```

### Read DM history
```bash
curl -s "https://slack.com/api/conversations.history?channel=DM_CHANNEL_ID&limit=30" \
  -H "Authorization: Bearer $SLACK_USER"
```

### Download files
```bash
curl -s -L -o output.file \
  -H "Authorization: Bearer $SLACK_USER" \
  "URL_PRIVATE_DOWNLOAD"
```
Requires `files:read` scope on user token.

### Send DM to Joel (bot token)
```bash
SLACK_BOT=$(secrets lease slack_bot_token --ttl 1h)
curl -s -X POST https://slack.com/api/chat.postMessage \
  -H "Authorization: Bearer $SLACK_BOT" \
  -H 'Content-Type: application/json' \
  -d '{"channel":"U030BJ3CK","text":"message"}'
```

### Upload file (3-step)
`files.getUploadURLExternal` → POST multipart → `files.completeUploadExternal`

### Resolve external user (Slack Connect)
```bash
curl -s "https://slack.com/api/users.info?user=EXTERNAL_USER_ID" \
  -H "Authorization: Bearer $SLACK_USER"
```

## Backfill Pipeline

Inngest functions (deployed, registered on the **host worker**):
- `slack-channel-backfill` — per-channel paginated history → Typesense `slack_messages`
- `slack-backfill-batch` — fan-out orchestrator for multiple channels
- Events: `channel/slack.backfill.requested`, `channel/slack.backfill.batch.requested`
- Flow control: concurrency 2, throttle 10/60s, 1.5s sleep between pages
- Runtime reason: host worker is required because the function leases `slack_user_token` through local `secrets`; do not move to k8s cluster worker unless token leasing is replaced with a cluster-safe adapter.
- Freshness gotcha: `conversations.history` only discovers thread parents inside the requested window. The function also expands `reply_count > 0` parents with `conversations.replies` and runs a bounded `search.messages in:<channel> after:<date>` pass so active replies on old threads are indexed too.
- Repair canary (2026-04-29): 9-channel 24h backfill indexed 43 current Slack messages into `slack_messages` after the search fallback landed.

## Realtime Important-Channel Intelligence

The live gateway no longer treats Slack as Joel-only for selected important channels. It still invokes only on Joel DMs, bot mentions, and tracked mention threads, but configured important channels now collect every non-bot message as passive intelligence.

Runtime config lives in private startup state:

- `~/.joelclaw/scripts/gateway-start.sh`
- `SLACK_IMPORTANT_CHANNEL_IDS` — comma-separated list of high/medium channel IDs from this skill
- optional `SLACK_IMPORTANT_CHANNEL_NAMES` fallback for local/dev use

Behavior:

- important-channel messages from anyone are indexed through `channel/message.received`
- important-channel messages are queued as `slack.signal.received` with `passiveIntel: true` and `importantChannel: true`
- Joel-authored messages also carry `joelSignal: true`
- relay policy batches ordinary channel chatter and escalates only on stronger multi-signal score
- if Redis is down, non-Joel important-channel messages remain index-only instead of direct-enqueuing the gateway sessio
Files: 1
Size: 9.3 KB
Complexity: 17/100
Category: Productivity

Related in Productivity