Intermediate~15 min setupCommunication & Project ManagementVerified April 2026
Slack logo
Asana logo

How to Create Asana Tasks from Slack Messages with Pipedream

When a client mentions an issue in a shared Slack channel, Pipedream instantly creates an Asana task with the message text, sender, channel, priority, and a direct Slack link.

Steps and UI details are based on platform versions at time of writing — check each platform for the latest interface.

Best for

Client-facing teams who share Slack channels with clients and need every reported issue captured as a tracked Asana task without manual copy-paste

Not ideal for

Teams where clients submit issues via email or a ticketing form — use a Jira or Help Scout integration instead

Sync type

real-time

Use case type

routing

Real-World Example

💡

A 12-person agency runs shared Slack channels with each of their 8 clients. Before this workflow, account managers screenshotted client complaints and manually created Asana tasks hours later — sometimes the next morning. Now, any message in a #client- channel that contains trigger words like 'broken', 'error', or 'urgent' creates an Asana task in that client's project within 10 seconds, tagged with priority level and a direct link back to the Slack thread.

What Will This Cost?

Drag the slider to your expected monthly volume.

/mo
505005K50K

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

Skip the setup

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.

Slack workspace admin access or permission to install the Pipedream app — required to authorize the Events API subscription
Asana account with edit access to the client project where tasks will be created — read-only access won't work for task creation
Pipedream account on the free tier or higher — free tier allows up to 10,000 invocations/month which covers most small agency setups
Asana project GID for each client project — find it in the project URL after /0/ e.g. asana.com/0/1234567890/list
List of client Slack channel IDs (not names) — copy from the channel URL or use Slack's conversations.list API to retrieve them

Field Mapping

Map these fields between your apps.

FieldAPI Name
Required
Task Namename
Task Notes / Descriptionnotes
Project GIDprojects
Slack Channel IDnotes
Reporter Namenotes
4 optional fields▸ show
Priority (Custom Field)custom_fields
Assigneeassignee
Due Datedue_on
Slack Message Timestampnotes

Step-by-Step Setup

1

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. You'll land on a blank canvas with a trigger slot at the top. This is where you'll wire in the Slack source. Name the workflow something specific like 'Slack Client Issue → Asana Task' so it's easy to find later.

  1. 1Log in at pipedream.com
  2. 2Click 'Workflows' in the left nav
  3. 3Click the blue 'New Workflow' button
  4. 4Click the workflow title at the top and rename it to 'Slack Client Issue → Asana Task'
What you should see: You should see a blank workflow canvas with a gray 'Add a trigger' block at the top and an empty steps area below it.
2

Workflow Canvas > Add a trigger > Slack > New Message Posted to Channel

Add a Slack trigger for new channel messages

Click the 'Add a trigger' block. Search for 'Slack' in the app search box and select it. From the list of triggers, choose 'New Message Posted to Channel'. This trigger uses a Slack webhook under the hood — Pipedream registers a bot in your workspace that receives message events instantly. You'll see a 'Select a Connected Account' dropdown appear.

  1. 1Click the gray 'Add a trigger' block
  2. 2Type 'Slack' in the search field
  3. 3Select 'Slack' from the app results
  4. 4Choose 'New Message Posted to Channel' from the trigger list
What you should see: The trigger configuration panel opens on the right side showing fields for Connected Account, Channel, and optional filters.
Common mistake — Slack's Events API requires your workspace to install the Pipedream app. If your IT team restricts third-party app installs, you'll need admin approval before this trigger can fire.
message template
🔔 New Record: {{text}} {{user}}
channel: {{channel}}
ts: {{ts}}
#sales
🔔 New Record: Jane Smith
Company: Acme Corp
3

Trigger Config Panel > Connected Account > Connect a new account

Connect your Slack account and configure the channel

