Claude Code Plugins

Community-maintained marketplace

Feedback

searching-slack-history

@ralphbean/claude-code-plugins
0
0

Use when needing to search Slack message history, find past conversations, or retrieve channel messages - provides Slack Web API patterns for search.messages and conversations.history endpoints using WebFetch or curl

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name searching-slack-history
description Use when needing to search Slack message history, find past conversations, or retrieve channel messages - provides Slack Web API patterns for search.messages and conversations.history endpoints using WebFetch or curl

Searching Slack History

Overview

Search Slack message history using the Slack Web API.

Core principle: Use Slack's REST API endpoints with WebFetch or curl to search messages, retrieve channel history, and find past conversations.

Prerequisites: Slack Bot token with appropriate scopes (setup guide below)

Setup Guide (One-Time)

Creating a Slack Bot Token

  1. Visit https://api.slack.com/apps → Click "Create New App"
  2. Choose "From scratch"
  3. Name it (e.g., "Claude Search Bot")
  4. Select your workspace
  5. Navigate to "OAuth & Permissions" in sidebar
  6. Scroll to "Scopes" → "Bot Token Scopes"
  7. Add these scopes:
    • search:read - Search messages across workspace
    • channels:history - Read public channel history
    • channels:read - List public channels
    • groups:history - Read private channel history (if needed)
    • groups:read - List private channels (if needed)
  8. Click "Install to Workspace" at top of page
  9. Authorize the app
  10. Copy the "Bot User OAuth Token" (starts with xoxb-)
  11. Store securely as environment variable:
    export SLACK_TOKEN="xoxb-your-token-here"
    

Security: Never commit tokens to git. Use environment variables or secure credential storage.

Private channels: Bot must be invited to private channels before it can search them (/invite @YourBotName).

Quick Reference

Task Endpoint Key Parameters
Search all messages search.messages query, sort, count
Get channel history conversations.history channel, limit, oldest
Find channel ID conversations.list types, exclude_archived
Search by date range search.messages query with date operators

API Patterns

Security Note: Never echo commands containing tokens. Use silent execution to prevent token exposure in terminal output.

Search Messages Globally

Endpoint: POST https://slack.com/api/search.messages

Use case: Find messages across all channels the bot has access to.

Secure pattern (use this):

# Create curl command without echoing it
cat > /tmp/slack_search.sh << 'SCRIPT'
curl -s -X POST https://slack.com/api/search.messages \
  -H "Authorization: Bearer $SLACK_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "your search terms",
    "count": 20,
    "sort": "timestamp"
  }'
SCRIPT

# Execute without showing token in terminal
bash /tmp/slack_search.sh
rm /tmp/slack_search.sh

Alternative secure pattern:

# Use curl config file (doesn't appear in terminal/history)
cat > /tmp/slack.curl << EOF
header = "Authorization: Bearer $SLACK_TOKEN"
header = "Content-Type: application/json"
EOF

curl -s -K /tmp/slack.curl -X POST https://slack.com/api/search.messages \
  -d '{"query": "your search terms", "count": 20, "sort": "timestamp"}'

rm /tmp/slack.curl

Query operators:

  • "exact phrase" - Match exact phrase
  • from:@username - Messages from specific user
  • in:#channel - Messages in specific channel
  • after:YYYY-MM-DD - Messages after date
  • before:YYYY-MM-DD - Messages before date

Example with operators:

{
  "query": "deployment after:2025-01-01 in:#engineering",
  "count": 50
}

Rate limit: Tier 3 (20 requests/minute)

Get Channel History

Endpoint: POST https://slack.com/api/conversations.history

Use case: Retrieve recent messages from a specific channel.

Important: Requires channel ID, not channel name. Use conversations.list first if you only have the name.

Secure pattern:

# Use config file to hide token
cat > /tmp/slack.curl << EOF
header = "Authorization: Bearer $SLACK_TOKEN"
header = "Content-Type: application/json"
EOF

curl -s -K /tmp/slack.curl -X POST https://slack.com/api/conversations.history \
  -d '{"channel": "C1234567890", "limit": 100}'

rm /tmp/slack.curl

Time filtering:

{
  "channel": "C1234567890",
  "oldest": "1609459200.000000",
  "latest": "1640995200.000000",
  "limit": 100
}

