AutomationFlowsSlack & Telegram › Slack Chat Router (example)

Slack Chat Router (example)

Slack chat router (example). Uses slackTrigger, slack. Event-driven trigger; 13 nodes.

Event trigger★★★★☆ complexity13 nodesSlack TriggerSlack
Slack & Telegram Trigger: Event Nodes: 13 Complexity: ★★★★☆ Added:

This workflow follows the Slack → Slack Trigger recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "name": "Slack chat router (example)",
  "nodes": [
    {
      "parameters": {
        "trigger": [
          "any_event",
          "message"
        ],
        "watchWorkspace": true,
        "options": {
          "resolveIds": false,
          "userIds": "={{ [\"U00000000BOT\"] }}"
        }
      },
      "type": "n8n-nodes-base.slackTrigger",
      "typeVersion": 1,
      "position": [
        -288,
        48
      ],
      "id": "a4fd7e45-2ec5-4588-8419-cdd0c787e0e6",
      "name": "Slack Trigger",
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.user === \"U00000000OWNER\" && $json.type === \"message\" }}",
                    "rightValue": "",
                    "operator": {
                      "type": "boolean",
                      "operation": "true",
                      "singleValue": true
                    },
                    "id": "69ac51ac-eef9-422a-846a-9d23760f7daa"
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Owner new message"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "id": "6be2d2be-bdfb-4487-9a6f-1b87abb452e8",
                    "leftValue": "={{ $json.user === \"U00000000OWNER\" && $json.type === \"reaction\" }}",
                    "rightValue": "",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Owner Added Reaction"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "id": "3726290c-15b6-4c60-9720-28b109b45859",
                    "leftValue": "={{ $json.user !== \"U00000000OWNER\" && $json.type === \"message\" }}",
                    "rightValue": "",
                    "operator": {
                      "type": "boolean",
                      "operation": "true",
                      "singleValue": true
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "unknown user"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.4,
      "position": [
        160,
        32
      ],
      "id": "fc990f48-cd17-43f1-b04b-a8036d67c370",
      "name": "Switch"
    },
    {
      "parameters": {
        "select": "user",
        "user": {
          "__rl": true,
          "value": "={{ $('Slack Trigger').item.json.user }}",
          "mode": "id"
        },
        "text": "={{ [\"Two atoms walk into a bar. One says 'I think I lost an electron.' The other replies, 'Are you sure?' 'I'm positive.'\",\"A neutron walks into a bar. The bartender says, 'For you, no charge.'\",\"Photons have mass? I didn't even know they were Catholic.\",\"I'd help you, but my owner has me on a strict no-stranger policy.\"][Math.floor(Math.random()*4)] }}\n\n_I'm a private AI assistant. I only respond to my owner._",
        "otherOptions": {
          "includeLinkToWorkflow": false,
          "thread_ts": {
            "replyValues": {
              "thread_ts": "={{ $('Slack Trigger').item.json.ts }}"
            }
          },
          "mrkdwn": true
        }
      },
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.4,
      "position": [
        528,
        304
      ],
      "id": "47bffa05-810e-4c70-bd3f-950b794e35d7",
      "name": "Send canned reply to non-owner",
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "workflowId": {
          "__rl": true,
          "value": "exampleAgentCoreWfId",
          "mode": "list",
          "cachedResultName": "Chat agent core"
        },
        "workflowInputs": {
          "mappingMode": "defineBelow",
          "value": {
            "chatInput": "={{ $('Slack Trigger').item.json.text }}",
            "threadId": "={{ $('Slack Trigger').item.json.thread_ts || $('Slack Trigger').item.json.ts }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "chatInput",
              "displayName": "chatInput",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "canBeUsedToMatch": true,
              "type": "string",
              "removed": false
            },
            {
              "id": "threadId",
              "displayName": "threadId",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "canBeUsedToMatch": true,
              "type": "string",
              "removed": false
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        },
        "options": {}
      },
      "type": "n8n-nodes-base.executeWorkflow",
      "typeVersion": 1.3,
      "position": [
        768,
        -208
      ],
      "id": "8f38246b-7810-4875-a6a0-6c0d90273ee2",
      "name": "Call 'Agent core'",
      "retryOnFail": true,
      "maxTries": 2,
      "waitBetweenTries": 5000,
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "select": "user",
        "user": {
          "__rl": true,
          "value": "={{ $('Slack Trigger').item.json.user }}",
          "mode": "id"
        },
        "messageType": "block",
        "blocksUi": "={{ { \"blocks\": $('Call \\'Agent core\\'').item.json.output.blocks } }}",
        "otherOptions": {
          "includeLinkToWorkflow": false,
          "thread_ts": {
            "replyValues": {
              "thread_ts": "={{ $('Slack Trigger').item.json.thread_ts || $('Slack Trigger').item.json.ts }}"
            }
          },
          "mrkdwn": false
        }
      },
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.4,
      "position": [
        1216,
        -208
      ],
      "id": "580cf92e-b198-4eec-988b-f232f7fa345a",
      "name": "Send Block Kit reply",
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "reaction",
        "channelId": {
          "__rl": true,
          "value": "={{ $json.channel }}",
          "mode": "id"
        },
        "timestamp": "={{ $json.ts }}",
        "name": "spinner"
      },
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.4,
      "position": [
        528,
        -208
      ],
      "id": "873145eb-46e1-4075-a7f8-10711447b94a",
      "name": "Add Loading Reaction",
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "reaction",
        "operation": "remove",
        "channelId": {
          "__rl": true,
          "value": "={{ $('Switch').item.json.channel }}",
          "mode": "id"
        },
        "timestamp": "={{ $('Switch').item.json.ts }}",
        "name": "spinner"
      },
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.4,
      "position": [
        992,
        -208
      ],
      "id": "ee481219-af13-4a1a-9363-2b15791f553d",
      "name": "Remove Loading Reaction (success)",
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "reaction",
        "operation": "remove",
        "channelId": {
          "__rl": true,
          "value": "={{ $('Switch').item.json.channel }}",
          "mode": "id"
        },
        "timestamp": "={{ $('Switch').item.json.ts }}",
        "name": "spinner"
      },
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.4,
      "position": [
        800,
        32
      ],
      "id": "e3cfba63-109f-4269-b5b2-1d9353a58167",
      "name": "Remove Loading Reaction (error)",
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "content": "### Anti-loop filter (trigger-level)\n\nThe Slack Trigger's `options.userIds` is an **exclusion list**: events from any user in the list are dropped before the workflow runs. Put the bot's own user ID here so the bot's replies don't re-trigger the workflow.\n\nWhen the trigger handles the bot filter, no separate Filter node is needed downstream.",
        "height": 336,
        "width": 240
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -336,
        -160
      ],
      "typeVersion": 1,
      "id": "64b85d5f-f0bc-4793-b7a3-88b9b0430118",
      "name": "Sticky: anti-loop"
    },
    {
      "parameters": {
        "content": "Switch routes by event type. Becomes a router for slash commands and shortcuts as new event types are added.",
        "height": 336,
        "width": 208
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        112,
        -112
      ],
      "typeVersion": 1,
      "id": "1b4b8495-b74d-4bba-b79e-51280f69fbeb",
      "name": "Sticky: switch"
    },
    {
      "parameters": {
        "content": "Loading reaction (added before agent, removed on both success and error paths).",
        "height": 336,
        "width": 208
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        480,
        -352
      ],
      "typeVersion": 1,
      "id": "5c88a0a2-c0d5-4e9d-99b5-6c979919f1ae",
      "name": "Sticky: loading reaction"
    },
    {
      "parameters": {
        "content": "### Block Kit envelope, NOT a raw array\n\n`blocksUi` must be an object shaped `{ \"blocks\": [...] }`, where the value is a real array, not just the blocks array on its own.\n\nThe agent returns `{ text, blocks }`, so wrap in a single expression that returns the object (reference the upstream by name, not `$json`):\n\n`={{ { \"blocks\": $('Call \\'Agent core\\'').item.json.output.blocks } }}`\n\nPassing only the array (`={{ $('Call \\'Agent core\\'').item.json.output.blocks }}`) silently fails: the Slack node accepts the input, the message posts with no rich content, and there is no error.",
        "height": 336,
        "width": 280
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1184,
        -560
      ],
      "typeVersion": 1,
      "id": "7b1c2d3e-4f5a-4b6c-9d8e-1f2a3b4c5d6e",
      "name": "Sticky: block kit envelope"
    },
    {
      "parameters": {
        "select": "user",
        "user": {
          "__rl": true,
          "value": "={{ $('Slack Trigger').item.json.user }}",
          "mode": "id"
        },
        "text": "=There was a workflow error. https://<your-n8n-host>/workflow/<this-workflow-id>/executions/{{ $execution.id }}",
        "otherOptions": {
          "includeLinkToWorkflow": false,
          "thread_ts": {
            "replyValues": {
              "thread_ts": "={{ $('Slack Trigger').item.json.thread_ts || $('Slack Trigger').item.json.ts }}"
            }
          },
          "mrkdwn": false
        }
      },
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.4,
      "position": [
        1024,
        32
      ],
      "id": "2267a068-bf1a-48cf-9316-61ad1063c17b",
      "name": "Send error message with execution link",
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Slack Trigger": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "Add Loading Reaction",
            "type": "main",
            "index": 0
          }
        ],
        [],
        [
          {
            "node": "Send canned reply to non-owner",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Call 'Agent core'": {
      "main": [
        [
          {
            "node": "Remove Loading Reaction (success)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Remove Loading Reaction (error)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add Loading Reaction": {
      "main": [
        [
          {
            "node": "Call 'Agent core'",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Remove Loading Reaction (success)": {
      "main": [
        [
          {
            "node": "Send Block Kit reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Remove Loading Reaction (error)": {
      "main": [
        [
          {
            "node": "Send error message with execution link",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Slack chat router (example). Uses slackTrigger, slack. Event-driven trigger; 13 nodes.

Source: https://github.com/n8n-io/skills/blob/main/skills/n8n-agents/references/examples/slack-router.json — original creator credit. Request a take-down →

More Slack & Telegram workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Slack & Telegram

Vendorbot Form Filler. Uses executeCommand, gmail, telegram, slack. Event-driven trigger; 39 nodes.

Execute Command, Gmail, Telegram +6
Slack & Telegram

Type in Slack. Walk away. Get a professional PDF report and a structured Excel fix sheet delivered to Google Drive and posted back in your Slack thread — fully automated, zero manual work.

Compression, HTTP Request, Google Drive +3
Slack & Telegram

This workflow automates the full company enrichment pipeline: Simply import CSV company lists to Slack and save time on enrichment and CRM maintenance. It processes uploaded files, extracts company do

Slack Trigger, Slack, HTTP Request +3
Slack & Telegram

This workflow enables seamless, bidirectional communication between WhatsApp and Slack using n8n. It automates the reception, processing, and forwarding of messages (text, media, and documents) betwee

WhatsApp Trigger, Slack, Slack Trigger +2
Slack & Telegram

Automatically convert structured Slack messages into Jira issues with parsed titles, descriptions, and priorities. This workflow also downloads file attachments from Slack (e.g., screenshots, logs, or

Slack Trigger, Jira, Slack +1