

How to Send Asana Task Notifications to Slack with n8n
Sends a direct Slack message to a team member the moment they're assigned an Asana task or when a task's priority changes — no polling, fires in under 10 seconds.
Steps and UI details are based on platform versions at time of writing — check each platform for the latest interface.
Best for
Engineering or ops teams where missed task assignments cause delays and team members shouldn't need Asana open all day.
Not ideal for
Teams that reassign tasks dozens of times per hour — the Slack noise will outweigh the benefit; use a daily digest instead.
Sync type
real-timeUse case type
notificationReal-World Example
A 22-person product team at a SaaS company uses this to DM engineers in Slack the instant a bug task gets assigned or escalated to urgent priority. Before this, engineers checked Asana once or twice a day and high-priority bugs sometimes sat unnoticed for 3-4 hours. With the webhook firing in under 10 seconds, the assigned engineer gets a Slack DM with the task name, due date, priority, and a direct link to Asana.
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 | |
| Assignee Name | assignee.name | |
| Assignee Email | assignee.email | |
| Task GID | gid | |
| Task Permalink URL | permalink_url | |
| Event Type | change.field | |
4 optional fields▸ show
| Due Date | due_on |
| Priority | custom_fields[priority].display_value |
| Project Name | projects[0].name |
| Task Notes | notes |
Step-by-Step Setup
n8n Canvas > + New Workflow
Create a new workflow in n8n
Log into your n8n instance (cloud at app.n8n.io or your self-hosted URL). Click the orange 'New Workflow' button in the top-right of the canvas. A blank canvas opens with a prompt to add your first node. Name the workflow 'Asana → Slack Task Notifications' using the pencil icon at the top so you can find it later.
- 1Click 'New Workflow' in the top-right corner
- 2Click the pencil icon next to 'My Workflow' at the top
- 3Type 'Asana → Slack Task Notifications' and press Enter
- 4Click the '+' node button in the center of the canvas to add your trigger
Canvas > Add Node > Search 'Asana Trigger'
Add the Asana Trigger node
In the node picker, search for 'Asana' and select the 'Asana Trigger' node — not the regular Asana node, which is for actions. This trigger listens via Asana's webhook API, so events fire in real time rather than on a schedule. You'll see a configuration panel open on the right with fields for credentials, resource, and event type.
- 1Type 'Asana' in the node search bar
- 2Click 'Asana Trigger' (look for the lightning bolt icon indicating it's a trigger)
- 3Click 'Create new credential' under the Credentials dropdown
- 4Paste your Asana Personal Access Token and click Save
Asana Trigger Node > Parameters Panel
Configure the Asana Trigger events
Set the Resource to 'Task' in the dropdown. Under Events, select both 'Task Assigned' and 'Task Changed' — you need both to catch new assignments and priority changes. In the Project field, either select a specific project to scope notifications or leave it blank to catch all tasks across the workspace. Set the Workspace field to your team's Asana workspace.
- 1Set 'Resource' to 'Task'
- 2Check 'Task Assigned' under Events
- 3Check 'Task Changed' under Events
- 4Set 'Workspace' to your Asana workspace from the dropdown
- 5Optionally select a specific Project to limit scope
Asana Trigger Node > Listen for Test Event button
Test the Asana trigger with sample data
Click 'Listen for Test Event' at the bottom of the Asana Trigger panel. n8n will register the webhook with Asana's API automatically when you enter test mode. Go to Asana, find any task, and assign it to someone (or reassign it) to fire a test event. Switch back to n8n — you should see the raw JSON payload appear in the Output panel on the right within a few seconds.
- 1Click 'Listen for Test Event' in the node panel
- 2Open Asana in a new tab
- 3Find any task and change the assignee or priority
- 4Return to n8n and wait for the payload to appear in the Output panel
Canvas > Add Node > Search 'IF'
Add an IF node to filter relevant events
Not every task event should fire a Slack notification. Add an 'IF' node after the trigger to filter out events where no assignee is present (unassigned tasks) and to separate 'assignment' events from 'priority change' events. This prevents spammy notifications for minor edits like description changes. Connect the Asana Trigger output to the IF node.
- 1Click the '+' button on the Asana Trigger node output connector
- 2Search for 'IF' and select the IF node
- 3Set Condition 1: Value 1 = '{{ $json.assignee }}', Operation = 'Is Not Empty'
- 4Click 'Add Condition' and set Condition 2: Value 1 = '{{ $json.assignee.gid }}', Operation = 'Is Not Empty'
- 5Set the Combine field to 'AND'
Canvas > Add Node > Search 'Asana' (action node)
Fetch full task details from Asana API
The webhook payload is sparse — it often omits due dates, priority, and project names. Add an Asana node (action, not trigger) to fetch the complete task record using the task GID from the webhook. This gives you all the fields you need to build a rich Slack message. Connect this node to the 'true' output of your IF node.
- 1Click '+' on the IF node's true output
- 2Search 'Asana' and select the regular Asana node (not the trigger)
- 3Set Resource to 'Task', Operation to 'Get'
- 4Set Task ID to '{{ $json.gid }}' using the expression editor
- 5Use the same Asana credential you configured in Step 2
Canvas > Add Node > Search 'Code'
Add a Code node to build the Slack message
Add an n8n Code node to transform the Asana task data into a formatted Slack Block Kit message. This is where you handle edge cases: null due dates, missing priority labels, and mapping the event type to a human-readable header ('You've been assigned a new task' vs. 'A task priority has changed'). The Code node outputs a structured object ready for the Slack node.
- 1Click '+' on the Asana Get Task node output
- 2Search 'Code' and select the Code node
- 3Set Language to 'JavaScript'
- 4Paste the transformation code from the Pro Tip section below
- 5Click 'Execute Node' to verify the output structure
This Code node runs after the Asana 'Get Task' API call. It builds a Slack Block Kit message with conditional headers (assignment vs. priority change), formats the due date, handles null priority gracefully, and outputs the assignee email for the users.lookupByEmail step. Paste this into the Code node in Step 7, using the JavaScript language setting.
JavaScript — Code Node// n8n Code Node — Asana → Slack Block Kit Message Builder▸ Show code
// n8n Code Node — Asana → Slack Block Kit Message Builder // Runs after Asana 'Get Task' node. Outputs structured Slack message + assignee email. const task = $input.item.json;
... expand to see full code
// n8n Code Node — Asana → Slack Block Kit Message Builder
// Runs after Asana 'Get Task' node. Outputs structured Slack message + assignee email.
const task = $input.item.json;
const triggerData = $node['Asana Trigger'].json;
// Determine event type from the webhook change field
const changeField = triggerData?.change?.field || 'assignee';
const isAssignment = changeField === 'assignee';
const isPriorityChange = changeField === 'custom_fields';
// Build human-readable header based on event type
const header = isAssignment
? '📋 You\'ve been assigned a new task'
: isPriorityChange
? '🔺 A task priority has changed'
: '🔔 A task was updated';
// Format due date — Asana returns ISO date string 'YYYY-MM-DD' or null
let dueDateDisplay = 'No due date set';
if (task.due_on) {
const d = new Date(task.due_on + 'T12:00:00Z'); // noon UTC avoids timezone-off-by-one
dueDateDisplay = d.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
}
// Resolve priority from custom fields array (null-safe)
const priorityField = (task.custom_fields || []).find(f => f.name === 'Priority');
const priority = priorityField?.display_value ?? 'No priority set';
// Truncate task notes to 200 chars for Slack context block
const rawNotes = task.notes || '';
const notesSnippet = rawNotes.length > 200
? rawNotes.substring(0, 197) + '...'
: rawNotes || '_No description provided_';
// Get project name (tasks can belong to multiple projects; show the first)
const projectName = (task.projects || [])[0]?.name ?? 'No project';
// Slack Block Kit structure
const blocks = [
{
type: 'header',
text: { type: 'plain_text', text: header, emoji: true }
},
{
type: 'section',
fields: [
{ type: 'mrkdwn', text: `*Task:*\n<${task.permalink_url}|${task.name}>` },
{ type: 'mrkdwn', text: `*Project:*\n${projectName}` },
{ type: 'mrkdwn', text: `*Due Date:*\n${dueDateDisplay}` },
{ type: 'mrkdwn', text: `*Priority:*\n${priority}` }
]
},
{
type: 'context',
elements: [
{ type: 'mrkdwn', text: notesSnippet }
]
},
{
type: 'actions',
elements: [
{
type: 'button',
text: { type: 'plain_text', text: 'Open in Asana', emoji: true },
url: task.permalink_url,
action_id: 'open_asana_task'
}
]
}
];
// Output: blocks for Slack node + email for users.lookupByEmail HTTP request
return [
{
json: {
blocks,
text: `${header}: ${task.name}`, // Fallback text for Slack notifications
assigneeEmail: task.assignee?.email ?? null,
assigneeName: task.assignee?.name ?? 'Unknown',
taskGid: task.gid
}
}
];channel: {{channel}}
ts: {{ts}}
Canvas > Add Node > Search 'HTTP Request'
Resolve Asana email to Slack user ID
Add an HTTP Request node to call Slack's users.lookupByEmail endpoint with the assignee's Asana email. This returns the Slack user ID needed to send a DM. Use your Slack Bot Token in the Authorization header. Connect this node between the Code node and the final Slack node.
- 1Click '+' after the Code node
- 2Add an HTTP Request node
- 3Set Method to GET
- 4Set URL to 'https://slack.com/api/users.lookupByEmail'
- 5Add Query Parameter: email = '{{ $json.assigneeEmail }}'
- 6Add Header: Authorization = 'Bearer xoxb-your-bot-token'
This Code node runs after the Asana 'Get Task' API call. It builds a Slack Block Kit message with conditional headers (assignment vs. priority change), formats the due date, handles null priority gracefully, and outputs the assignee email for the users.lookupByEmail step. Paste this into the Code node in Step 7, using the JavaScript language setting.
JavaScript — Code Node// n8n Code Node — Asana → Slack Block Kit Message Builder▸ Show code
// n8n Code Node — Asana → Slack Block Kit Message Builder // Runs after Asana 'Get Task' node. Outputs structured Slack message + assignee email. const task = $input.item.json;
... expand to see full code
// n8n Code Node — Asana → Slack Block Kit Message Builder
// Runs after Asana 'Get Task' node. Outputs structured Slack message + assignee email.
const task = $input.item.json;
const triggerData = $node['Asana Trigger'].json;
// Determine event type from the webhook change field
const changeField = triggerData?.change?.field || 'assignee';
const isAssignment = changeField === 'assignee';
const isPriorityChange = changeField === 'custom_fields';
// Build human-readable header based on event type
const header = isAssignment
? '📋 You\'ve been assigned a new task'
: isPriorityChange
? '🔺 A task priority has changed'
: '🔔 A task was updated';
// Format due date — Asana returns ISO date string 'YYYY-MM-DD' or null
let dueDateDisplay = 'No due date set';
if (task.due_on) {
const d = new Date(task.due_on + 'T12:00:00Z'); // noon UTC avoids timezone-off-by-one
dueDateDisplay = d.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
}
// Resolve priority from custom fields array (null-safe)
const priorityField = (task.custom_fields || []).find(f => f.name === 'Priority');
const priority = priorityField?.display_value ?? 'No priority set';
// Truncate task notes to 200 chars for Slack context block
const rawNotes = task.notes || '';
const notesSnippet = rawNotes.length > 200
? rawNotes.substring(0, 197) + '...'
: rawNotes || '_No description provided_';
// Get project name (tasks can belong to multiple projects; show the first)
const projectName = (task.projects || [])[0]?.name ?? 'No project';
// Slack Block Kit structure
const blocks = [
{
type: 'header',
text: { type: 'plain_text', text: header, emoji: true }
},
{
type: 'section',
fields: [
{ type: 'mrkdwn', text: `*Task:*\n<${task.permalink_url}|${task.name}>` },
{ type: 'mrkdwn', text: `*Project:*\n${projectName}` },
{ type: 'mrkdwn', text: `*Due Date:*\n${dueDateDisplay}` },
{ type: 'mrkdwn', text: `*Priority:*\n${priority}` }
]
},
{
type: 'context',
elements: [
{ type: 'mrkdwn', text: notesSnippet }
]
},
{
type: 'actions',
elements: [
{
type: 'button',
text: { type: 'plain_text', text: 'Open in Asana', emoji: true },
url: task.permalink_url,
action_id: 'open_asana_task'
}
]
}
];
// Output: blocks for Slack node + email for users.lookupByEmail HTTP request
return [
{
json: {
blocks,
text: `${header}: ${task.name}`, // Fallback text for Slack notifications
assigneeEmail: task.assignee?.email ?? null,
assigneeName: task.assignee?.name ?? 'Unknown',
taskGid: task.gid
}
}
];Canvas > Add Node > Search 'Slack'
Add the Slack node to send the DM
Add a Slack node configured to send a direct message. Set the channel to the Slack user ID resolved in the previous step. Use the Block Kit blocks from your Code node output for a formatted message. The Slack node handles the API call to chat.postMessage under the hood — you just map the fields.
- 1Click '+' on the HTTP Request node output
- 2Search 'Slack' and select the Slack node
- 3Set Resource to 'Message', Operation to 'Post'
- 4Set Channel to '{{ $node["HTTP Request"].json.user.id }}'
- 5Set Message Type to 'Block' and paste '{{ $node["Code"].json.blocks }}' in Blocks field
- 6Set the Fallback Text to '{{ $node["Code"].json.text }}'
Canvas > Slack Node > Error Output > Add Node
Add an error handler for failed notifications
Add a second Slack node connected to the error output of your main Slack send node. Route failures to a shared ops channel like #automation-alerts rather than losing them silently. Include the error message and the task GID so someone can manually follow up. This is especially important for the email-to-Slack-ID lookup failures from Step 8.
- 1Hover over the Slack node to reveal the red error output connector
- 2Click the red error connector and add a new Slack node
- 3Set Channel to your ops or alerts channel ID (e.g. C04ABCDEF)
- 4Set Message to 'Task notification failed for task {{ $node["Asana Trigger"].json.gid }}: {{ $json.error.message }}'
- 5Use the same Slack credential
n8n Canvas > Inactive toggle (top-right)
Activate the workflow and verify end-to-end
Click the 'Inactive' toggle in the top-right of the canvas to activate the workflow. Once active, n8n keeps the Asana webhook registration alive and processes events as they arrive. Go to Asana, assign a real task to a team member, and confirm the Slack DM arrives within 10 seconds. Check the Executions tab in n8n to see the run log.
- 1Click the 'Inactive' toggle — it should flip to 'Active' and turn green
- 2Open Asana and assign a task to a team member who is also in Slack
- 3Check that person's Slack DMs within 10 seconds
- 4Return to n8n and click 'Executions' in the left sidebar to confirm a successful run appears
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 you self-host your infrastructure and can't send internal task data through a third-party cloud automation service. Asana task notifications can include sensitive project names, deadlines, and personnel — n8n running on your own servers keeps all of that in-house. The second reason to pick n8n: you need the Code node. The Asana webhook payload is sparse, the email-to-Slack-ID lookup requires a raw HTTP call, and the Block Kit message needs conditional logic based on event type. n8n handles all three in a single workflow. If your team has no one comfortable with JavaScript and you're on Asana Premium or above, Zapier's Asana integration is genuinely easier to configure and will have you sending notifications in 15 minutes without writing a line of code.
n8n cloud starts at $20/month for 2,500 executions. This workflow uses 4 executions per task event (trigger, IF, Asana Get, HTTP lookup, Slack send — n8n counts trigger + nodes differently depending on version, so budget 3-5 per event). At 200 task assignments per month, you're at roughly 800-1,000 executions — well within the base plan. Self-hosted n8n is free with no execution limits, which is the real cost story: if you're already running n8n for other workflows, this one adds effectively zero cost. Zapier would run you $49/month on the Team plan to access multi-step Zaps with the same logic.
Zapier has a pre-built 'Asana New Task Assigned' trigger that requires zero configuration — you pick the project and it works. No webhook setup, no API calls. That's the one thing Zapier does better here. Make's Asana module includes a built-in task watcher that handles the email-to-user lookup inside the Slack module without a separate HTTP step, which saves one node. Power Automate has an Asana connector but it's through a third-party premium connector that costs extra and has a 15-minute polling minimum — not real-time. Pipedream's Asana source component handles webhook registration automatically, same as n8n, and the code step is nearly identical syntax. n8n wins here specifically because the self-hosted option removes data residency concerns and the execution cost math works out cheaper than Zapier at any meaningful task volume.
Three things you'll hit after setup. First: Asana sends duplicate webhook events for tasks created with an assignee already set — you get both a 'task created' and 'assignee added' event within milliseconds. Without deduplication logic using n8n's static data, team members get two Slack DMs per task. Second: the Asana webhook registration silently expires if your n8n instance goes offline for more than a few hours during Asana's retry window. Asana retries for about 24 hours, then deletes the webhook. You won't know until someone notices they stopped getting notifications — check the Executions tab and the Asana webhook list weekly. Third: Asana's custom fields API returns an array of all custom fields on the task, not just Priority. If your workspace has 10 custom fields, you need to find Priority by name using Array.find() — the index position is not stable across different projects or task types.
Ideas for what to build next
- →Add a daily digest for low-priority tasks — Replace the real-time DM for Medium and Low priority assignments with a scheduled n8n workflow that batches them into a single Slack message each morning at 9am, reducing notification noise without losing visibility.
- →Post to a shared project channel in addition to DMs — Extend the workflow to also post task assignments to the relevant project's Slack channel (e.g. #project-q1-bugs) so project managers can see assignment activity without receiving personal DMs.
- →Track notification acknowledgment with Slack button interactions — Add a Slack Interactivity webhook to n8n that listens for clicks on the 'Open in Asana' button, then updates a Google Sheet or Asana custom field to log when the assignee acknowledged the task.
Related guides
How to Share Notion Meeting Notes to Slack with Pipedream
~15 min setup
How to Share Notion Meeting Notes to Slack with Power Automate
~15 min setup
How to Share Notion Meeting Notes to Slack with n8n
~20 min setup
How to Send Notion Meeting Notes to Slack with Zapier
~8 min setup
How to Share Notion Meeting Notes to Slack with Make
~12 min setup
How to Create Notion Tasks from Slack with Pipedream
~15 min setup