Timestamps are Unix epoch time with microseconds (e.g., 1609459200.000000 = 2021-01-01).

Find Channel ID from Name

Endpoint: POST https://slack.com/api/conversations.list

Use case: Get channel ID when you only know the channel name.

Secure pattern:

cat > /tmp/slack.curl << EOF
header = "Authorization: Bearer $SLACK_TOKEN"
header = "Content-Type: application/json"
EOF

curl -s -K /tmp/slack.curl -X POST https://slack.com/api/conversations.list \
  -d '{"types": "public_channel,private_channel", "exclude_archived": true}'

rm /tmp/slack.curl

Filter response: Look for channel with matching name field, extract id.

Handling Pagination

All endpoints return paginated results. Check for response_metadata.next_cursor:

# Create reusable config (do this once)
cat > /tmp/slack.curl << EOF
header = "Authorization: Bearer $SLACK_TOKEN"
header = "Content-Type: application/json"
EOF

# First request
curl -s -K /tmp/slack.curl -X POST https://slack.com/api/search.messages \
  -d '{"query": "search", "cursor": ""}'

# If response contains "next_cursor": "dXNlcjpVMDYxTkZUVDI="
# Second request with cursor
curl -s -K /tmp/slack.curl -X POST https://slack.com/api/search.messages \
  -d '{"query": "search", "cursor": "dXNlcjpVMDYxTkZUVDI="}'

# Clean up when done
rm /tmp/slack.curl

Continue until next_cursor is empty or not present.

Common Mistakes

1. Missing Token Scopes

Symptom: {"ok": false, "error": "missing_scope"}

Fix: Add required scopes in Slack App OAuth settings, then reinstall app to workspace.

2. Using Channel Names Instead of IDs

Symptom: {"ok": false, "error": "channel_not_found"}

Fix: Call conversations.list first to map channel name → ID.

3. Ignoring Pagination

Symptom: Only getting first 20-100 results, missing older messages.

Fix: Check for response_metadata.next_cursor and make subsequent requests with cursor parameter.

4. Rate Limit Errors

Symptom: {"ok": false, "error": "rate_limited"} or HTTP 429

Fix: Implement exponential backoff. Wait time often provided in Retry-After header.

5. Private Channel Access

Symptom: Empty results or permission errors for private channels.

Fix:

  • Add groups:history and groups:read scopes
  • Invite bot to private channel: /invite @YourBotName

6. Token Exposure in Terminal

Risk: Running curl with -H "Authorization: Bearer $SLACK_TOKEN" displays token in terminal output and shell history.

Fix:

  • ALWAYS use curl config files (-K /tmp/slack.curl) to hide token
  • Create config file with headers, run curl referencing it, delete config after
  • Never echo commands containing $SLACK_TOKEN
  • Add .env to .gitignore if storing tokens in files
  • Rotate token immediately if exposed in logs or history

Response Format

Successful responses have "ok": true:

{
  "ok": true,
  "messages": {
    "matches": [
      {
        "type": "message",
        "user": "U1234567890",
        "text": "Message content",
        "ts": "1234567890.123456",
        "permalink": "https://workspace.slack.com/archives/...",
        "channel": {
          "id": "C1234567890",
          "name": "general"
        }
      }
    ],
    "total": 150
  },
  "response_metadata": {
    "next_cursor": "dXNlcjpVMDYxTkZUVDI="
  }
}

Error responses have "ok": false:

{
  "ok": false,
  "error": "invalid_auth"
}

Real-World Workflow

Scenario: Find all messages about "deployment" in #engineering from last week.

# 1. Create secure config file
cat > /tmp/slack.curl << EOF
header = "Authorization: Bearer $SLACK_TOKEN"
header = "Content-Type: application/json"
EOF

# 2. Get channel ID (pipe to jq to extract)
curl -s -K /tmp/slack.curl -X POST https://slack.com/api/conversations.list \
  -d '{"types": "public_channel"}' \
  | jq -r '.channels[] | select(.name=="engineering") | .id'
# Returns: C1234567890

# 3. Search messages with date filter
curl -s -K /tmp/slack.curl -X POST https://slack.com/api/search.messages \
  -d '{
    "query": "deployment in:#engineering after:2025-10-24",
    "count": 100,
    "sort": "timestamp"
  }'

# 4. Clean up config file
rm /tmp/slack.curl

Further Reading