Portal Community

channel/getHistory

Retrieves the message history of a Slack channel, with optional time-range filters using Unix timestamps. Supports full pagination for compliance exports or bounded retrieval for recent-message analysis. 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 Slack channel ID (starts with C for public, G for private). Example: C08AB3XYZ12.
returnAllbooleanOptionalWhen true, paginates through all messages in the specified time range. Default: true.
limitintegerOptionalMaximum messages to return when returnAll is false. Default: 100. Max: 1000.
oldeststringOptionalStart of time range as Unix timestamp (float). Only returns messages after this time. Example: 1716700000.000000.
lateststringOptionalEnd of time range as Unix timestamp (float). Only returns messages before this time. Defaults to current time.
Timestamp Format: Slack uses Unix epoch timestamps with microsecond precision (e.g., 1716729600.000000). To get the timestamp for "24 hours ago" use: {{(Date.now() / 1000 - 86400).toString()}}

Sample Configuration

{
  "operation": "channel/getHistory",
  "connection": {
    "botToken": "{{credentials.slackBotToken}}"
  },
  "fields": {
    "channelId": "{{$json.channelId}}",
    "returnAll": false,
    "limit": 100,
    "oldest": "{{(Date.now() / 1000 - 86400).toString()}}",
    "latest": "{{(Date.now() / 1000).toString()}}"
  }
}

Validation Errors

Error CodeCauseResolution
channel_not_foundThe channel ID is invalid or the bot is not a member of the private channel.Verify the channel ID. For private channels, join the channel first using channel/join.
missing_scopeBot token lacks channels:history or groups:history scope.Re-authorize the Slack app with the required history scopes.
not_in_channelThe bot is not a member of the requested channel.Use channel/join to add the bot to the channel before reading its history.

Output

Success Port

FieldTypeDescription
messageCountnumberNumber of messages returned in this response.
messagesarrayArray of message objects. Each contains: messageTs, channel, userId, text, permalink.
nextCursorstringPagination cursor for next page. Empty when all results 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. Common cause: bot not in channel — handle by routing to a channel/join node first.

Sample Output

{
  "messageCount": 3,
  "messages": [
    {
      "messageTs": "1716729600.001200",
      "channel": "C08AB3XYZ12",
      "userId": "U01USER12345",
      "text": "Deployment to production completed successfully.",
      "permalink": "https://yourworkspace.slack.com/archives/C08AB3XYZ12/p1716729600001200"
    },
    {
      "messageTs": "1716729500.000900",
      "channel": "C08AB3XYZ12",
      "userId": "U01USER67890",
      "text": "Starting deployment pipeline for v2.4.1",
      "permalink": "https://yourworkspace.slack.com/archives/C08AB3XYZ12/p1716729500000900"
    }
  ],
  "nextCursor": "",
  "status": "success",
  "errorCode": "",
  "payload": { "ok": true, "messages": [ ... ], "has_more": false }
}

Expression Reference

ExpressionResult
{{$node["channel-gethistory"].json.messageCount}}Total messages returned — use as loop bound or report metric.
{{$node["channel-gethistory"].json.messages}}Full message array — pass to AI summarization or compliance export node.
{{$node["channel-gethistory"].json.messages[0].text}}Text of the most recent message.
{{$node["channel-gethistory"].json.messages.map(m => m.text).join('\n')}}All message texts joined — useful as input to an AI summarization prompt.
{{(Date.now() / 1000 - 86400).toString()}}Unix timestamp for 24 hours ago — use as the oldest parameter.

Node Policies & GuardRails

Policy AreaRecommendation
Scope requirementsRequires channels:history for public channels and groups:history for private channels. The bot must also be a member of the channel.
Rate limitingTier 3 (50+ req/min). History retrieval can generate many paginated requests on busy channels — always bound the time range with oldest and latest for production workflows.
No hard-coded IDsAlways pass channelId dynamically. Never hard-code channel IDs in configuration.
Time-range boundingAlways set oldest for production runs. Unbounded returnAll on a busy channel can return tens of thousands of messages, consuming significant memory and time.
Privacy considerationMessage history contains user-generated content. Ensure downstream storage and processing complies with your organization's data retention and privacy policies.
Archive accessYou can retrieve history from archived channels. The bot must have been a member when messages were sent, or have admin-level access.

Examples

Example 1 — Daily Compliance Archive Export

Scheduled nightly workflow that exports the previous day's messages from all regulated channels to a compliance database.

// Runs at 00:05 daily
// Calculates yesterday's time window
const yesterdayStart = (new Date().setHours(0,0,0,0) / 1000 - 86400).toString();
const yesterdayEnd   = (new Date().setHours(0,0,0,0) / 1000).toString();

{
  "operation": "channel/getHistory",
  "fields": {
    "channelId": "{{$json.channelId}}",
    "returnAll": true,
    "oldest": yesterdayStart,
    "latest": yesterdayEnd
  }
}
// Next: HTTP Request node → POST to compliance archive API

Example 2 — AI-Powered Daily Standup Summary

Pulls the last 24 hours of standup messages and sends them to an LLM for summarization, then posts the summary to a digest channel.

{
  "operation": "channel/getHistory",
  "fields": {
    "channelId": "C08STANDUP01",
    "returnAll": false,
    "limit": 50,
    "oldest": "{{(Date.now() / 1000 - 86400).toString()}}"
  }
}
// Code node: format messages as LLM prompt
const messages = $node["channel-gethistory"].json.messages
  .map(m => `${m.userId}: ${m.text}`).join('\n');
// AI node → summarize → message/send to #standup-digest

Example 3 — Post-Incident Message Replay

After a monitoring outage, retrieves all messages from the incident window to reconstruct the timeline.

{
  "operation": "channel/getHistory",
  "fields": {
    "channelId": "C08INCIDENTS",
    "returnAll": true,
    "oldest": "{{$json.incidentStartTs}}",
    "latest": "{{$json.incidentEndTs}}"
  }
}
// Output: ordered message list for incident post-mortem report