

How to Post Todoist Standups to Slack with Pipedream
A scheduled Pipedream workflow pulls each team member's active Todoist tasks every morning and posts a formatted standup summary to a designated Slack channel.
Steps and UI details are based on platform versions at time of writing — check each platform for the latest interface.
Real-World Example
A 12-person product team at a remote SaaS company runs async standups in #standup-product. Before automation, each person pasted their task list manually into Slack every morning — about 3 minutes per person, often skipped. Now Pipedream fires at 9:00 AM, pulls every member's due-today and overdue Todoist tasks via the REST API, and posts a single formatted digest. The channel sees consistent standup data every day with zero manual effort.
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 | |
| Due Date | due.date | |
| Priority | priority | |
| Is Completed | is_completed | |
4 optional fields▸ show
| Project ID | project_id |
| Assignee ID | assignee_id |
| Task URL | url |
| Labels | labels |
Step-by-Step Setup
pipedream.com > Workflows > New Workflow
Create a new Pipedream workflow
Go to pipedream.com and sign in. Click 'New Workflow' in the top-right corner of the dashboard. Give it a clear name like 'Daily Standup — Todoist to Slack'. You'll land on the workflow canvas with an empty trigger slot at the top.
- 1Click the blue 'New Workflow' button in the top-right
- 2Type 'Daily Standup — Todoist to Slack' in the workflow name field
- 3Press Enter or click the checkmark to save the name
- 4Click the '+ Add Trigger' block at the top of the canvas
Trigger Panel > Search > Schedule > Every Day
Set a daily schedule trigger
In the trigger panel, search for 'Schedule' and select the 'Schedule' source. Choose 'Every day' from the frequency dropdown. Set the time to 9:00 AM and select your team's timezone — this is critical for international teams. Pipedream runs the schedule in UTC by default until you change it.
- 1Type 'Schedule' in the trigger search box
- 2Click 'Schedule' under the 'Core' category
- 3Select 'Every Day' from the frequency dropdown
- 4Set the time field to '09:00'
- 5Open the timezone dropdown and select your team's local timezone (e.g., 'America/New_York')
Workflow Canvas > + Add Step > Todoist > Get Active Tasks
Connect your Todoist account
Click '+ Add Step' below the trigger and search for 'Todoist'. Select the 'Get Active Tasks' action (action key: todoist-get-active-tasks). In the step configuration panel, click 'Connect Account' and authenticate with your Todoist credentials. You'll need a Todoist account that has access to the projects you want to pull from.
- 1Click '+ Add Step' directly below the trigger block
- 2Type 'Todoist' in the app search field
- 3Select 'Todoist' from the results
- 4Choose the 'Get Active Tasks' action
- 5Click 'Connect Account' and complete the OAuth login
Todoist Step > Configuration > Filter Field
Filter tasks by project or assignee
In the Todoist 'Get Active Tasks' step, find the 'Filter' field. Todoist's REST API accepts filter strings like 'today | overdue' to limit which tasks come back. Type your filter string here. If your team members each own a Todoist project, you can also set 'Project ID' to pull from a specific project. Run a test now — click 'Test' at the bottom of the step — to confirm tasks return.
- 1Click inside the 'Filter' input field in the Todoist step
- 2Type 'today | overdue' to capture due-today and overdue tasks
- 3Optionally set 'Project ID' if you want to scope tasks to one project
- 4Click the 'Test' button at the bottom of the step
- 5Expand the returned array to confirm your tasks appear in the output
Workflow Canvas > + Add Step > Run Node.js Code
Add a Node.js code step to format the standup message
Click '+ Add Step' and choose 'Run Node.js code'. This is where you transform the raw Todoist task array into a readable Slack message. You'll map task content, priority, and due date into a formatted string. Paste the code from the Pro Tip section below directly into this step's code editor. The code groups tasks by priority and assembles a Block Kit-friendly Slack message payload.
- 1Click '+ Add Step' below the Todoist step
- 2Select 'Run Node.js code' from the step type list
- 3Clear the default boilerplate from the editor
- 4Paste your formatting code into the editor
- 5Click 'Test' to confirm the output includes a formatted 'blocks' array
Paste this into your Node.js code step (Step 5 on the canvas). It reads the Todoist task array from the previous step's output, maps priority numbers to labels, flags overdue tasks, groups everything by priority, and returns a Slack Block Kit blocks array ready to drop into the Slack Send Message step.
JavaScript — Code Stepexport default defineComponent({▸ Show code
export default defineComponent({
async run({ steps, $ }) {
const tasks = steps.todoist_get_active_tasks.$return_value;... expand to see full code
export default defineComponent({
async run({ steps, $ }) {
const tasks = steps.todoist_get_active_tasks.$return_value;
if (!tasks || tasks.length === 0) {
return {
blocks: [
{
type: 'section',
text: {
type: 'mrkdwn',
text: ':white_check_mark: No tasks due today — enjoy the quiet.'
}
}
]
};
}
const priorityMap = {
4: { label: 'Urgent', emoji: ':red_circle:' },
3: { label: 'High', emoji: ':large_orange_circle:' },
2: { label: 'Medium', emoji: ':large_yellow_circle:' },
1: { label: 'Normal', emoji: ':white_circle:' }
};
const today = new Date().toISOString().split('T')[0];
const sorted = [...tasks].sort((a, b) => b.priority - a.priority);
const blocks = [
{
type: 'header',
text: {
type: 'plain_text',
text: `:clipboard: Daily Standup — ${new Date().toLocaleDateString('en-US', { weekday: 'long', month: 'short', day: 'numeric' })}`,
emoji: true
}
},
{ type: 'divider' }
];
for (const task of sorted) {
const { label, emoji } = priorityMap[task.priority] || priorityMap[1];
const dueDate = task.due?.date || 'No due date';
const isOverdue = task.due?.date && task.due.date < today;
const overdueFlag = isOverdue ? ' :warning: *Overdue*' : '';
const formattedDate = dueDate !== 'No due date'
? new Date(dueDate + 'T00:00:00').toLocaleDateString('en-US', { month: 'short', day: 'numeric' })
: 'No due date';
blocks.push({
type: 'section',
text: {
type: 'mrkdwn',
text: `${emoji} *${label}* — <${task.url}|${task.content}> · Due: ${formattedDate}${overdueFlag}`
}
});
}
blocks.push({ type: 'divider' });
blocks.push({
type: 'context',
elements: [
{
type: 'mrkdwn',
text: `${sorted.length} task${sorted.length !== 1 ? 's' : ''} · Pulled from Todoist at ${new Date().toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' })}`
}
]
});
return { blocks };
}
});channel: {{channel}}
ts: {{ts}}
Workflow Canvas > + Add Step > Slack > Send Message
Connect your Slack account
Click '+ Add Step' and search for 'Slack'. Select the 'Send Message' action. Click 'Connect Account' and authorize Pipedream via OAuth. Pipedream will request the 'chat:write' and 'chat:write.public' scopes — both are required. If you're posting to a private channel, you'll also need to invite the Pipedream Slack app to that channel manually inside Slack.
- 1Click '+ Add Step' below the Node.js code step
- 2Type 'Slack' in the app search
- 3Select 'Slack' and then 'Send Message'
- 4Click 'Connect Account' and complete the Slack OAuth flow
- 5Confirm the connected account name matches your workspace
Slack Step > Channel > Blocks Field > Expression Picker
Configure the Slack message destination and payload
In the Slack 'Send Message' step, set the Channel field to your standup channel name, e.g. '#standup-product'. In the Blocks field, reference the output from your Node.js code step by clicking the '{{' expression picker and selecting 'steps.nodejs.$return_value.blocks'. Leave the Text field as a fallback string like 'Daily standup summary' — Slack uses this as a notification preview.
- 1Click the Channel field and type '#standup-product' or your channel name
- 2Click into the Blocks field
- 3Click the '{{' button to open the expression picker
- 4Navigate to your Node.js step and select '$return_value.blocks'
- 5Set the Text field fallback to 'Daily standup summary — see thread'
Workflow Canvas > Run Now Button (top toolbar)
Test the full workflow end to end
Click 'Run Now' at the top of the workflow canvas to trigger a manual test run. Watch each step execute in sequence — green checkmarks indicate success. Open your Slack standup channel and confirm the message posted correctly. Check that task priorities, due dates, and task content all look right. If any step shows a red X, click it to read the error log.
- 1Click the grey 'Run Now' button in the top toolbar
- 2Watch each step tile turn green as they complete
- 3Open Slack and navigate to your standup channel
- 4Confirm the posted message shows the correct tasks and formatting
- 5If a step fails, click the red X icon on that step to read the error detail
Node.js Code Step > Editor
Handle the case where no tasks are due
When Todoist returns zero tasks, your Node.js code will produce an empty blocks array and Slack will reject the message with a 'no_text' error. Add a short conditional in your code step that checks the array length. If it's zero, export a simple fallback message like 'No tasks due today — enjoy the quiet.' This prevents workflow errors on low-activity days.
- 1Open your Node.js code step
- 2Add an array length check before the blocks-building logic
- 3Return a minimal Slack block with the fallback text if the array is empty
- 4Click 'Test' to confirm the fallback triggers when task count is zero
Workflow Canvas > Deploy Button (top-right)
Deploy and activate the workflow
Click the grey 'Deploy' button in the top-right corner of the canvas. Pipedream will switch the workflow from draft mode to active. The toggle next to the workflow name will turn green. Your standup will now fire automatically every day at the time and timezone you set in Step 2. You can pause it anytime by flipping the toggle back.
- 1Click the 'Deploy' button in the top-right corner
- 2Confirm the prompt if one appears
- 3Check that the toggle next to the workflow name turns green
- 4Navigate to 'Workflow > Logs' to confirm the next scheduled run time
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 someone comfortable with JavaScript and wants full control over the standup message format. Pipedream's Node.js code step handles the Todoist priority inversion, overdue flagging, and Slack Block Kit formatting in one place without duct-taping multiple no-code actions together. The scheduled trigger fires reliably and the logs make debugging fast. If nobody on your team writes code, use Zapier instead — the formatter action handles basic task formatting without touching a single line of code.
Pipedream's pricing for this workflow is straightforward. Each daily run costs roughly 3 credits: 1 for the Todoist step, 1 for the code step, 1 for the Slack step. At Pipedream's free tier of 100 credits/month, you'll burn through in about 33 days — just over one month. The Basic plan at $19/month gives you 10,000 credits, which covers this workflow for 3,333 days at one run per day. In practice, even teams running 5 separate standup channels (5 workflows × 3 credits × 30 days = 450 credits/month) stay well within the Basic plan. Make's free tier covers the same workflow at zero cost indefinitely for a single channel.
Make handles this use case with a visual router that branches to multiple Slack channels in one scenario — no code needed. Zapier has a native Todoist 'New Task' trigger but no 'get all tasks on schedule' action, so you'd need workarounds. n8n has a Todoist node with better filter support and a Slack node that handles Block Kit natively, making it cleaner for teams self-hosting. Power Automate has no official Todoist connector, so you'd be hitting the REST API manually via HTTP actions — workable but slow to set up. Pipedream wins here because the code step eliminates the gap between what Todoist's API returns and what Slack's Block Kit expects, and the Node.js environment means you're not fighting a visual mapper to do basic data transformation.
Three things you'll hit after the first week. First, Todoist's 'today | overdue' filter includes tasks with no time component, which means a task due 'today' at 11:59 PM shows up in the 9 AM standup alongside actually overdue items — decide upfront if that's what you want. Second, if a team member revokes Todoist OAuth or changes their password, the workflow fails silently unless you add error alerting — Pipedream lets you add an error handler step that pings a Slack DM when a workflow fails, which takes 2 minutes to set up and is worth doing on day one. Third, Slack's Block Kit has a hard limit of 50 blocks per message. If a team has more than 45–48 tasks due in a single day, the message will be truncated without an error. Add a block count check in your code step and split into a thread reply if the count exceeds 40.
Ideas for what to build next
- →Add per-user task breakdowns — Extend the code step to group tasks by assignee_id, then resolve each ID to a display name using the Todoist Users API. This turns one team digest into a per-person breakdown inside a single Slack message thread.
- →Post a weekly summary on Fridays — Duplicate the workflow and change the Schedule trigger to fire every Friday at 4:00 PM. Adjust the Todoist filter to 'overdue | due before: +7 days' to give the team a forward-looking view going into the weekend.
- →Add a Slack emoji reaction acknowledgment — After the standup posts, add a second Slack step that adds a ':white_check_mark:' reaction to the message automatically. Then track who adds a thumbs-up reaction using Pipedream's Slack event source to measure standup engagement over time.
Related guides
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
How to Send Weekly Todoist Reports to Slack with n8n
~20 min setup
How to Send Weekly Todoist Reports to Slack with Zapier
~8 min setup
How to Send Weekly Todoist Reports to Slack with Make
~12 min setup
How to Assign Todoist Tasks from Slack Mentions with Pipedream
~15 min setup