Portal Community

channel/open

Opens or creates a Direct Message (DM) or Multi-Party IM (MPIM) conversation. Provide userIds to initiate a new DM/MPIM, or provide channelId to reopen a previously closed conversation. Returns the channel ID needed for message/send. Requires im:write scope.

When to Use

Configuration

Connection

FieldTypeRequiredDescription
botTokenstringRequiredBot Token starting with xoxb-. Requires im:write scope for DMs and mpim:write for multi-party IMs.

Operation Fields

FieldTypeRequiredDescription
channelIdstringOptionalExisting DM/MPIM channel ID to reopen (starts with D for DMs, G for MPIMs). Provide this OR userIds, not both.
userIdsstringOptionalComma-separated Slack user IDs to open a new DM or MPIM with. A single ID opens a DM; two or more IDs open an MPIM. Provide this OR channelId, not both.
channelId vs userIds: Provide either channelId (to reopen an existing DM) or userIds (to open a new DM/MPIM) — never both. Opening a DM with a user ID that already has a DM is idempotent and returns the existing DM channel ID.

Sample Configuration

// Open a new DM with a single user
{
  "operation": "channel/open",
  "connection": {
    "botToken": "{{credentials.slackBotToken}}"
  },
  "fields": {
    "userIds": "{{$json.userId}}"
  }
}

// Open a multi-party DM
{
  "operation": "channel/open",
  "fields": {
    "userIds": "{{$json.userIds.join(',')}}"
  }
}

Validation Errors

Error CodeCauseResolution
user_not_foundOne of the user IDs does not exist or is deactivated.Validate user IDs with user/get before opening. Filter out deactivated users.
missing_scopeBot token lacks im:write (DM) or mpim:write (MPIM) scope.Re-authorize the Slack app with the required scopes.
channel_not_foundThe channelId provided does not correspond to a DM/MPIM accessible to this bot.Verify the channel ID. DM channel IDs start with D; MPIM with G.

Output

Success Port

FieldTypeDescription
channelIdstringThe DM or MPIM channel ID. Pass this directly to message/send to deliver the message.
statusstringsuccess or error.
errorCodestringSlack error code when status is error.
payloadobjectFull raw Slack API response including channel details.

Error Port

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

Sample Output

{
  "channelId": "D08DM3XYZ99",
  "status": "success",
  "errorCode": "",
  "payload": {
    "ok": true,
    "channel": {
      "id": "D08DM3XYZ99",
      "is_im": true,
      "user": "U01USER12345"
    },
    "already_open": true
  }
}

Expression Reference

ExpressionResult
{{$node["channel-open"].json.channelId}}DM channel ID — pass directly to message/send as the channelId.
{{$node["channel-open"].json.payload.already_open}}True if this DM was already open — use to skip a "starting a conversation" notification if resuming.
{{$node["channel-open"].json.status === "success"}}Boolean gate — confirm open before sending message.

Node Policies & GuardRails

Policy AreaRecommendation
Scope requirementsRequires im:write for single DMs and mpim:write for multi-party IMs. Add im:read and mpim:read for reading these conversations.
Rate limitingTier 2 (20+ req/min). For bulk DM campaigns (e.g., sending to 100+ users), add delays between open+send pairs to avoid rate limits.
No hard-coded IDsAlways source userId and channelId dynamically. Never hard-code user or channel IDs.
Idempotent opensOpening a DM that already exists returns the existing channel ID. This is safe to call every time before sending — no need to cache DM IDs between workflow runs.
User consent considerationAutomated DMs can feel intrusive. Reserve direct messages for genuinely important, personalized communications. Avoid bulk unsolicited DMs.
Archive vs. closeUse channel/close to clean up DMs after use. DMs cannot be archived — they can only be closed (hidden from the sidebar).

Examples

Example 1 — Onboarding Welcome DM

When a new employee's Slack account is created, open a DM and send a welcome message with onboarding links.

// Node 1: channel/open
{ "userIds": "{{$json.newEmployeeSlackId}}" }

// Node 2: message/send
{
  "channelId": "{{$node['channel-open'].json.channelId}}",
  "text": "Welcome to the team, {{$json.firstName}}! Here are your onboarding resources: {{$json.onboardingUrl}}"
}

Example 2 — Support Ticket Resolution DM

When a support ticket is resolved, opens a DM with the requester to confirm resolution.

// Trigger: ticket status changed to "Resolved"
// $json.requesterSlackId, $json.ticketId, $json.resolutionNotes

// Node 1: channel/open
{ "userIds": "{{$json.requesterSlackId}}" }

// Node 2: message/send
{
  "channelId": "{{$node['channel-open'].json.channelId}}",
  "text": "Your support ticket #{{$json.ticketId}} has been resolved. Summary: {{$json.resolutionNotes}}"
}

// Node 3: channel/close — clean up after resolution
{ "channelId": "{{$node['channel-open'].json.channelId}}" }

Example 3 — Multi-Party Incident Coordination DM

When a critical incident fires, opens a group DM with the on-call engineer and their manager for immediate coordination.

// $json.onCallEngineerId, $json.managerId, $json.incidentId

// channel/open with multiple users
{
  "userIds": "{{[$json.onCallEngineerId, $json.managerId].join(',')}}"
}

// message/send to the returned channelId
{
  "text": "INCIDENT {{$json.incidentId}} requires immediate attention. Please coordinate here."
}