

How to Sync Slack Members to Copper with Pipedream
Automatically creates a Copper contact when a new member joins a designated Slack channel, keeping your CRM current without manual data entry.
Steps and UI details are based on platform versions at time of writing — check each platform for the latest interface.
Best for
Sales and partnerships teams who onboard external partners or new hires via Slack and need those people logged in Copper immediately.
Not ideal for
Teams adding hundreds of members per day — at that volume, a batch import via CSV or Copper's native Google Workspace sync is more practical.
Sync type
real-timeUse case type
syncReal-World Example
A 20-person SaaS company invites all new agency partners to a private #partners Slack channel during onboarding. Before this workflow, the sales ops manager spent 30 minutes each Friday manually cross-checking the channel member list against Copper. Now every partner invite fires a Pipedream workflow that creates the Copper contact within seconds, with name, email, and company pre-filled from their Slack profile.
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.
Optional
Field Mapping
Map these fields between your apps.
| Field | API Name | |
|---|---|---|
| Required | ||
| Full Name | name | |
| Email Address | emails | |
6 optional fields▸ show
| Job Title | title |
| Phone Number | phone_numbers |
| Company Name | company_name |
| Tags | tags |
| Slack User ID | custom_fields |
| Lead Source | lead_source |
Step-by-Step Setup
pipedream.com > Workflows > New Workflow
Create a new Pipedream workflow
Go to pipedream.com and log in. Click 'New Workflow' in the top-left dashboard. You'll land on the workflow canvas with an empty trigger slot at the top. Give the workflow a name like 'Slack → Copper Contact Sync' in the title bar so you can find it later.
- 1Click 'New Workflow' in the left sidebar
- 2Click the workflow title at the top and rename it to 'Slack → Copper Contact Sync'
- 3Click 'Add a trigger' in the first step block
Trigger > Search Apps > Slack > Member Joined Channel
Set the Slack trigger: member joined channel
In the trigger search box, type 'Slack' and select it. Browse the event list and choose 'Member Joined Channel'. This trigger uses Slack's Events API under the hood — Pipedream registers a webhook URL with Slack automatically when you connect your account. You do not need to manually configure a Slack app.
- 1Type 'Slack' in the trigger search bar
- 2Select 'Slack' from the app results
- 3Click 'Member Joined Channel' from the event list
- 4Click 'Connect a Slack account' and authorize via OAuth
- 5Select the specific Slack channel to monitor from the dropdown (e.g., #partners)
Trigger > Generate Test Event
Test the trigger with a real event
Click 'Generate Test Event' at the bottom of the trigger panel. Pipedream will prompt you to actually add a member to your selected Slack channel to produce a live payload. Do this in Slack — invite a test user or yourself to the channel. Once the event fires, Pipedream captures the raw JSON and displays it in the trigger output panel.
- 1Click 'Generate Test Event'
- 2Open Slack and add a member to the monitored channel
- 3Return to Pipedream and click 'Refresh' if the event hasn't appeared
- 4Expand the event payload to confirm you see 'user', 'channel', and 'event_ts' fields
Steps > Add Step > Slack > Get User
Add a Slack step to fetch the user's profile
Click the '+' button below the trigger to add a new step. Search for 'Slack' and select the 'Get User' action. This calls the Slack users.info API endpoint using the user ID from the trigger event. Map the user ID field to the trigger output: steps.trigger.event.event.user. This returns the full profile including display name, real name, email, title, and company.
- 1Click the '+' button below the trigger block
- 2Search for 'Slack' and select it
- 3Choose 'Get User' from the action list
- 4In the 'User ID' field, click the reference picker and select steps.trigger.event.event.user
- 5Click 'Test' to run this step and confirm the profile returns
Steps > Add Step > Run Node.js code
Add a Node.js code step to check for duplicates
Before creating the Copper contact, you need to verify one doesn't already exist with that email. Click '+' and choose 'Run Node.js code'. Write a fetch call to the Copper People Search API using the email from the Slack profile. If Copper returns a non-empty results array, you can either skip creation or update the existing record. This prevents duplicate contacts when someone leaves and rejoins the channel.
- 1Click the '+' button below the Get User step
- 2Select 'Run Node.js code'
- 3Paste the duplicate-check code (see pro tip below)
- 4Click 'Test' to run the step and inspect the output
This code handles three things in one step: duplicate checking via Copper's People Search API, email format validation, and graceful exit if the contact already exists. Paste this as a 'Run Node.js code' step between your Slack Get User step and the Copper Create Person step.
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, $ }) {
const userProfile = steps.get_user.user.profile;
const email = userProfile?.email;
// Guard: no email means we can't create a usable Copper contact
if (!email) {
$.flow.exit('Skipping: Slack user has no email address in their profile.');
}
const copperEmail = process.env.COPPER_EMAIL;
const copperApiKey = process.env.COPPER_API_KEY;
const authHeader = Buffer.from(`${copperEmail}:${copperApiKey}`).toString('base64');
// Search Copper for an existing contact with this email
const searchResponse = await axios.post(
'https://api.copper.com/developer_api/v1/people/search',
{ emails: [email] },
{
headers: {
'X-PW-AccessToken': copperApiKey,
'X-PW-Application': 'developer_api',
'X-PW-UserEmail': copperEmail,
'Content-Type': 'application/json',
},
}
);
const existingContacts = searchResponse.data;
if (existingContacts.length > 0) {
const existing = existingContacts[0];
console.log(`Duplicate found: Copper Person ID ${existing.id} already has email ${email}`);
$.flow.exit(`Skipping: Contact already exists in Copper (ID: ${existing.id}).`);
}
// Format data for the Copper Create Person step
$.export('contactPayload', {
name: userProfile.real_name || steps.get_user.user.name,
emails: [{ email, category: 'work' }],
phone_numbers: userProfile.phone
? [{ number: userProfile.phone, category: 'work' }]
: [],
title: userProfile.title || null,
company_name: userProfile.company || null,
tags: ['slack-partners'],
lead_source: 'Slack',
});
console.log(`Ready to create Copper contact for ${email}`);
},
});
Steps > Add Step > Run Node.js code
Add a conditional step to gate contact creation
Click '+' and add another 'Run Node.js code' step. Write a simple conditional that checks whether the previous step returned an existing contact ID. If it did, export a flag like $.export('should_create', false). If it didn't, export $.export('should_create', true). The next step will read this flag to decide whether to proceed.
- 1Click '+' to add a new code step
- 2Write the conditional check against the duplicate-check step output
- 3Use $.export('should_create', true/false) to pass the decision downstream
- 4Click 'Test' to confirm the exported value appears in the step output
Steps > Add Step > Copper > Create Person
Add the Copper 'Create Person' step
Click '+' and search for 'Copper'. Select the 'Create Person' action. Connect your Copper account using your Copper API key and registered email — both are found in Copper under Settings > Integrations > API. Map the fields from the Slack profile step: Name from steps.get_user.user.real_name, Email from steps.get_user.user.profile.email, Title from steps.get_user.user.profile.title, Phone from steps.get_user.user.profile.phone.
- 1Click '+' and search for 'Copper'
- 2Select 'Create Person'
- 3Click 'Connect a Copper account' and enter your API key and email
- 4Map 'Name' to steps.get_user.user.real_name
- 5Map 'Email' to steps.get_user.user.profile.email
- 6Map 'Title' to steps.get_user.user.profile.title
Steps > Copper > Create Person > tags field
Add a tag to the Copper contact
Immediately after the Create Person step, add another Copper step or extend the create payload to include tags. Tag the contact with the Slack channel name (e.g., 'slack-partners') so your team knows exactly how this contact entered Copper. This is especially useful when you run the same workflow across multiple channels.
- 1In the Copper Create Person step, scroll to the optional 'Tags' field
- 2Click the reference picker and type the channel name as a static string, e.g., 'slack-partners'
- 3Or reference steps.trigger.event.event.channel dynamically if you want the actual channel ID as a tag
Steps > Add Step > Run Node.js code
Add error handling for failed contact creation
Click '+' after the Copper step and add a 'Run Node.js code' step. Wrap the logic in a try/catch and use $.flow.exit() to gracefully stop the workflow if Copper returns an error. Optionally, send a Slack DM to a designated admin using the Slack 'Send Message' action if the creation fails — this gives you visibility without checking Pipedream logs manually.
- 1Click '+' to add a code step after the Copper step
- 2Check if the Copper step output contains an error property
- 3If error exists, call $.flow.exit('Contact creation failed: ' + error.message)
- 4Optionally add a Slack step after to DM your admin channel with the failure details
Workflow Canvas > Deploy > Executions tab
Deploy and test with a live channel join
Click 'Deploy' in the top-right corner of the canvas. The workflow is now live and listening for Slack events. Test it by adding a real user to your monitored Slack channel. Switch to Pipedream's Executions tab (left sidebar) and watch for a new execution to appear within seconds. Click into the execution to see each step's input and output.
- 1Click the blue 'Deploy' button in the top-right
- 2Open Slack and add a test user to the monitored channel
- 3Return to Pipedream and click 'Executions' in the left sidebar
- 4Click the most recent execution to inspect each step's output
- 5Verify the new contact appears in Copper under People
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 any tolerance for Node.js and wants the contact created in under 10 seconds with zero infrastructure overhead. The key reason Pipedream wins here specifically: the Slack 'Member Joined Channel' webhook fires instantly, and Pipedream processes it without the polling delays you'd get from Make or Zapier's free tiers. The one scenario where you'd pick something else: if everyone on your team is non-technical and needs to maintain this workflow themselves — Zapier's UI is more forgiving for people who've never read a JSON payload.
Pipedream's free tier gives you 10,000 credits per month. This workflow costs roughly 3-4 credits per execution (trigger + profile lookup + code steps + Copper write). At 50 new channel members per month — a realistic number for a mid-size SaaS company — you're burning around 200 credits. That's 2% of your free monthly allowance. You'd need to be onboarding 2,500+ contacts per month before hitting the free tier ceiling. Zapier charges $49/month for the equivalent Zap at 750 tasks. Make's free tier caps at 1,000 operations/month and would handle the same volume. For this specific use case, Pipedream is either free or dramatically cheaper than Zapier.
Make has one genuine edge here: its visual flow canvas makes the conditional duplicate-check logic easier to follow without reading code. Zapier has a pre-built Copper integration with better field mapping UI — you won't need to format email arrays manually. n8n handles the Slack profile enrichment step natively without writing fetch calls, which saves 10 minutes of setup. Power Automate has no meaningful Copper connector, so cross it off the list entirely for this workflow. Despite those advantages elsewhere, Pipedream is still the right call here because the Slack Events API webhook handling is instantaneous, the Node.js step gives you full control over the duplicate logic and email formatting, and you won't pay anything meaningful until you're onboarding at scale.
Three things you'll hit after launch. First: Slack guest accounts (external users invited to a channel) often have no email address in their profile. Your workflow will throw a Copper 422 error unless you check for a null email before the create step. Second: Copper's People Search API only matches exact emails — if a partner uses a different email than the one in Copper, you'll create a duplicate. Store the Slack user ID in a Copper custom field on first creation and check that field on re-joins. Third: if you're monitoring a high-traffic channel and multiple people join within seconds of each other, Pipedream will spawn concurrent executions. Each will independently query Copper before the others finish writing — meaning two executions can both pass the duplicate check and both create a contact for the same person. Add a small delay step (500ms) and accept that true race conditions at this scale require a dedicated deduplication table outside Copper.
Ideas for what to build next
- →Sync Copper Updates Back to Slack — When a Copper contact's status changes (e.g., marked as a Customer), post an automated message to the original Slack channel. This closes the loop between your CRM and the team managing the relationship.
- →Enrich Contacts with Clearbit After Creation — Add a Clearbit Enrichment step in Pipedream immediately after the Copper Create Person step. Use the email to pull company size, industry, LinkedIn URL, and funding stage, then update the Copper contact with those fields automatically.
- →Monitor Multiple Channels with One Workflow — Extend the workflow to watch several Slack channels (e.g., #partners, #clients, #vendors) and tag each Copper contact with the specific channel name they joined. Use a Pipedream filter step to route contacts to different Copper pipelines based on channel.
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