In the 'Connected Account' dropdown, click 'Connect a new account'. Pipedream opens an OAuth window — log in with the Slack workspace where your shared client channels live. Once connected, return to the Channel field and type or select the specific client channel you want to monitor (e.g., #client-acme). If you want to monitor all channels matching a pattern, you'll handle that in a filter step — for now, pick one channel to test.

  1. 1Click 'Connect a new account' in the Connected Account dropdown
  2. 2Complete the Slack OAuth flow in the popup window
  3. 3Return to the Channel field and select your target client channel
  4. 4Leave 'Resolve Names' set to true so usernames appear readable
What you should see: You should see a green checkmark next to your Slack workspace name and the selected channel name populated in the Channel field.
Common mistake — The connected Slack account must be a workspace admin or have been granted the channels:read and channels:history OAuth scopes. A standard member account will authenticate but the trigger will silently fail to receive messages from private channels.
Pipedream settings
Connection
Choose a connection…Add
click Add
Slack
Log in to authorize
Authorize Pipedream
popup window
Connected
green checkmark
4

Trigger Config Panel > Test button

Test the Slack trigger with a real message

Click the 'Test' button at the bottom of the trigger config panel. Pipedream will wait for an incoming event. Go to Slack and post a test message in the configured channel — something like 'The login page is broken again, urgent fix needed.' Return to Pipedream within 30 seconds. You should see the raw event payload appear in the trigger output panel on the right.

  1. 1Click the 'Test' button in the trigger configuration panel
  2. 2Switch to Slack and post a message in the target channel
  3. 3Return to Pipedream and wait for the event to appear
  4. 4Click the event to expand and inspect the full JSON payload
What you should see: The trigger output panel shows a JSON object with fields including event.text, event.user, event.channel, event.ts, and event.thread_ts. The message text you typed should appear in event.text.
Common mistake — Map fields using the variable picker — don't type field names manually. Hand-typed variable names often have invisible spacing errors that produce blank output.
Pipedream
▶ Deploy & test
executed
Slack
Asana
Asana
🔔 notification
received
5

Workflow Canvas > + Add Step > Run Node.js code

Add a Node.js code step to extract and classify the message

Click the '+' button below the trigger to add a new step. Select 'Run Node.js code'. This step pulls the relevant fields out of the Slack event and assigns a priority level based on keywords in the message text. You'll write a short async function that checks for words like 'urgent', 'critical', 'broken', or 'error' and outputs a priority string. This parsed data feeds into the Asana step cleanly without complex field references.

  1. 1Click the '+' icon below the trigger block
  2. 2Select 'Run Node.js code' from the step options
  3. 3Paste the code from the Pro Tip section into the code editor
  4. 4Click 'Test' to run the step against the trigger event you captured
What you should see: The step output shows a JSON object with fields: taskName, priority, clientContext, slackLink, channelId, and senderUserId — all ready to pass to Asana.
Common mistake — Pipedream's code steps run on Node.js 18. If you paste code that uses top-level await outside an async function, it will throw a syntax error. Always wrap your logic inside the default export async function.

Paste this into the Node.js 'classify' step (Step 5). It extracts the message, assigns a priority based on keyword matching, builds the Slack deep link, and exports a clean object that every downstream step references — no repeated string parsing needed.

JavaScript — Code Stepexport default defineComponent({
▸ Show code
export default defineComponent({
  async run({ steps, $ }) {
    const event = steps.trigger.event;

... expand to see full code

export default defineComponent({
  async run({ steps, $ }) {
    const event = steps.trigger.event;
    const messageText = event.text || '';
    const channelId = event.channel;
    const teamId = event.team;
    const ts = event.ts;

    // Build Slack deep link — format: slack://channel?team=T...&id=C...&message=ts_without_dot
    const tsFormatted = ts.replace('.', '');
    const slackLink = `https://slack.com/archives/${channelId}/p${tsFormatted}`;

    // Priority classification via keyword matching (case-insensitive)
    const highPriorityKeywords = ['urgent', 'critical', 'broken', 'down', 'outage', 'error', 'asap', 'emergency'];
    const mediumPriorityKeywords = ['issue', 'problem', 'wrong', 'incorrect', 'fix', 'bug', 'not working'];

    const lowerText = messageText.toLowerCase();
    let priority = 'Normal';

    if (highPriorityKeywords.some(kw => lowerText.includes(kw))) {
      priority = 'High';
    } else if (mediumPriorityKeywords.some(kw => lowerText.includes(kw))) {
      priority = 'Medium';
    }

    // Truncate message to 80 chars for the task name, keep full text for notes
    const truncated = messageText.length > 80
      ? messageText.substring(0, 77) + '...'
      : messageText;

    const taskName = `[CLIENT] ${truncated}`;

    // Due date: today + 1 day for High, null otherwise
    let dueOn = null;
    if (priority === 'High') {
      const tomorrow = new Date();
      tomorrow.setDate(tomorrow.getDate() + 1);
      dueOn = tomorrow.toISOString().split('T')[0]; // format: YYYY-MM-DD
    }

    return {
      taskName,
      priority,
      slackLink,
      dueOn,
      channelId,
      teamId,
      rawMessage: messageText,
      senderUserId: event.user,
    };
  }
});
6

Workflow Canvas > + Add Step > Run Node.js code

Resolve the Slack user ID to a readable name

The Slack event gives you event.user as a user ID like 'U04XKJZ12'. Asana task descriptions should show 'Reported by: Jane Smith', not a raw ID. Add another Node.js code step that calls the Slack users.info API using the user ID from the previous step. Use the connected Slack account's OAuth token, which Pipedream exposes via auths.slack.oauth_access_token. Extract profile.real_name from the response.

  1. 1Click '+' below the classification step
  2. 2Select 'Run Node.js code'
  3. 3Reference auths.slack.oauth_access_token for the API call
  4. 4Extract profile.real_name from the users.info response
  5. 5Export the resolved name as senderName
What you should see: The step output shows senderName as a plain string like 'Jane Smith' instead of the raw Slack user ID.
Common mistake — The Slack users.info endpoint is rate-limited to 20 requests per minute on most plans. If you're processing bursts of messages, add a 1-second delay between calls using await new Promise(r => setTimeout(r, 1000)).

Paste this into the Node.js 'classify' step (Step 5). It extracts the message, assigns a priority based on keyword matching, builds the Slack deep link, and exports a clean object that every downstream step references — no repeated string parsing needed.

JavaScript — Code Stepexport default defineComponent({
▸ Show code
export default defineComponent({
  async run({ steps, $ }) {
    const event = steps.trigger.event;

... expand to see full code

export default defineComponent({
  async run({ steps, $ }) {
    const event = steps.trigger.event;
    const messageText = event.text || '';
    const channelId = event.channel;
    const teamId = event.team;
    const ts = event.ts;

    // Build Slack deep link — format: slack://channel?team=T...&id=C...&message=ts_without_dot
    const tsFormatted = ts.replace('.', '');
    const slackLink = `https://slack.com/archives/${channelId}/p${tsFormatted}`;

    // Priority classification via keyword matching (case-insensitive)
    const highPriorityKeywords = ['urgent', 'critical', 'broken', 'down', 'outage', 'error', 'asap', 'emergency'];
    const mediumPriorityKeywords = ['issue', 'problem', 'wrong', 'incorrect', 'fix', 'bug', 'not working'];

    const lowerText = messageText.toLowerCase();
    let priority = 'Normal';

    if (highPriorityKeywords.some(kw => lowerText.includes(kw))) {
      priority = 'High';
    } else if (mediumPriorityKeywords.some(kw => lowerText.includes(kw))) {
      priority = 'Medium';
    }

    // Truncate message to 80 chars for the task name, keep full text for notes
    const truncated = messageText.length > 80
      ? messageText.substring(0, 77) + '...'
      : messageText;

    const taskName = `[CLIENT] ${truncated}`;

    // Due date: today + 1 day for High, null otherwise
    let dueOn = null;
    if (priority === 'High') {
      const tomorrow = new Date();
      tomorrow.setDate(tomorrow.getDate() + 1);
      dueOn = tomorrow.toISOString().split('T')[0]; // format: YYYY-MM-DD
    }

    return {
      taskName,
      priority,
      slackLink,
      dueOn,
      channelId,
      teamId,
      rawMessage: messageText,
      senderUserId: event.user,
    };
  }
});
7

Workflow Canvas > + Add Step > Asana > Create Task

Connect Asana and map the target project

Click '+' to add another step. Search for 'Asana' and select it. Choose the 'Create Task' action. Click 'Connect a new account' and complete the Asana OAuth flow. Once connected, the Project field appears — paste your Asana project GID or select the project from the dropdown. Each client should have a dedicated Asana project; select the one that matches the Slack channel you configured in Step 3.

  1. 1Click '+' below the user resolution step
  2. 2Search for 'Asana' and select it
  3. 3Choose 'Create Task' from the action list
  4. 4Click 'Connect a new account' and complete Asana OAuth
  5. 5Select the target client project from the Project dropdown
What you should see: The Asana step configuration panel shows fields for Name, Notes, Projects, Assignee, Due Date, and Custom Fields, with your connected Asana workspace visible in the account selector.
Common mistake — Asana's OAuth scopes during Pipedream connection default to your personal projects. If the client project is inside a team workspace, make sure you select the correct workspace during OAuth — you can't change it without reconnecting the account.
Slack fields
text
user
channel
ts
thread_ts
available as variables:
1.props.text
1.props.user
1.props.channel
1.props.ts
1.props.thread_ts
8

Asana Step Config > Name / Notes / Custom Fields

Map Slack message data to Asana task fields

In the Asana 'Create Task' step, reference the outputs from your Node.js steps using Pipedream's variable picker (the double-brace syntax or the UI picker). Set the task Name to the extracted taskName, Notes to the full clientContext string including the Slack message link, and add a custom field or tag for priority. If your Asana project has a Priority custom field, reference its GID in the Custom Fields section.

  1. 1Click the Name field and reference steps.classify.taskName
  2. 2Click the Notes field and reference steps.classify.clientContext
  3. 3Set the Assignee field to the default account manager's Asana user GID
  4. 4Add the priority tag by referencing steps.classify.priority
  5. 5Set Due Date to tomorrow's date using a date expression if priority is High
What you should see: Each field in the Asana step shows a variable reference in curly braces rather than static text, confirming the data will flow dynamically from each Slack message.
Common mistake — Map fields using the variable picker — don't type field names manually. Hand-typed variable names often have invisible spacing errors that produce blank output.
9

Workflow Canvas > + Add Step (between trigger and classify) > Filter

Add a filter to avoid creating tasks for bot messages

Slack channels with integrations will flood your Asana project with bot noise — status updates, deploy notifications, CI alerts. Add a Filter step between the trigger and the classification step. Set the condition to: event.bot_id is empty AND event.subtype is not equal to 'bot_message'. This ensures only real human messages from your clients reach the task creation logic.

  1. 1Click '+' between the trigger and the Node.js classify step
  2. 2Select 'Filter' from the step options
  3. 3Set Condition 1: steps.trigger.event.bot_id must be EMPTY
  4. 4Set Condition 2: steps.trigger.event.subtype must NOT EQUAL 'bot_message'
  5. 5Set the filter to require ALL conditions to pass
What you should see: When you test the filter with a normal message, it shows 'Passed' in green. When you test it with a simulated bot event, it shows 'Halted' — meaning the workflow stops and no Asana task is created.
Common mistake — Pipedream counts halted executions against your monthly event quota the same as completed ones. If bot traffic is heavy, consider restricting the Slack trigger to only fire for specific user IDs at the source level instead of filtering downstream.
Slack
SL
trigger
filter
Condition
matches criteria?
yes — passes through
no — skipped
Asana
AS
notified
10

Workflow Canvas > + Add Step > Slack > Send Message

Send a Slack confirmation back to the thread

Add one more Asana step or a Slack step at the end to post a threaded reply confirming the task was created. Use Slack's 'Send Message' action and set thread_ts to the original event.ts so the reply appears inside the message thread, not in the main channel. Include the Asana task URL from the previous step's output so the client can see the task was captured.

  1. 1Click '+' below the Asana Create Task step
  2. 2Search for 'Slack' and select 'Send Message'
  3. 3Set Channel to steps.trigger.event.channel
  4. 4Set Thread TS to steps.trigger.event.ts to reply in-thread
  5. 5Set Text to a message like '✅ Task created in Asana: [link from Asana step output]'
What you should see: After a full test run, you should see a threaded reply appear under the original client message in Slack with a direct link to the newly created Asana task.
Common mistake — If you set channel to the channel name instead of the channel ID, the Slack API will reject it with a 'channel_not_found' error. Always use the channel ID (format: C04XKJZ12) pulled directly from the trigger event payload.
11

Workflow Canvas > Deploy button > Event History tab

Deploy the workflow and verify live behavior

Click the blue 'Deploy' button in the top right of the workflow canvas. Pipedream activates the Slack event subscription and your workflow is now live. Post a real test message in the client channel from a non-bot Slack account. Within 10 seconds you should see a new task in Asana and a threaded confirmation in Slack. Check the Pipedream event history tab to confirm the execution completed without errors.

  1. 1Click the blue 'Deploy' button in the top right
  2. 2Confirm the workflow status shows 'Active' (green dot in the sidebar)
  3. 3Post a test message in the Slack channel
  4. 4Check Asana for the new task within 10-15 seconds
  5. 5Open the Event History tab in Pipedream to review the full execution log
What you should see: The Event History tab shows a completed execution with green checkmarks on every step. The Asana project shows a new task with the correct name, notes, and priority. The Slack thread shows the confirmation reply.

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

VerdictWhy n8n for this workflow

Use Pipedream for this if your team has someone comfortable writing 20 lines of JavaScript and you want the task created within 5 seconds of the Slack message posting. Pipedream's webhook processing is genuinely fast — sub-10-second end-to-end is consistent, not aspirational. The second reason to pick Pipedream: the keyword-to-priority logic and user ID resolution both require code, and doing that in Pipedream's Node.js steps is cleaner than duct-taping Zapier Formatter fields together. The one scenario where you'd pick something else: if your team is non-technical and wants to configure this via dropdowns, use Zapier — the same workflow takes 12 minutes to set up without touching code.

Cost

Pipedream's free tier gives you 10,000 invocations/month and 30 compute seconds per execution. This workflow runs in under 3 seconds per trigger (Slack webhook + two code steps + Asana API call + Slack reply). At 200 client messages/month across all channels, you're using 2% of your free quota. At 2,000 messages/month — a busier agency with 10+ client channels — you're still under the free limit. If you exceed 10,000 events/month, the Basic plan is $19/month for 100,000 invocations. Zapier's equivalent would cost $49/month for a similar volume on their Professional plan. Make handles 10,000 operations/month free but counts each step as a separate operation — this 5-step workflow burns 5x the quota per run.

Tradeoffs

Zapier has a pre-built 'Slack to Asana' Zap template that requires zero code and takes 8 minutes — it wins on setup speed but can't do keyword classification or user ID resolution without a $49/month Formatter add-on. Make's scenario builder handles conditional priority logic well using its built-in if() expressions, and its free tier is generous, but the visual router gets complicated fast when you add the user lookup branch. n8n can do everything Pipedream does here but requires self-hosting or a paid cloud plan starting at $20/month — not worth it unless you already run n8n for other workflows. Power Automate has a native Slack connector that's unreliable; Microsoft's Slack integration lags behind and the trigger fires on a 1-5 minute poll rather than instant webhook. For this specific use case, Pipedream is the right call if you can write basic JavaScript. If you can't, use Zapier.

Three things you'll hit after going live. First, Slack's Events API occasionally delivers duplicate events under high load — the same message fires the workflow twice within 2-3 seconds. Add deduplication by storing event.ts in Pipedream's built-in key-value store ($.store) and halting if that timestamp was already processed. Second, Asana's task creation API returns a 403 if the connected account's token expires — Asana tokens don't auto-refresh unless you reconnect. Check Connected Accounts monthly. Third, the Slack users.info lookup fails with 'user_not_found' for shared channel external users who are guests from another workspace — their user IDs are prefixed differently. Handle this with a try/catch in the resolution step and fall back to displaying the raw user ID rather than crashing the workflow.

Ideas for what to build next

  • Route tasks to different Asana projects per client channelAdd a mapping object in the Node.js classify step that maps Slack channel IDs to Asana project GIDs. This lets one workflow handle all client channels instead of deploying a separate workflow per client.
  • Post a daily digest of open client tasks to a Slack channelCreate a second Pipedream workflow on a scheduled trigger that queries Asana for open tasks tagged with a client label and posts a formatted summary to your internal #client-ops channel every morning at 9am.
  • Sync Asana task status back to Slack when a task is completedAdd a reverse workflow triggered by Asana's 'Task Completed' webhook that posts a resolution message in the original Slack thread, closing the loop with the client automatically without manual follow-up.

Related guides

Was this guide helpful?
Slack + Asana overviewPipedream profile →