Portal Community

channel/getReplies

Retrieves all reply messages in a Slack message thread, identified by the parent message's timestamp. The first message in the response is always the parent (thread root). Requires channels:history scope.

When to Use

Configuration

Connection

FieldTypeRequiredDescription
botTokenstringRequiredBot Token starting with xoxb-. Requires channels:history (public) or groups:history (private) scopes.

Operation Fields

FieldTypeRequiredDescription
channelIdstringRequiredThe channel containing the parent message. Starts with C (public) or G (private).
threadTsstringRequiredTimestamp of the parent (root) message. This is the thread identifier. Example: 1716729600.001200.
returnAllbooleanOptionalWhen true, paginates through all replies. Default: true.
limitintegerOptionalMax replies to return when returnAll is false. Default: 100.
Thread Timestamp: The threadTs is the timestamp of the first (parent) message in the thread — not a reply. You can find it in the messageTs field from channel/getHistory output, or from a Slack event payload's thread_ts field.

Sample Configuration

{
  "operation": "channel/getReplies",
  "connection": {
    "botToken": "{{credentials.slackBotToken}}"
  },
  "fields": {
    "channelId": "{{$json.channelId}}",
    "threadTs": "{{$json.threadTs}}",
    "returnAll": true
  }
}

Validation Errors

Error CodeCauseResolution
channel_not_foundInvalid channel ID or bot not in private channel.Verify the channel ID. Join the channel with channel/join if needed.
thread_not_foundThe threadTs does not correspond to a known thread root in this channel.Verify the timestamp matches a parent message. Timestamps are exact — do not round or truncate them.
missing_scopeBot token lacks channels:history or groups:history scope.Re-authorize the Slack app with history scopes.

Output

Success Port

FieldTypeDescription
messageCountnumberTotal messages returned, including the parent message as the first item.
messagesarrayArray of message objects: messageTs, channel, userId, text, permalink. Index 0 is always the parent message.
nextCursorstringPagination cursor. Empty when all replies have been returned.
statusstringsuccess or error.
errorCodestringSlack error code when status is error.
payloadobjectFull raw Slack API response.

Error Port

On failure with Continue on Error enabled, routes to the error port with status: "error" and populated errorCode.

Sample Output

{
  "messageCount": 3,
  "messages": [
    {
      "messageTs": "1716729600.001200",
      "channel": "C08INCIDENTS",
      "userId": "U01ALERT99999",
      "text": "INCIDENT P1: Database connection pool exhausted — prod affected",
      "permalink": "https://yourworkspace.slack.com/archives/C08INCIDENTS/p1716729600001200"
    },
    {
      "messageTs": "1716729720.001300",
      "channel": "C08INCIDENTS",
      "userId": "U01USER12345",
      "text": "On it — investigating RDS connections now",
      "permalink": "https://yourworkspace.slack.com/archives/C08INCIDENTS/p1716729720001300"
    },
    {
      "messageTs": "1716730200.001400",
      "channel": "C08INCIDENTS",
      "userId": "U01USER12345",
      "text": "Resolved — connection pool limit increased to 500, all services healthy",
      "permalink": "https://yourworkspace.slack.com/archives/C08INCIDENTS/p1716730200001400"
    }
  ],
  "nextCursor": "",
  "status": "success",
  "errorCode": "",
  "payload": { "ok": true, "messages": [ ... ], "has_more": false }
}

Expression Reference

ExpressionResult
{{$node["channel-getreplies"].json.messageCount}}Total messages including parent — subtract 1 for reply count only.
{{$node["channel-getreplies"].json.messages[0].text}}Parent (root) message text — the thread-starting message.
{{$node["channel-getreplies"].json.messages.slice(1).map(m => m.text).join('\n')}}All reply texts joined — use as AI summarization input (excludes parent).
{{$node["channel-getreplies"].json.messages.at(-1).messageTs}}Timestamp of the last reply — use to calculate resolution time.
{{parseFloat($node["channel-getreplies"].json.messages.at(-1).messageTs) - parseFloat($json.threadTs)}}Thread duration in seconds from first to last message.

Node Policies & GuardRails

Policy AreaRecommendation
Scope requirementsRequires channels:history for public channels and groups:history for private channels. Bot must be a channel member.
Rate limitingTier 3 (50+ req/min). Safe for individual thread fetches. For bulk thread processing, add delays between calls to avoid rate limit errors.
No hard-coded IDsAlways source channelId and threadTs from upstream event data or expressions. Never hard-code timestamps.
Timestamp precisionSlack message timestamps are float strings with 6 decimal places. Never round or truncate them — doing so will result in thread_not_found errors.
Parent message inclusionThe first element of the messages array is always the parent message. Use .slice(1) to isolate replies when you only need the response content.
Privacy complianceThread content is user-generated data. Ensure any downstream AI processing or storage complies with data retention and privacy policies.

Examples

Example 1 — Incident Post-Mortem Thread Export

After an incident is resolved, collects the full thread and formats it for a post-mortem report document.

{
  "operation": "channel/getReplies",
  "fields": {
    "channelId": "C08INCIDENTS",
    "threadTs": "{{$json.incidentThreadTs}}",
    "returnAll": true
  }
}
// Code node: calculate resolution time
const messages = $node["channel-getreplies"].json.messages;
const durationSec = parseFloat(messages.at(-1).messageTs) - parseFloat(messages[0].messageTs);
const resolutionMinutes = Math.round(durationSec / 60);
return { messages, resolutionMinutes, replyCount: messages.length - 1 };

Example 2 — Approval Thread Audit Log

When a process approval completes, exports the approval discussion thread to the audit database.

// Triggered by approval-complete event
// $json.channelId = approval channel
// $json.approvalThreadTs = parent message timestamp

{
  "operation": "channel/getReplies",
  "fields": {
    "channelId": "{{$json.channelId}}",
    "threadTs": "{{$json.approvalThreadTs}}"
  }
}
// HTTP Request → POST thread to audit API endpoint

Example 3 — AI Thread Summary Digest

Daily workflow that summarizes all active incident threads and posts digests to the ops channel.

// For each open incident thread:
{
  "operation": "channel/getReplies",
  "fields": { "channelId": "C08INCIDENTS", "threadTs": "{{$json.threadTs}}" }
}
// Format replies for LLM:
const replies = $node["channel-getreplies"].json.messages.slice(1)
  .map(m => `${m.userId}: ${m.text}`).join('\n');
// AI node → summarize → message/send to #incidents-digest