

How to Create Monday.com Tasks from Slack with n8n
When a teammate reacts with a specific emoji to any Slack message, n8n captures the message text, sender, and channel, then creates a Monday.com task with that context automatically.
Steps and UI details are based on platform versions at time of writing — check each platform for the latest interface.
Best for
Teams already using Monday.com for task tracking who want to capture action items directly from Slack without switching apps or copy-pasting.
Not ideal for
Teams who need two-way sync — if Monday.com task updates should post back to Slack, this one-way setup needs a second workflow.
Sync type
real-timeUse case type
routingReal-World Example
A 22-person product team at a B2B SaaS company reacts with a ✅ emoji whenever a Slack message contains a customer request or bug report. Before this workflow, someone had to manually copy the message into Monday.com — it happened maybe 60% of the time, and context got lost in translation. Now every ✅ reaction creates a Monday.com task in the 'Backlog' group with the original message text, the Slack channel name, and the message author pre-filled as the task description.
What Will This Cost?
Drag the slider to your expected monthly volume.
Each platform counts differently — Zapier: 1 task per trigger. Make: 1 operation per module per record. n8n: 1 execution per run.





Prices shown for annual billing. Based on published pricing as of April 2026.
Estimated ROI
1000
min saved/mo
$583
labor value/mo
Free
no platform cost
Based on ~2 min manual effort per operation at $35/hr fully loaded labor cost.
Implementation
Import this workflow directly into n8n
Copy the pre-built n8n blueprint and paste it straight into n8n. All modules, filters, and field mappings are already configured — you just need to connect your accounts.
Before You Start
Make sure you have everything ready.
Field Mapping
Map these fields between your apps.
| Field | API Name | |
|---|---|---|
| Required | ||
| Task Name | name | |
7 optional fields▸ show
| Description / Long Text Column | long_text |
| Status Column | status |
| Assignee (People Column) | people |
| Slack Channel | text |
| Slack Message Link | link |
| Reacting User | text |
| Creation Date | date |
Step-by-Step Setup
api.slack.com/apps > Your App > Event Subscriptions
Create a Slack App and configure the Event Subscriptions webhook
Go to api.slack.com/apps and click 'Create New App', then choose 'From Scratch'. Name it something like 'n8n Task Bot' and select your workspace. Navigate to 'Event Subscriptions' in the left sidebar and toggle 'Enable Events' on. You'll need to paste your n8n webhook URL here — set up the n8n node first (Step 2) and come back to complete this.
- 1Go to api.slack.com/apps and click 'Create New App'
- 2Choose 'From Scratch', enter app name, select your workspace
- 3Click 'Event Subscriptions' in the left sidebar
- 4Toggle 'Enable Events' to On
- 5Leave the Request URL field blank — you'll fill this in after Step 2
This Code node runs after the IF filter and before the Slack API call. It extracts and normalizes all fields from the raw reaction_added webhook payload — message timestamp, channel ID, reacting user, and item type — and prepares a clean object for the downstream nodes. Paste it into a Code node set to 'Run Once for Each Item' mode, placed between the IF node's true branch and the HTTP Request node.
JavaScript — Code Node// n8n Code Node: Extract and normalize Slack reaction_added payload▸ Show code
// n8n Code Node: Extract and normalize Slack reaction_added payload // Place between: IF node (true branch) → this Code node → HTTP Request (conversations.history) const body = $input.item.json.body;
... expand to see full code
// n8n Code Node: Extract and normalize Slack reaction_added payload
// Place between: IF node (true branch) → this Code node → HTTP Request (conversations.history)
const body = $input.item.json.body;
const event = body.event;
// Validate we have what we need before going further
if (!event || event.type !== 'reaction_added') {
throw new Error(`Unexpected event type: ${event?.type}. Check your Slack event subscription.`);
}
if (!event.item || event.item.type !== 'message') {
// Reactions on files or app messages — skip gracefully
return [{ json: { skip: true, reason: 'Reaction was not on a message item', eventType: event.item?.type } }];
}
// Extract core fields from the reaction event
const channelId = event.item.channel;
const messageTs = event.item.ts;
const reactingUserId = event.user; // Who reacted (the person flagging the task)
const originalAuthorId = event.item_user; // Who wrote the original message (potential assignee)
const reactionName = event.reaction; // e.g. 'white_check_mark'
const eventTs = event.event_ts; // When the reaction was added
// Build a Slack permalink manually (faster than calling chat.getPermalink)
const tsForUrl = messageTs.replace('.', '');
const slackPermalink = `https://slack.com/archives/${channelId}/p${tsForUrl}`;
// Format a human-readable timestamp for Monday.com
const reactionDate = new Date(parseFloat(eventTs) * 1000);
const formattedDate = reactionDate.toISOString().split('T')[0]; // YYYY-MM-DD
// Build the output object for downstream nodes
return [
{
json: {
channelId,
messageTs,
reactingUserId,
originalAuthorId: originalAuthorId || reactingUserId, // fallback if item_user missing
reactionName,
slackPermalink,
formattedDate,
skip: false,
// Passed to conversations.history call:
historyParams: {
channel: channelId,
latest: messageTs,
limit: 1,
inclusive: 'true'
}
}
}
];n8n Canvas > + Node > Webhook
Add a Webhook trigger node in n8n
Open your n8n instance and create a new workflow. Click the '+' button to add the first node and search for 'Webhook'. Select the Webhook node and set the HTTP Method to POST. Copy the 'Test URL' shown — this is what you'll paste into Slack in the next step. Keep the Response Mode as 'Immediately' and set the Response Code to 200.
- 1Click the '+' button on the blank canvas
- 2Search for 'Webhook' and select it
- 3Set HTTP Method to POST
- 4Set Response Mode to 'Immediately'
- 5Copy the 'Test URL' from the node panel
api.slack.com/apps > Event Subscriptions > Subscribe to Bot Events
Paste the webhook URL into Slack and subscribe to reaction_added events
Go back to your Slack app's Event Subscriptions page and paste the n8n Test URL into the Request URL field. Slack will immediately send a challenge request — your n8n webhook needs to be active (click 'Listen for Test Events' in n8n first) to respond. Once Slack shows a green 'Verified' badge, scroll down to 'Subscribe to Bot Events' and add 'reaction_added'. Save your changes.
- 1In n8n, click 'Test Workflow' to start listening on the test URL
- 2Paste the n8n Test URL into Slack's Request URL field
- 3Wait for the green 'Verified' checkmark to appear
- 4Click 'Add Bot User Event' and search for 'reaction_added'
- 5Select 'reaction_added' and click 'Save Changes'
api.slack.com/apps > OAuth & Permissions > Bot Token Scopes
Install the Slack app to your workspace and add it to target channels
In your Slack app settings, go to 'OAuth & Permissions' in the left sidebar. Under 'Bot Token Scopes', add the scopes: reactions:read, channels:history, channels:read, and users:read. Click 'Install App to Workspace' and authorize it. Once installed, copy the Bot User OAuth Token — you'll need it in Step 7. Then go into each Slack channel you want to monitor and type /invite @n8n-task-bot.
- 1Click 'OAuth & Permissions' in the left sidebar
- 2Under 'Bot Token Scopes', click 'Add an OAuth Scope'
- 3Add: reactions:read, channels:history, channels:read, users:read
- 4Click 'Install App to Workspace' and click 'Allow'
- 5Copy the 'Bot User OAuth Token' (starts with xoxb-)
channel: {{channel}}
ts: {{ts}}
n8n Canvas > + Node > IF
Add an IF node to filter for your chosen emoji only
Not every reaction should create a Monday.com task — only your designated trigger emoji (e.g., ✅ or 📌). Add an IF node after the Webhook node. Set the condition to check Value 1 as '{{$json.body.event.reaction}}' and Value 2 as the emoji name without colons — for ✅ use 'white_check_mark'. Only the True branch continues to task creation.
- 1Click '+' after the Webhook node and search for 'IF'
- 2Set Condition to 'String'
- 3Set Value 1 to expression: {{$json.body.event.reaction}}
- 4Set Operation to 'Equal'
- 5Set Value 2 to: white_check_mark (no colons, no emoji character)
n8n Canvas > + Node > Code
Add a Code node to extract and format message context
The reaction_added event payload contains the message timestamp and channel ID, but not the actual message text or the sender's name. Add a Code node after the IF node's true branch to restructure the data. This node will format the task name, pull the channel ID, and prepare all fields for Monday.com. Paste the JavaScript from the Pro Tip section into this node.
- 1Click '+' on the true branch of the IF node
- 2Search for 'Code' and select it
- 3Set Mode to 'Run Once for Each Item'
- 4Paste the pro tip code into the code editor
- 5Click 'Test Step' to verify output looks correct
This Code node runs after the IF filter and before the Slack API call. It extracts and normalizes all fields from the raw reaction_added webhook payload — message timestamp, channel ID, reacting user, and item type — and prepares a clean object for the downstream nodes. Paste it into a Code node set to 'Run Once for Each Item' mode, placed between the IF node's true branch and the HTTP Request node.
JavaScript — Code Node// n8n Code Node: Extract and normalize Slack reaction_added payload▸ Show code
// n8n Code Node: Extract and normalize Slack reaction_added payload // Place between: IF node (true branch) → this Code node → HTTP Request (conversations.history) const body = $input.item.json.body;
... expand to see full code
// n8n Code Node: Extract and normalize Slack reaction_added payload
// Place between: IF node (true branch) → this Code node → HTTP Request (conversations.history)
const body = $input.item.json.body;
const event = body.event;
// Validate we have what we need before going further
if (!event || event.type !== 'reaction_added') {
throw new Error(`Unexpected event type: ${event?.type}. Check your Slack event subscription.`);
}
if (!event.item || event.item.type !== 'message') {
// Reactions on files or app messages — skip gracefully
return [{ json: { skip: true, reason: 'Reaction was not on a message item', eventType: event.item?.type } }];
}
// Extract core fields from the reaction event
const channelId = event.item.channel;
const messageTs = event.item.ts;
const reactingUserId = event.user; // Who reacted (the person flagging the task)
const originalAuthorId = event.item_user; // Who wrote the original message (potential assignee)
const reactionName = event.reaction; // e.g. 'white_check_mark'
const eventTs = event.event_ts; // When the reaction was added
// Build a Slack permalink manually (faster than calling chat.getPermalink)
const tsForUrl = messageTs.replace('.', '');
const slackPermalink = `https://slack.com/archives/${channelId}/p${tsForUrl}`;
// Format a human-readable timestamp for Monday.com
const reactionDate = new Date(parseFloat(eventTs) * 1000);
const formattedDate = reactionDate.toISOString().split('T')[0]; // YYYY-MM-DD
// Build the output object for downstream nodes
return [
{
json: {
channelId,
messageTs,
reactingUserId,
originalAuthorId: originalAuthorId || reactingUserId, // fallback if item_user missing
reactionName,
slackPermalink,
formattedDate,
skip: false,
// Passed to conversations.history call:
historyParams: {
channel: channelId,
latest: messageTs,
limit: 1,
inclusive: 'true'
}
}
}
];n8n Canvas > + Node > HTTP Request
Add a Slack node to fetch the original message text
The reaction event only gives you the message timestamp — not the text. Add a Slack node after the Code node and set the operation to 'Get Permalink' or use the HTTP Request node to call conversations.history with the channel ID and timestamp. Use your Bot Token from Step 4. This fetches the actual message text so your Monday.com task has meaningful content, not just a timestamp.
- 1Click '+' after the Code node and search for 'HTTP Request'
- 2Set Method to GET
- 3Set URL to: https://slack.com/api/conversations.history
- 4Add Header: Authorization = Bearer xoxb-your-token
- 5Add Query Parameters: channel = {{$json.channelId}}, latest = {{$json.originalMessageTs}}, limit = 1, inclusive = true
Monday.com > Avatar > Developers > My Access Tokens
Connect Monday.com credentials in n8n
Add a Monday.com node after the HTTP Request node. In n8n, click 'Create New Credential' for Monday.com and select 'API Token'. Get your API token from Monday.com by clicking your avatar in the bottom left, selecting 'Developers', then 'My Access Tokens', and clicking 'Copy'. Paste it into n8n and save the credential.
- 1In Monday.com, click your avatar in the bottom-left corner
- 2Select 'Developers' from the menu
- 3Click 'My Access Tokens' then 'Show' next to your token
- 4Copy the token
- 5In n8n, paste it into the Monday.com credential field and click 'Save'
n8n Canvas > Monday.com Node > Create Item
Configure the Monday.com node to create the task
Set the Monday.com node Operation to 'Create Item'. Select your target board from the Board dropdown — n8n fetches your boards automatically. Set the Group to your preferred group (e.g., 'Backlog' or 'Inbox'). Set the Item Name to an expression pointing to the message text. Map additional column values like Status, Description, and Assignee using the Column Values field with Monday.com's column IDs.
- 1Set Resource to 'Item' and Operation to 'Create'
- 2Select your target Board from the dropdown
- 3Select the target Group (e.g., 'Backlog')
- 4Set Item Name to expression: {{$node['HTTP Request'].json.messages[0].text.slice(0, 80)}}
- 5Add Column Values for status, description, and assignee fields
n8n Canvas > Workflow Toggle (top right)
Activate the workflow and switch to the production webhook URL
Before activating, go back to Step 2 and note the 'Production URL' — it's different from the Test URL. In your Slack app's Event Subscriptions page, replace the Test URL with the Production URL. Then in n8n, click the toggle in the top right to activate the workflow. The workflow now runs on live events without you clicking 'Test'.
- 1Copy the Production URL from the Webhook node (not the Test URL)
- 2Go back to api.slack.com/apps > Event Subscriptions
- 3Replace the Test URL with the Production URL
- 4Click 'Save Changes' in Slack
- 5Click the activation toggle in n8n's top right corner
n8n > Executions > Latest Run
Test end-to-end and check execution logs
React to any message in your monitored Slack channel with the trigger emoji. Switch to n8n and click 'Executions' in the left sidebar to see the run. Each node should show green. Click into any node to see the exact data it processed. If Monday.com received the item, go to your board and confirm the task appears in the right group with the correct name and description.
- 1React to a Slack message with your trigger emoji (e.g., ✅)
- 2In n8n, click 'Executions' in the left sidebar
- 3Click the latest execution entry
- 4Click each node to inspect input/output data
- 5Go to your Monday.com board and confirm the task was created
Going live
Production Checklist
Before you turn this on for real, confirm each item.
Troubleshooting
Common errors and how to fix them.
Frequently Asked Questions
Common questions about this workflow.
Analysis
Use n8n for this if your team self-hosts and wants full control over the Slack token, message data, and where tasks land. The Code node advantage is real here — parsing the reaction_added payload, resolving user IDs, and formatting Monday.com column values cleanly takes about 20 lines of JavaScript that you'd otherwise hack together with five separate transformation nodes. n8n also lets you add conditional routing (different boards for different channels) without paying per task. The one case where I'd pick something else: if you're a non-technical team and nobody wants to touch JavaScript, Make handles this workflow with zero code and a friendlier UI.
Cost math: each Slack reaction triggers one workflow execution in n8n. One execution touches five nodes (Webhook, IF, Code, HTTP Request, Monday.com). On n8n Cloud's Starter plan at $20/month, you get 2,500 executions/month — that's 2,500 tasks created from Slack reactions. At that rate, cost is effectively $0.008 per task. Self-hosted n8n costs only your server fees, making this workflow free at any volume. Monday.com's API has no per-call cost. Slack's API is free for this use case. Total monthly cost for a 30-person team creating ~200 tasks/month via Slack reactions: $20 on n8n Cloud, or ~$5-10 server costs self-hosted.
Make handles the Slack 'Watch Events' trigger natively without building a custom app — it's genuinely easier to set up for non-developers and takes about half the time. Zapier has a 'New Reaction Added' trigger that works with zero webhook configuration, but it polls every 5-15 minutes instead of firing instantly, so your tasks appear with a lag. Power Automate has no native Slack connector worth using — you'd end up on a third-party connector with limited event support. Pipedream's Slack source is excellent and fires in under 2 seconds, with built-in user resolution helpers, but costs $19/month for always-on sources. n8n wins on cost and flexibility, Make wins on setup speed, Pipedream wins on Slack-specific features.
Three things you'll hit post-launch. First, Slack's reaction_added event includes item_user (the message author) only sometimes — if the message is older than a few days or in certain channel types, that field is missing and your assignee mapping breaks. Add a fallback. Second, Monday.com's people column expects an integer user ID, not an email or name — you need to call Monday.com's users query once to build a lookup table, or your assignee field will always be empty. Third, if your n8n instance goes down for maintenance and someone reacts during that window, the event is lost permanently — Slack doesn't retry failed webhook deliveries. Set up n8n's built-in error alerting and consider a short downtime window policy for the team.
Ideas for what to build next
- →Post a Slack confirmation when the task is created — Add a Slack node at the end of the workflow to reply in the thread of the reacted message with a link to the new Monday.com item. This closes the loop so the person who reacted knows the task was captured.
- →Map Slack users to Monday.com users automatically — Add an HTTP Request node that calls Slack's users.info API to get the reacting user's email, then queries Monday.com's users API to find the matching Monday.com user ID. This makes the Assignee field accurate instead of blank.
- →Route tasks to different Monday.com boards by channel — Add a Switch node after the Code node that checks the channelId and sends tasks from #engineering to a 'Tech Backlog' board, #marketing to a 'Campaigns' board, and so on. One workflow handles all channels without duplicating the setup.
Related guides
How to Create Notion Tasks from Slack with Pipedream
~15 min setup
How to Create Notion Tasks from Slack with Power Automate
~15 min setup
How to Create Notion Tasks from Slack with n8n
~20 min setup
How to Create Notion Tasks from Slack Messages with Zapier
~8 min setup
How to Create Notion Tasks from Slack Messages with Make
~12 min setup
How to Share Notion Meeting Notes to Slack with Pipedream
~15 min setup