Intermediate~20 min setupCommunication & CRMVerified April 2026
Slack logo
Copper logo

How to Create Copper Tasks from Slack with n8n

Listens for a Slack slash command or emoji reaction, parses the message text, and creates a follow-up task in Copper CRM — no manual copy-paste required.

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

Best for

Sales teams who discuss prospects in Slack and want to log follow-up tasks in Copper without leaving the conversation.

Not ideal for

Teams that need two-way sync or want Copper task updates to post back to Slack — build a separate workflow for that.

Sync type

real-time

Use case type

routing

Real-World Example

💡

A 12-person B2B sales team at a logistics SaaS company discusses deal updates in a #prospects Slack channel. A rep types '/copper-task Follow up with Acme on pricing — due Friday' and a Copper task appears instantly on the related contact, assigned to that rep. Before this, tasks were created manually at end-of-day — or forgotten entirely — because switching to Copper mid-conversation broke focus.

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 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.

Copper API key and the email address tied to your Copper account — both required for every API request header
Slack app with slash command permissions and the commands OAuth scope enabled
Slack Bot Token (xoxb-) with users:read scope to resolve user IDs to names
n8n instance (self-hosted or n8n Cloud) with a publicly accessible webhook URL — localhost won't work unless you use a tunnel like ngrok
Copper contacts already in your CRM — this workflow looks up existing records, it doesn't create new ones

Field Mapping

Map these fields between your apps.

FieldAPI Name
Required
Task Namename
Related Resource IDrelated_resource.id
Related Resource Typerelated_resource.type
5 optional fields▸ show
Due Datedue_date
Assignee IDassignee_id
Statusstatus
Prioritypriority
Detailsdetails

Step-by-Step Setup

1

api.slack.com/apps > Your App > Slash Commands > Create New Command

Create a Slack Slash Command

Go to api.slack.com/apps, open your app (or create one), and navigate to Slash Commands in the left sidebar. Click 'Create New Command'. Set the command to /copper-task, the Request URL to a placeholder for now — you'll replace it after n8n gives you a webhook URL. Set the short description to 'Create a Copper follow-up task'.

  1. 1Go to api.slack.com/apps and open or create your Slack app
  2. 2Click 'Slash Commands' in the left sidebar
  3. 3Click the green 'Create New Command' button
  4. 4Enter '/copper-task' in the Command field
  5. 5Paste a placeholder URL in the Request URL field — you'll update it in Step 3
  6. 6Click Save
What you should see: You should see /copper-task listed under Slash Commands with a yellow 'Unverified' badge — that's expected until the webhook URL is live.
Common mistake — Slack sends slash command payloads as application/x-www-form-urlencoded, not JSON. n8n's webhook node will receive this as form data — make sure you don't assume JSON structure when parsing it in later steps.
2

api.slack.com/apps > Your App > OAuth & Permissions

Install the Slack App to Your Workspace

Navigate to 'OAuth & Permissions' in your Slack app settings. Under Bot Token Scopes, add commands and users:read. Scroll up and click 'Install to Workspace', then authorize it. Copy the Bot User OAuth Token — it starts with xoxb-. You'll need this in n8n.

  1. 1Click 'OAuth & Permissions' in the left sidebar
  2. 2Scroll to 'Bot Token Scopes' and click 'Add an OAuth Scope'
  3. 3Add 'commands' and 'users:read' scopes
  4. 4Click 'Install to Workspace' at the top of the page
  5. 5Click Allow on the authorization screen
  6. 6Copy the Bot User OAuth Token (starts with xoxb-)
What you should see: You should see a green 'Installed' badge at the top of the OAuth & Permissions page and a valid xoxb- token in the Bot User OAuth Token field.
Common mistake — The users:read scope is required to resolve a Slack user ID to a real name. Without it, your Copper task assignee field will contain a raw user ID like U04XKJL2P instead of a name.
3

n8n > New Workflow > + Add Node > Webhook

Create the n8n Workflow and Add a Webhook Trigger

