

How to Assign Todoist Tasks from Slack Mentions with Pipedream
Automatically creates a Todoist task assigned to the right person whenever they're mentioned in a specific Slack channel, pulling channel context into the task content.
Steps and UI details are based on platform versions at time of writing — check each platform for the latest interface.
Best for
Dev or ops teams who use dedicated project channels in Slack and need mentions to become tracked, assigned tasks without copy-pasting between tools.
Not ideal for
Teams who need bidirectional sync or want to update existing Todoist tasks from Slack — this only creates new tasks.
Sync type
real-timeUse case type
routingReal-World Example
A 12-person product team at a SaaS company uses dedicated Slack channels per sprint (#sprint-42, #sprint-43). When a PM types '@sarah fix the onboarding modal bug' in #sprint-42, a Todoist task appears in the Sprint 42 project, assigned to Sarah, with the channel name and message permalink attached. Before this, task assignment happened in stand-up the next morning — a full day of lag on average.
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 Pipedream
Copy the pre-built Pipedream blueprint and paste it straight into Pipedream. 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 Content | content | |
| Project ID | project_id | |
| Assignee ID | assignee_id | |
5 optional fields▸ show
| Description | description |
| Due Date | due_string |
| Priority | priority |
| Labels | label_ids |
| Source Channel Name |
Step-by-Step Setup
pipedream.com > Workflows > + New Workflow
Create a new Pipedream Workflow
Go to pipedream.com and log in. Click 'Workflows' in the left sidebar, then click the blue '+ New Workflow' button in the top right. Give it a name like 'Slack Mention → Todoist Task' so you can find it later. You'll land on the workflow canvas with a trigger slot at the top.
- 1Click 'Workflows' in the left sidebar
- 2Click the blue '+ New Workflow' button
- 3Type a workflow name in the title field at the top
- 4Click 'Save' to confirm the name
Workflow Canvas > Add a trigger > Slack > New Mention (Instant)
Add the Slack Event Mention trigger
Click the 'Add a trigger' slot on the canvas. Search for 'Slack' in the app search box and select it. Scroll through the trigger options and choose 'New Mention (Instant)' — this fires every time a user is @-mentioned in a channel your bot is in. Do not pick 'New Message Posted to Channel' — that fires on every message and will generate far more noise than you need.
- 1Click the 'Add a trigger' slot
- 2Type 'Slack' in the search box
- 3Click 'Slack' in the results
- 4Select 'New Mention (Instant)' from the trigger list
Trigger Card > Connect Account > OAuth > Channel dropdown
Connect your Slack account and configure the channel filter
Click 'Connect your Slack account' inside the trigger card. Pipedream opens an OAuth window — sign in with the Slack workspace where your project channels live and click Allow. Back in the trigger config, locate the 'Channel' dropdown and select only the specific channels you want this workflow to watch (e.g., #sprint-42). You can select multiple channels. Leave the 'Resolve names' toggle ON so the payload includes readable usernames.
- 1Click 'Connect your Slack account'
- 2Authenticate in the Slack OAuth popup
- 3Return to Pipedream and open the 'Channel' dropdown
- 4Select one or more specific project channels
- 5Confirm 'Resolve names' is toggled ON
Trigger Card > Generate Test Event
Send a test mention to generate sample data
Click 'Generate Test Event' at the bottom of the trigger card. Pipedream will listen for 30 seconds. During that window, go to your selected Slack channel and type a message that @-mentions one of your team members, like '@alex please review the API spec'. Switch back to Pipedream — the test event should appear with the raw Slack payload including the user ID, channel ID, and message text. Click on the event to expand it and confirm the fields are populated.
- 1Click 'Generate Test Event'
- 2Switch to Slack and post a message mentioning a team member
- 3Switch back to Pipedream
- 4Click the incoming test event to inspect the payload
Workflow Canvas > + > Run Node.js code
Add a Node.js code step to parse the mention and resolve the assignee
Click the '+' button below the trigger to add a new step. Choose 'Run Node.js code'. This step will extract the mentioned user's Slack ID from the message text, look up their display name via the Slack API, and map them to a Todoist assignee ID based on a hardcoded lookup table you define. It also strips the channel ID into a readable project name. Paste the code from the Pro Tip section below into the code editor.
- 1Click the '+' button below the Slack trigger
- 2Select 'Run Node.js code'
- 3Clear the default code in the editor
- 4Paste your custom parsing code
- 5Click 'Test' to run the step against your sample event
Paste this into the Node.js code step added in Step 5. It extracts the mentioned user's Slack ID, resolves their display name via the Slack API, maps them to a Todoist collaborator ID using a lookup table you define, builds clean task content, and generates the Slack permalink. Replace the SLACK_USER_MAP and CHANNEL_PROJECT_MAP objects with your actual IDs before deploying.
JavaScript — Code Stepimport axios from 'axios';▸ Show code
import axios from 'axios';
export default defineComponent({
async run({ steps, $ }) {... expand to see full code
import axios from 'axios';
export default defineComponent({
async run({ steps, $ }) {
// --- CONFIG: Update these maps with your real IDs ---
const SLACK_USER_MAP = {
'U04KXYZ99': { name: 'Alex Morgan', todoist_id: '45678901' },
'U04KABC12': { name: 'Sam Rivera', todoist_id: '45678902' },
'U04KDEF34': { name: 'Jordan Lee', todoist_id: '45678903' },
};
const CHANNEL_PROJECT_MAP = {
'C05SPRINT42': { name: 'Sprint 42', todoist_project_id: '2347891234' },
'C05SPRINT43': { name: 'Sprint 43', todoist_project_id: '2347891235' },
'C05BUGFIX': { name: 'Bug Fixes', todoist_project_id: '2347891236' },
};
// --- END CONFIG ---
const text = steps.trigger.event.text || '';
const channel = steps.trigger.event.channel;
const ts = steps.trigger.event.ts;
// Extract the first user mention from message text
const mentionMatch = text.match(/<@([A-Z0-9]+)>/);
if (!mentionMatch) {
$.flow.exit('No user mention found — skipping');
}
const slackUserId = mentionMatch[1];
// Resolve user from lookup table
const user = SLACK_USER_MAP[slackUserId];
if (!user) {
$.flow.exit(`User ${slackUserId} not in lookup table — skipping`);
}
// Resolve channel to Todoist project
const project = CHANNEL_PROJECT_MAP[channel];
if (!project) {
$.flow.exit(`Channel ${channel} not in lookup table — skipping`);
}
// Clean message text: replace raw mention with display name
const cleanText = text
.replace(/<@[A-Z0-9]+>/g, user.name)
.replace(/<[^>]+>/g, '') // strip other Slack formatting
.trim();
// Build Slack permalink using workspace domain
const workspaceDomain = 'yourworkspace'; // replace with your Slack subdomain
const tsFormatted = ts.replace('.', '');
const messageUrl = `https://${workspaceDomain}.slack.com/archives/${channel}/p${tsFormatted}`;
return {
task_content: `${user.name}: ${cleanText}`,
todoist_assignee_id: user.todoist_id,
todoist_project_id: project.todoist_project_id,
channel_name: project.name,
message_url: messageUrl,
};
},
});Workflow Canvas > + > Filter
Add a conditional filter to skip non-actionable mentions
Click '+' to add another step. Select 'Filter' from the Pipedream built-in options. Set the condition to check that the parsed assignee_id from the previous step is not null. This prevents the workflow from creating blank Todoist tasks when someone mentions a channel (@here, @channel) or a bot account that has no Todoist equivalent. Configure the filter to 'End workflow' if the condition fails.
- 1Click '+' below the Node.js step
- 2Select 'Filter' from the built-in step list
- 3Set field to '{{steps.code.$return_value.todoist_assignee_id}}'
- 4Set operator to 'is not empty'
- 5Set action on failure to 'End workflow execution'
Workflow Canvas > + > Todoist > Create Task
Add the Todoist 'Create Task' action
Click '+' to add a new step. Search for 'Todoist' and select it. Choose the 'Create Task' action. Click 'Connect your Todoist account' and complete the OAuth flow — use the account that has access to all the projects you want to write to. The action card will show a form with fields for Content, Project, Due Date, and Assignee.
- 1Click '+' below the Filter step
- 2Search for 'Todoist' and click it
- 3Select 'Create Task'
- 4Click 'Connect your Todoist account'
- 5Complete the OAuth flow and return to Pipedream
Todoist Step > Create Task > Field mapping form
Map the Slack data to Todoist task fields
In the Todoist Create Task form, map each field using the output from your Node.js step. Set Content to '{{steps.code.$return_value.task_content}}', which includes the original Slack message. Set Project ID to the mapped project ID from your channel lookup. Set Assignee ID to '{{steps.code.$return_value.todoist_assignee_id}}'. Set Description to '{{steps.code.$return_value.message_url}}' so the task links back to the original Slack thread.
- 1Click the Content field and type '{{' to open the data picker
- 2Select 'steps.code.$return_value.task_content'
- 3Repeat for Project ID using 'steps.code.$return_value.todoist_project_id'
- 4Set Assignee ID to 'steps.code.$return_value.todoist_assignee_id'
- 5Set Description to 'steps.code.$return_value.message_url'
Workflow Canvas > Test workflow button (top right)
Test the full workflow end-to-end
Click 'Test workflow' at the top of the canvas to run all steps in sequence using your saved test event. Watch the step-by-step execution log on the right side — each step shows green for success or red for errors. After the test completes, open your Todoist project and confirm the task appears with the correct assignee, content, and description link. Check that the Slack message URL in the description resolves to the correct message.
- 1Click 'Test workflow' in the top toolbar
- 2Watch each step turn green in the execution log
- 3Open Todoist and find the new task in the expected project
- 4Click the Slack URL in the task description to confirm it opens the correct message
Workflow Canvas > Deploy button > Events tab
Deploy the workflow and verify it's active
Click the grey 'Deploy' button in the top right corner of the canvas. The workflow status changes from 'Inactive' to 'Active' and Pipedream begins listening for real Slack events. Go to your Slack channel and post a live @mention. Within 5–10 seconds, the task should appear in Todoist. Check the Pipedream event log under 'Events' in the left sidebar to see incoming events and confirm none are failing.
- 1Click the grey 'Deploy' button
- 2Confirm the status indicator changes to 'Active'
- 3Go to Slack and post a real @mention in the target channel
- 4Return to Pipedream and click 'Events' in the left sidebar
- 5Confirm the event shows a 200 status and all steps succeeded
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 Pipedream for this if your team has at least one developer who can maintain a Node.js code step. The mention-to-task logic requires resolving Slack user IDs, mapping channels to projects, and building permalinks — three things that need code, not drag-and-drop config. Pipedream lets you do all three in a single step with full async/await support and direct API access. The one scenario where you'd pick something else: if your team is fully non-technical, Zapier can do a simplified version of this with its Formatter step and lookup tables, at the cost of less flexibility on the Todoist field mapping.
Pipedream's free tier gives you 10,000 workflow invocations per month. Each Slack mention triggers one invocation. At 50 mentions per day across your watched channels, you're at 1,500/month — well inside the free tier. The paid plan at $19/month buys you 100,000 invocations, which covers even noisy teams. Compare that to Zapier: this same workflow on Zapier costs at least 3 tasks per trigger (trigger + code + Todoist action), so at 1,500 events/month you burn 4,500 Zapier tasks — which puts you in the $49/month Starter plan immediately. Pipedream is roughly $30/month cheaper for this specific use case at moderate volume.
Zapier handles the Slack-to-Todoist connection with fewer steps to configure, but its lookup table for user mapping is clunky — you're limited to a static table in a Formatter step with no easy way to pull from an external source. Make has a cleaner visual router that could handle the channel-to-project mapping without code, and its Slack module exposes more event subtypes than Pipedream's pre-built trigger. n8n gives you full Node.js flexibility like Pipedream but requires self-hosting or a cloud plan starting at $20/month, with a steeper initial setup. Power Automate has a Todoist connector but it's community-built and hasn't been updated in over a year — skip it for this. Pipedream wins here because instant webhook processing plus native code steps means no glue logic workarounds.
Three things you'll hit after setup. First, Slack's mention event fires before the message is indexed, so if you immediately try to fetch the message via conversations.history, you'll occasionally get a not_found error — add a 500ms delay in your code step before any secondary API calls. Second, Todoist silently ignores the assignee_id field if the task's project doesn't have collaborators enabled (this happens on personal projects) — the task creates successfully but lands unassigned with no error returned. Third, if your team uses Slack's workflow builder to post automated messages that include @mentions, those will trigger your Pipedream workflow too — add a check in your code step that skips messages where event.bot_id is present in the payload.
Ideas for what to build next
- →Post a Slack confirmation when the task is created — Add a Todoist step after task creation that posts a reply in the original Slack thread with the Todoist task URL. This closes the loop so the mentioned person sees the task was created without leaving Slack.
- →Parse due dates from natural language in Slack messages — Extend the Node.js code step to detect date patterns like 'by Friday' or 'before EOD' using a library like chrono-node, then pass the parsed date to Todoist's due_string field so tasks arrive with deadlines already set.
- →Handle multiple mentions in a single message — The current workflow only catches the first @mention per message. Update the regex in the code step to extract all user mentions and loop through them, creating one Todoist task per mentioned person with the same channel context.
Related guides
How to Assign Todoist Tasks from Slack Mentions with Power Automate
~15 min setup
How to Assign Todoist Tasks from Slack Mentions with n8n
~20 min setup
How to Assign Todoist Tasks from Slack Mentions with Zapier
~8 min setup
How to Assign Todoist Tasks from Slack Mentions with Make
~12 min setup
How to Send Weekly Todoist Reports to Slack with Pipedream
~15 min setup
How to Send Weekly Todoist Reports to Slack with Power Automate
~15 min setup