# Respond To Slack Thread

> Post a reply to a Slack thread. Use when the user asks to reply to, respond to, or follow up on a Slack thread. Handles fetching thread context and posting a reply.

- Skill: `warpdotdev/respond-to-slack-thread` (Agent Skill)
- Install (CLI): `npx skillmds@latest add warpdotdev/respond-to-slack-thread`
- Raw SKILL.md: https://api.skillmd.com/api/skills/warpdotdev/respond-to-slack-thread/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: warpdotdev (https://skillmd.com/u/warpdotdev)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/warpdotdev/respond-to-slack-thread

---


# respond-to-slack-thread

Post a reply to an existing Slack thread. Requires `$SLACK_BOT_TOKEN` with `channels:history`, `channels:read`, and `chat:write` OAuth scopes.

## Step 1: Clarify inputs

Before proceeding, ensure you have:

- **Channel ID**: The Slack channel ID (e.g. `C0123456789`). If the user gave a channel name, resolve it in Step 2.
- **Thread timestamp (`thread_ts`)**: The `ts` of the parent message (e.g. `1234567890.123456`).
  - If the user provided a Slack message link (e.g. `https://yourworkspace.slack.com/archives/C0123456789/p1234567890123456`), parse it:
    - Channel ID = the segment after `/archives/` (e.g. `C0123456789`)
    - `thread_ts` = the `p`-prefixed value at the end, with a decimal inserted 6 characters from the right (e.g. `p1234567890123456` → `1234567890.123456`)
- **Reply content**: What to say. If not provided, fetch the thread context (Step 3) and draft a reply based on it.

If `$SLACK_BOT_TOKEN` is not set, ask the user for it before proceeding.

## Step 2: Resolve channel ID (if needed)

If you only have the channel name:

```bash
curl -s -H "Authorization: Bearer $SLACK_BOT_TOKEN" \
  "https://slack.com/api/conversations.list?types=public_channel,private_channel&limit=200" | \
  jq -r '.channels[] | select(.name == "<channel_name>") | .id'
```

If the list is paginated, follow the `response_metadata.next_cursor` value.

## Step 3: Fetch thread context

Read the existing thread to understand the conversation before composing a reply:

```bash
curl -s -H "Authorization: Bearer $SLACK_BOT_TOKEN" \
  "https://slack.com/api/conversations.replies?channel=<CHANNEL_ID>&ts=<THREAD_TS>" | \
  jq '.messages[] | {user, ts, text, attachments}'
```

Review all messages to understand what has already been said before drafting your response.

## Step 4: Resolve user info (if needed)

To @mention someone by email:

```bash
curl -s -H "Authorization: Bearer $SLACK_BOT_TOKEN" \
  "https://slack.com/api/users.lookupByEmail?email=<email>" | \
  jq -r '.user.id'
```

Use the resulting ID as `<@USER_ID>` in the message text.

## Step 5: Post the reply

```bash
curl -s -X POST \
  -H "Authorization: Bearer $SLACK_BOT_TOKEN" \
  -H "Content-Type: application/json" \
  --data "{
    \"channel\": \"<CHANNEL_ID>\",
    \"thread_ts\": \"<THREAD_TS>\",
    \"text\": \"<MESSAGE_TEXT>\"
  }" \
  "https://slack.com/api/chat.postMessage" | jq '{ok, ts, error}'
```

For multi-line messages, use `$'...'` ANSI-C quoting so `\n` is interpreted as real newlines:

```bash
MESSAGE=$'First line\n\nSecond line'
curl -s -X POST \
  -H "Authorization: Bearer $SLACK_BOT_TOKEN" \
  -H "Content-Type: application/json" \
  --data "$(jq -n --arg channel "<CHANNEL_ID>" --arg thread_ts "<THREAD_TS>" --arg text "$MESSAGE" \
    '{channel: $channel, thread_ts: $thread_ts, text: $text}')" \
  "https://slack.com/api/chat.postMessage" | jq '{ok, ts, error}'
```

### Slack mrkdwn formatting

Slack uses its own mrkdwn syntax — do NOT use standard Markdown:

| Intent | Slack mrkdwn |
|---|---|
| @mention user | `<@USER_ID>` |
| Hyperlink | `<https://example.com\|link text>` |
| Bold | `*bold*` |
| Italic | `_italic_` |
| Strikethrough | `~strikethrough~` |
| Code (inline) | `` `code` `` |
| Code block | ` ```code block``` ` |

## Step 6: Confirm

After posting, share the reply's permalink with the user:

```bash
curl -s -H "Authorization: Bearer $SLACK_BOT_TOKEN" \
  "https://slack.com/api/chat.getPermalink?channel=<CHANNEL_ID>&message_ts=<REPLY_TS>" | \
  jq -r '.permalink'
```

## Notes

- If the API returns `ok: false`, check the `error` field and handle it — common errors include `not_in_channel` (bot must be invited to the channel) and `missing_scope` (token lacks required permissions).
- To post as the bot's configured name/icon rather than a user, ensure the token is a bot token (starts with `xoxb-`).
- If `thread_ts` is omitted, the message posts as a new top-level message rather than a reply.