Open your n8n instance and click 'New Workflow'. Add a Webhook node as the trigger. Set the HTTP Method to POST and Authentication to None (Slack signs requests with a header — you'll validate that separately). Click 'Listen for Test Event' to get the webhook URL, then copy it.

  1. 1Click 'New Workflow' in the top-left of n8n
  2. 2Click the + button to add a node and search for 'Webhook'
  3. 3Set HTTP Method to POST
  4. 4Set Path to something readable like 'copper-task'
  5. 5Click 'Listen for Test Event' — n8n will display the webhook URL
  6. 6Copy the webhook URL
What you should see: n8n shows a webhook URL ending in /webhook/copper-task and displays 'Waiting for test event...' in the node panel.
Common mistake — Copy the webhook URL carefully — it expires if you regenerate it, and any scenarios using the old URL will silently stop working.
n8n
+
click +
search apps
Slack
SL
Slack
Create the n8n Workflow and …
Slack
SL
module added
4

api.slack.com/apps > Your App > Slash Commands > /copper-task > Edit

Connect the Webhook URL to Slack

Go back to api.slack.com/apps, open your Slash Command settings, and replace the placeholder Request URL with the n8n webhook URL you just copied. Save the command. Now trigger the slash command from Slack by typing '/copper-task Test follow-up with Acme' in any channel. n8n should receive the payload immediately.

  1. 1Open your Slack app settings and click 'Slash Commands'
  2. 2Click 'Edit' next to /copper-task
  3. 3Paste the n8n webhook URL into the Request URL field
  4. 4Click Save
  5. 5Open Slack and type '/copper-task Test follow-up with Acme' in any channel
  6. 6Press Enter to send
What you should see: n8n exits the 'Waiting' state and shows the raw Slack payload in the Webhook node output. You'll see fields like text, user_id, user_name, and channel_id in the data panel.
Common mistake — Slack expects a response within 3 seconds or it will show the user an error. n8n's webhook node responds immediately with a 200 OK before your workflow continues — this is fine by default. Don't add a Respond to Webhook node that waits on downstream steps.
5

n8n Workflow Editor > + Add Node > Code

Parse the Slash Command Text

Add a Code node after the Webhook trigger. The slash command payload puts everything the user typed after /copper-task into the text field. You need to extract the task name, due date (if included), and any contact reference. Use a JavaScript regex to pull out an optional 'due:YYYY-MM-DD' pattern from the text, and treat the remainder as the task name.

  1. 1Click the + button after the Webhook node and search for 'Code'
  2. 2Set Mode to 'Run Once for All Items'
  3. 3Paste the parsing logic from the Pro Tip section below
  4. 4Click 'Execute Node' to test with the sample Slack payload
What you should see: The Code node output shows two fields: taskName (the cleaned text) and dueDate (a formatted date string like '2024-03-15' or null if no due date was in the command).
Common mistake — Slack URL-encodes the text field — spaces become '+' or '%20'. The Code node receives this already decoded by n8n's webhook parser, so don't double-decode it or you'll corrupt the string.
6

n8n Workflow Editor > + Add Node > HTTP Request

Look Up the Copper Contact or Lead

Add an HTTP Request node to search Copper for the contact mentioned in the Slack message. Copper's API endpoint for searching people is POST https://api.copper.com/developer_api/v1/people/search. Send the contact name (or email if your team includes it in the command) as the query. Set the headers to include X-PW-AccessToken, X-PW-Application (developer_api), and X-PW-UserEmail — all required by Copper.

  1. 1Add an HTTP Request node after the Code node
  2. 2Set Method to POST
  3. 3Set URL to 'https://api.copper.com/developer_api/v1/people/search'
  4. 4Add headers: X-PW-AccessToken (your Copper API key), X-PW-Application (developer_api), X-PW-UserEmail (your Copper account email), Content-Type (application/json)
  5. 5Set Body to JSON: { "name": "{{ $json.contactName }}" }
  6. 6Click Execute Node to test the search
What you should see: The HTTP Request node returns a JSON array of matching Copper contacts. The first result includes an id field — that's what you'll use as the parent record for the task.
Common mistake — Copper's people search returns partial matches. If a rep types 'Acme' and there are 3 contacts with Acme in their company name, you'll get all 3. Add an IF node after this step to check if the result array has exactly one item — if not, post a Slack message back asking the rep to be more specific.
7

n8n Workflow Editor > + Add Node > IF

Handle No-Match Results with an IF Node

Add an IF node to check whether the Copper search returned at least one result. Set the condition to check if the array length of the HTTP Request output is greater than 0. Wire the False branch to a Slack node that sends a direct message back to the user telling them no contact was found. Wire the True branch to continue to task creation.

  1. 1Add an IF node after the HTTP Request node
  2. 2Set Condition to: {{ $json.length }} > 0
  3. 3On the False branch, add a Slack node set to 'Send a Direct Message'
  4. 4Configure the Slack DM to message the original user_id with: 'No Copper contact found for that name. Try again with a full name or email.'
  5. 5On the True branch, continue to the next step
What you should see: If a contact is found, the True branch activates and passes the Copper contact ID downstream. If not, the user gets a Slack DM within seconds explaining the issue.
8

n8n Workflow Editor > + Add Node > HTTP Request

Create the Task in Copper

Add another HTTP Request node on the True branch. This one hits Copper's task creation endpoint: POST https://api.copper.com/developer_api/v1/tasks. The body needs name, due_date (Unix timestamp in milliseconds), assignee_id, and a related resource object pointing to the Copper contact ID. Map these fields from the parsed Slack payload and the contact lookup result.

  1. 1Add an HTTP Request node on the True branch of the IF node
  2. 2Set Method to POST
  3. 3Set URL to 'https://api.copper.com/developer_api/v1/tasks'
  4. 4Use the same Copper API headers from Step 6
  5. 5Set Body to JSON using the field mapping from the Field Mapping section below
  6. 6Click Execute Node to create a test task
What you should see: Copper returns a 200 response with the newly created task object, including an id field. Check your Copper account — the task should appear on the matched contact's activity timeline.
Common mistake — Copper's due_date field expects a Unix timestamp in seconds, not milliseconds. If you pass milliseconds, Copper will silently accept it but set the due date to the year 2527. Divide your timestamp by 1000 before sending.
9

n8n Workflow Editor > + Add Node > Slack

Confirm Success Back to Slack

Add a Slack node at the end of the True branch to send a confirmation message. Post to the original channel_id with a message that includes the task name, due date, and a direct link to the Copper contact. This closes the loop so the rep knows the task was created without leaving Slack.

  1. 1Add a Slack node after the Copper task creation node
  2. 2Set Operation to 'Send a Message'
  3. 3Set Channel to {{ $('Webhook').item.json.body.channel_id }}
  4. 4Set Message to: '✅ Task created in Copper: *{{ $json.taskName }}* — due {{ $json.dueDate }}. View contact: https://app.copper.com/companies/people/{{ $json.copperContactId }}'
  5. 5Add your Slack Bot Token in the credentials dropdown
  6. 6Click Execute Node
What you should see: A formatted Slack message appears in the channel where the slash command was used, confirming the task name, due date, and linking directly to the Copper contact record.
10

n8n Workflow Editor > Active Toggle (top right)

Activate the Workflow

Click the toggle in the top-right of the n8n editor to switch the workflow from inactive to active. The webhook URL is now live and will process every /copper-task command your team sends. Test end-to-end from Slack with a real contact name and check that the task appears in Copper within 5 seconds.

  1. 1Click the gray toggle in the top-right corner of the n8n workflow editor
  2. 2Confirm the toggle turns green and shows 'Active'
  3. 3Open Slack and type '/copper-task Follow up with Sarah Chen on proposal — due:2024-03-20'
  4. 4Check Copper for the new task on Sarah Chen's contact record
  5. 5Verify the Slack confirmation message appears in the channel
What you should see: The workflow runs in under 5 seconds. Copper shows the new task on the correct contact. The Slack channel shows the confirmation message with a link to the contact.
Common mistake — n8n's webhook URL changes if you move between n8n versions or reset your instance. If you self-host n8n and migrate, you'll need to update the Request URL in your Slack app's Slash Commands settings — otherwise the slash command silently fails.

This Code node runs after the Webhook trigger and before the Copper API calls. It parses the raw Slack slash command text to extract the task name, optional due date, and optional contact name — then outputs clean fields for downstream nodes. Paste this into a Code node set to 'Run Once for All Items' mode.

JavaScript — Code Node// Paste into n8n Code node (Run Once for All Items mode)
▸ Show code
// Paste into n8n Code node (Run Once for All Items mode)
// Parses Slack slash command text into structured Copper task fields
const items = $input.all();

... expand to see full code

// Paste into n8n Code node (Run Once for All Items mode)
// Parses Slack slash command text into structured Copper task fields

const items = $input.all();
const payload = items[0].json.body;

const rawText = payload.text || '';
const userId = payload.user_id || '';
const userName = payload.user_name || '';
const channelId = payload.channel_id || '';
const channelName = payload.channel_name || '';

// Extract optional due date in format due:YYYY-MM-DD
const dueDateMatch = rawText.match(/due:(\d{4}-\d{2}-\d{2})/);
const dueDateStr = dueDateMatch ? dueDateMatch[1] : null;

// Convert due date string to Unix timestamp in SECONDS (Copper requires seconds)
let dueDateUnix = null;
if (dueDateStr) {
  const dateObj = new Date(dueDateStr + 'T00:00:00Z');
  dueDateUnix = Math.floor(dateObj.getTime() / 1000);
}

// Strip the due:YYYY-MM-DD pattern from task name and clean up whitespace
const taskName = rawText
  .replace(/due:\d{4}-\d{2}-\d{2}/gi, '')
  .replace(/--/g, '-')
  .trim()
  .replace(/\s{2,}/g, ' ');

// Normalize contact name: assume contact name appears before the first dash or 'on'
// Reps type: "Follow up with Sarah Chen on proposal" — extract "Sarah Chen"
const contactMatch = taskName.match(/with ([A-Z][a-z]+ [A-Z][a-z]+)/i);
const contactName = contactMatch
  ? contactMatch[1]
      .split(' ')
      .map(w => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase())
      .join(' ')
  : null;

// Build details string for Copper task notes field
const details = `Created from #${channelName} by ${userName} via Slack slash command`;

return [
  {
    json: {
      taskName,
      dueDateUnix,
      dueDateStr,
      contactName,
      slackUserId: userId,
      slackUserName: userName,
      channelId,
      channelName,
      details,
    },
  },
];

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 n8n for this if your team self-hosts and wants full control over the Slack payload parsing logic. The Code node lets you handle edge cases — multiple contact matches, missing due dates, keyword-based priority detection — without duct-taping together three separate no-code nodes. If your Copper contact names are inconsistent (mixed case, nicknames, abbreviations), n8n's code node lets you normalize them with real JavaScript before the API call. The one scenario where you'd pick something else: if your team has zero engineering capacity and nobody wants to write even 20 lines of JavaScript, Zapier's Slack + Copper integration handles basic task creation through a form-based UI with no code required.

Cost

n8n Cloud costs $20/month for up to 2,500 workflow executions. This workflow uses 1 execution per slash command. At 50 reps each sending 3 slash commands per day, that's 150 executions/day, roughly 4,500/month — you'd hit the Starter limit and need the Pro plan at $50/month. If you self-host n8n on a $6/month VPS, the execution cost drops to zero beyond server costs. Zapier would charge per task at ~$50–75/month for the same volume on the Professional plan. Make falls in between at around $9/month on the Core plan, which covers 10,000 operations.

Tradeoffs

Zapier handles the Slack slash command trigger with a dedicated zap trigger and a pre-built Copper action — setup takes about 15 minutes with no code, but you can't customize how contacts are matched and there's no built-in fallback for multiple results. Make gives you better conditional logic through its router module, and you can branch on match count without a code node, but the Copper integration in Make is community-built and occasionally lags behind Copper's API. Power Automate has no native Copper connector — you'd use HTTP actions for everything, which puts it at the same effort level as n8n but with a worse debugging experience. Pipedream offers the cleanest code-first experience for this use case with built-in Slack and Copper API helpers, and its free tier covers 10,000 invocations/month — genuinely worth considering if you're comfortable with Node.js and want to skip the n8n UI entirely. n8n wins here because it combines visual debugging, the Code node for parsing logic, and self-hosting economics for teams who need all three.

Three things you'll hit after setup. First, Copper rate-limits API requests to 600 per minute per user — that's not a problem at normal slash command volume, but if you run load tests or batch-import tasks, you'll hit 429 errors. Add a Wait node between search and create calls if you're ever running bulk operations. Second, Slack slash commands time out at 3 seconds — if your Copper contact search is slow (sometimes it is on large databases), n8n's immediate 200 response saves you, but any visible slowness in the confirmation message will make reps think it failed. Third, Copper's API returns dates in Unix seconds but its UI displays them in the user's local timezone. A task due March 20 at midnight UTC will show as March 19 for reps in US time zones. Set your due date timestamps to noon UTC instead of midnight to avoid off-by-one day issues.

Ideas for what to build next

  • Sync Copper Task Completion Back to SlackBuild a reverse workflow that polls Copper every 15 minutes for tasks marked complete and posts a summary to the original Slack channel — closes the feedback loop for the whole team.
  • Add Emoji Reaction Trigger as an AlternativeUse the Slack Events API to listen for a specific emoji reaction (e.g. 📋) on any message, then use that message's text as the task name — lets reps create tasks from existing messages without retyping.
  • Route Tasks to the Right Copper OpportunityExtend the slash command syntax to accept an optional deal name (e.g. /copper-task deal:Acme-Q2 Follow up on pricing) and link the created task to a Copper opportunity instead of just a contact.

Related guides

Was this guide helpful?
Slack + Copper overviewn8n profile →