Portal Community

channel/setTopic

Sets or updates the topic of a Slack channel. The topic is displayed prominently at the top of the channel and serves as a live status line. Ideal for dynamic status information that changes frequently. Requires channels:manage scope.

When to Use

Configuration

Connection

FieldTypeRequiredDescription
botTokenstringRequiredBot Token starting with xoxb-. Requires channels:manage scope.

Operation Fields

FieldTypeRequiredDescription
channelIdstringRequiredThe channel to update. Starts with C (public) or G (private).
topicstringRequiredThe new topic text. Max 250 characters. Supports basic Slack formatting: <URL|label>, @user, #channel.
Topic vs. Purpose: The topic is a live status line — update it frequently to reflect what is happening right now. The purpose is a stable description of what the channel is for. Use channel/setTopic for current-state information and channel/setPurpose for channel documentation.

Sample Configuration

{
  "operation": "channel/setTopic",
  "connection": {
    "botToken": "{{credentials.slackBotToken}}"
  },
  "fields": {
    "channelId": "{{$json.channelId}}",
    "topic": "{{$json.topic}}"
  }
}

Validation Errors

Error CodeCauseResolution
channel_not_foundInvalid channel ID or bot not in private channel.Verify the channel ID. For private channels, the bot must be a member.
missing_scopeBot token lacks channels:manage scope.Re-authorize the Slack app with the required scope.
is_archivedThe channel is archived.Unarchive the channel first, then update the topic.

Output

Success Port

FieldTypeDescription
channelIdstringThe channel that was updated.
topicstringThe new topic text as confirmed by Slack.
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

{
  "channelId": "C08INCIDENTS",
  "topic": "P1 ACTIVE | DB connection exhausted | Owner: @john | Status: Mitigating | Started: 14:32 UTC",
  "status": "success",
  "errorCode": "",
  "payload": {
    "ok": true,
    "topic": "P1 ACTIVE | DB connection exhausted | Owner: @john | Status: Mitigating | Started: 14:32 UTC"
  }
}

Expression Reference

ExpressionResult
{{$node["channel-settopic"].json.topic}}Confirmed new topic — use in audit logs.
{{'P' + $json.severity + ' ACTIVE | ' + $json.description + ' | Owner: @' + $json.ownerHandle}}Template for an incident channel topic with severity and owner.
{{'v' + $json.version + ' deployed to ' + $json.env + ' at ' + new Date().toUTCString()}}Template for a deployment status topic.
{{'Sprint ' + $json.sprintNumber + ': ' + $json.sprintGoal + ' | Ends: ' + $json.sprintEndDate}}Template for a sprint goal topic.

Node Policies & GuardRails

Policy AreaRecommendation
Scope requirementsRequires channels:manage scope for public channels. Private channels may need groups:write.
Rate limitingTier 2 (20+ req/min). For high-frequency topic updates (e.g., real-time status), debounce updates — send at most one update per 30 seconds to avoid flooding the channel with system messages.
No hard-coded IDsAlways source channelId from upstream expressions. Never hard-code channel IDs.
Topic length limitKeep topics under 250 characters. Use a template that prioritizes the most important fields (status, owner, time) and truncates secondary details.
Topic vs. purposeUse topic for dynamic, frequently-changing status. Use purpose for stable, descriptive documentation. Do not duplicate content between the two.
System message noiseEach topic update generates a system message in the channel ("Bot updated the channel topic"). For high-frequency updates, consider batching changes to reduce noise.

Examples

Example 1 — Incident Channel Topic with Live Status

When an incident fires or its status changes, updates the incident channel topic with current severity, status, and owner.

// Triggered by PagerDuty status change event
// $json.severity, $json.description, $json.ownerHandle, $json.status, $json.startedAt

{
  "operation": "channel/setTopic",
  "fields": {
    "channelId": "{{$json.incidentChannelId}}",
    "topic": "{{
      $json.severity + ' ' + $json.status.toUpperCase() +
      ' | ' + $json.description.substring(0, 80) +
      ' | Owner: @' + $json.ownerHandle +
      ' | Started: ' + $json.startedAt
    }}"
  }
}

Example 2 — Deployment Channel Post-Deploy Update

After a successful deployment pipeline completes, updates the deploy channel topic to reflect the current production version.

// Triggered by CI/CD pipeline success event
// $json.version, $json.environment, $json.deployedBy

{
  "operation": "channel/setTopic",
  "fields": {
    "channelId": "C08DEPLOYS01",
    "topic": "{{
      'PROD: v' + $json.version +
      ' | Deployed: ' + new Date().toUTCString() +
      ' | By: ' + $json.deployedBy
    }}"
  }
}

Example 3 — Weekly On-Call Rotation Update

Scheduled Monday morning workflow that updates the ops channel topic with the week's on-call engineer.

// HTTP Request → get on-call schedule for this week
// $json.oncallName, $json.oncallHandle, $json.weekEndDate

{
  "operation": "channel/setTopic",
  "fields": {
    "channelId": "C08OPSALERTS",
    "topic": "{{
      'On-call this week: @' + $json.oncallHandle +
      ' (' + $json.oncallName + ')' +
      ' | Rotation ends: ' + $json.weekEndDate +
      ' | PagerDuty: https://pagerduty.example.com/oncall'
    }}"
  }
}