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
Search Slack message history using Slack's Web API. Use this when you need to find past conversations or retrieve channel messages by calling search.messages or conversations.history endpoints with curl or WebFetch.
/plugin marketplace add ralphbean/claude-code-plugins/plugin install searching-slack-history@claude-code-pluginsThis skill inherits all available tools. When active, it can use any tool Claude has access to.
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)
search:read - Search messages across workspacechannels:history - Read public channel historychannels:read - List public channelsgroups:history - Read private channel history (if needed)groups:read - List private channels (if needed)xoxb-)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).
| 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 |
Security Note: Never echo commands containing tokens. Use silent execution to prevent token exposure in terminal output.
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 phrasefrom:@username - Messages from specific userin:#channel - Messages in specific channelafter:YYYY-MM-DD - Messages after datebefore:YYYY-MM-DD - Messages before dateExample with operators:
{
"query": "deployment after:2025-01-01 in:#engineering",
"count": 50
}
Rate limit: Tier 3 (20 requests/minute)
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).
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.
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.
Symptom: {"ok": false, "error": "missing_scope"}
Fix: Add required scopes in Slack App OAuth settings, then reinstall app to workspace.
Symptom: {"ok": false, "error": "channel_not_found"}
Fix: Call conversations.list first to map channel name → ID.
Symptom: Only getting first 20-100 results, missing older messages.
Fix: Check for response_metadata.next_cursor and make subsequent requests with cursor parameter.
Symptom: {"ok": false, "error": "rate_limited"} or HTTP 429
Fix: Implement exponential backoff. Wait time often provided in Retry-After header.
Symptom: Empty results or permission errors for private channels.
Fix:
groups:history and groups:read scopes/invite @YourBotNameRisk: Running curl with -H "Authorization: Bearer $SLACK_TOKEN" displays token in terminal output and shell history.
Fix:
-K /tmp/slack.curl) to hide token$SLACK_TOKEN.env to .gitignore if storing tokens in filesSuccessful 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"
}
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