

How to Log Slack Messages to Copper CRM with Make
When a message is posted in a designated Slack channel, Make captures it instantly and creates an activity note on the matching Copper contact record.
Steps and UI details are based on platform versions at time of writing — check each platform for the latest interface.
Best for
Sales or CS teams using Slack for customer conversations who need every interaction captured in Copper without manual copy-paste
Not ideal for
Teams who want to log every Slack message company-wide — scope this to specific channels or you will flood Copper with noise
Sync type
real-timeUse case type
syncReal-World Example
A 12-person B2B SaaS company creates a dedicated Slack channel per customer during onboarding. Their CS reps were copying key messages into Copper by hand, taking 5-10 minutes per conversation and frequently skipping it under deadline pressure. With this scenario running, every message posted in those channels lands in Copper as a timestamped activity note within 30 seconds — no manual entry.
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 Make
Copy the pre-built Make blueprint and paste it straight into Make. 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 | ||
| Contact ID (Parent) | parent.id | |
| Parent Type | parent.type | |
| Activity Type | type.id | |
| Activity Details | details | |
| Activity Date | activity_date | |
| Slack Message Text | ||
| Slack User Email | ||
| Slack Message Timestamp (ts) | ||
2 optional fields▸ show
| Slack Sender Display Name | |
| Slack Channel Name |
Step-by-Step Setup
make.com > Scenarios > Create a new scenario
Create a new scenario in Make
Log into make.com and click the blue 'Create a new scenario' button in the top-right of your dashboard. You will land on the visual scenario builder — a blank canvas with a large plus icon in the center. This is where you add your first module. Give the scenario a name right away by clicking the default title at the top; name it something like 'Slack → Copper: Log Customer Messages' so it's immediately identifiable in your scenario list.
- 1Click 'Create a new scenario' in the top-right
- 2Click the large plus icon on the canvas to open the app picker
- 3Type 'Slack' in the search bar
- 4Select 'Slack' from the results
Scenario Canvas > Slack Module > Watch Messages
Configure the Slack trigger: Watch Messages
From the Slack module list, select 'Watch Messages' as your trigger — this fires instantly when a new message is posted in a channel you specify. You will be prompted to connect your Slack workspace if you haven't already; click 'Add' and follow the OAuth flow. Once connected, set the Channel field to the specific customer-facing channel you want to monitor, such as #customer-acme or a channel group pattern. Set the trigger to watch 'New Messages' only, not thread replies, unless you want replies logged too.
- 1Select 'Watch Messages' from the Slack trigger list
- 2Click 'Add' next to the Connection field to authenticate with Slack
- 3Authorize Make in the Slack OAuth popup
- 4Set the Channel dropdown to your target customer channel
- 5Set 'Message type' to 'Messages' (not replies) unless you need both
📬 New entry: {{1.name}}
Email: {{1.email}}
Details: {{1.description}}Scenario Canvas > Add Module > Slack > Get User Info
Add a Text Parser to extract contact email
Most Slack messages won't contain the customer email directly, but Slack user profiles often do. Add a 'Tools > Get a Variable' module or, more practically, add the Slack 'Get User Info' module to resolve the message sender's Slack user ID into a real name and email address. Connect it immediately after the trigger. Map the 'User' field from the Watch Messages output (it returns a user ID like U04XKPL2B) into the 'User ID' field of Get User Info. This email is what you will use to look up the matching Copper contact in the next step.
- 1Click the right edge of the Slack trigger module to add a new module
- 2Search for 'Slack' and select it
- 3Choose 'Get User Info' from the action list
- 4Map the 'User' output from the Watch Messages trigger into the 'User ID' field
- 5Save the module
Scenario Canvas > Add Module > Copper > Search Contacts
Search Copper for the matching contact
Add a Copper module and choose 'Search Contacts'. Connect your Copper account via OAuth — Make uses Copper's v1 REST API, and you will need your Copper API key plus the email address associated with your Copper account for authentication. In the search filter, map the email from the Slack Get User Info output (profile.email) into the Email search field. This locates the Copper contact record that matches the person who sent the Slack message. If no match is found, you can route the scenario differently using a Router in the next step.
- 1Click the plus icon after the Get User Info module
- 2Search for 'Copper' and select it
- 3Choose 'Search Contacts' from the action list
- 4Click 'Add' to connect Copper — enter your Copper API key and account email
- 5Map 'profile.email' from the Slack module into the Email filter field
Scenario Canvas > Connection Line > Add Router
Add a Router to handle missing contacts
Not every Slack user will have a matching Copper contact — internal team members, bots, and new prospects won't be found. Add a Router module after the Search Contacts step. This splits your scenario into two paths: one for when a contact is found, one for when it isn't. The Router in Make is added by clicking the small wrench icon on the connection line between modules and selecting 'Add a router'. You will set conditions on each path in the next step.
- 1Right-click the connection line after the Copper Search Contacts module
- 2Select 'Add a router' from the context menu
- 3Two output paths appear from the Router node
- 4Label Path 1 'Contact Found' and Path 2 'No Contact — Skip'
Scenario Canvas > Router > Filter Icon
Set filter conditions on each Router path
Click the filter icon on Path 1 and set the condition: the Copper Search Contacts result ID field 'Exists' (is not empty). This means a contact was found. On Path 2, set the opposite condition: ID 'Does not exist'. For Path 2, you can simply add a Slack module to post a message to a private admin channel like #crm-alerts saying a Slack message had no matching Copper contact — giving your team a chance to create the contact manually. This prevents silent data loss.
- 1Click the filter icon on the first Router path
- 2Set Field to the Copper contact ID output token
- 3Set Condition to 'Exists'
- 4Click the filter icon on the second path
- 5Set the same field with condition 'Does not exist'
Scenario Canvas > Router Path 1 > Copper > Create Activity
Add Copper 'Create Activity' on the matched-contact path
On Path 1, add a Copper module and select 'Create Activity'. This is where the Slack message gets written to the contact's timeline in Copper. Set the 'Parent Type' to 'contact' and map the Copper contact ID from the Search Contacts output into the 'Parent ID' field. Set the Activity Type to 'Note' — Copper supports custom activity types too, but Note is universally available. In the Details field, you will build a formatted string combining the Slack message text, sender name, channel name, and timestamp.
- 1Click the plus icon on Path 1 of the Router
- 2Search for and select 'Copper'
- 3Choose 'Create Activity'
- 4Set 'Parent Type' to 'contact'
- 5Map the Copper contact ID into 'Parent ID'
- 6Set 'Activity Type' to 'Note'
Scenario Canvas > Copper Create Activity > Details Field
Build the activity detail field with formatted message content
Click into the 'Details' field of the Create Activity module. Use Make's text editor to compose the note body. Type a label, then insert dynamic tokens from the previous modules. A good format is: '[Slack] #channel-name | Sender: display_name | Date: timestamp\n\n message_text'. Use Make's built-in formatDate() function to convert the Slack Unix timestamp (it comes as seconds since epoch) into a readable format. The formatDate() call wraps the timestamp token like this: formatDate(timestamp * 1000; "YYYY-MM-DD HH:mm"). Without the * 1000, Make misreads the Unix timestamp as milliseconds.
- 1Click into the Details field in the Copper Create Activity module
- 2Type '[Slack] #' then click the token picker and select the Slack channel name
- 3Add ' | Sender: ' then map the Slack user display name
- 4Add ' | Date: ' then insert formatDate(ts * 1000; "YYYY-MM-DD HH:mm")
- 5Press Enter twice, then map the Slack message text field
📬 New entry: {{1.name}}
Email: {{1.email}}
Details: {{1.description}}Scenario Canvas > Copper Create Activity > All Fields
Map remaining activity fields
Still in the Create Activity module, fill in the optional but useful fields. Set 'Activity Date' to the formatted date from the previous step — Copper uses ISO 8601 format (YYYY-MM-DD) for this field, separate from the note details text. If your Copper account has custom activity categories, match the closest one. Leave 'User ID' blank unless you want to attribute the activity to a specific Copper user rather than the API key owner. Check that the 'Parent ID' correctly references the Copper contact ID, not the person ID from Slack.
- 1Set 'Activity Date' to formatDate(ts * 1000; "YYYY-MM-DD")
- 2Leave 'User ID' blank unless attributing to a specific rep
- 3Confirm 'Parent Type' is 'contact' not 'lead' or 'opportunity'
- 4Save the module
Scenario Canvas > Run Once (bottom toolbar)
Activate the scenario and test with a real message
Click 'Run once' in the bottom-left of the scenario builder to fire a test. Go to your Slack workspace and post a test message in the target channel from an account that has a matching Copper contact. Return to Make and watch the execution flow animate across the modules — green checkmarks mean data passed through, orange badges show the record count per module. Click any module to inspect the exact data it received and output. Confirm the Copper contact now shows the new activity in its timeline.
- 1Click 'Run once' in the bottom-left toolbar
- 2Post a test Slack message in the target channel
- 3Watch the execution animation in Make
- 4Click the Copper Create Activity module bubble to inspect the output
- 5Open Copper and find the contact — check the Activity tab for the new note
📬 New entry: {{1.name}}
Email: {{1.email}}
Details: {{1.description}}Scenario Canvas > Toggle (bottom-left) > Scenario Settings
Schedule and activate the scenario
Once the test passes, click the toggle in the bottom-left of the scenario builder to switch from 'Off' to 'On'. Because this uses Slack's event-based trigger via Make's webhook infrastructure, the scenario fires within seconds of each new Slack message — you do not need to set a polling interval. Set the maximum number of cycles per execution to 1 (the default) since each Slack message fires its own trigger. In the scenario settings, enable 'Auto-commit' so partial runs don't leave incomplete data in Copper.
- 1Click the toggle at the bottom-left to set the scenario to 'On'
- 2Click the clock icon to open scheduling settings
- 3Confirm the scenario is set to respond to webhooks, not a timed interval
- 4Open Scenario Settings and enable 'Auto-commit'
- 5Save settings
This formula goes in the Details field of the Copper Create Activity module. It conditionally appends a '[URGENT]' tag to the note if the Slack message contains certain keywords, so your team can filter high-priority interactions in Copper's activity feed.
JavaScript — Custom Functionif(▸ Show code
if(
or(
contains(lower(text); "urgent"),... expand to see full code
if(
or(
contains(lower(text); "urgent"),
contains(lower(text); "escalate"),
contains(lower(text); "cancel"),
contains(lower(text); "refund")
);
"[URGENT] [Slack] #" + channel_name + " | Sender: " + profile.display_name + " | Date: " + formatDate(ts * 1000; "YYYY-MM-DD HH:mm") + "\n\n" + text;
"[Slack] #" + channel_name + " | Sender: " + profile.display_name + " | Date: " + formatDate(ts * 1000; "YYYY-MM-DD HH:mm") + "\n\n" + text
)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 Make for this if your team needs conditional routing — specifically, the ability to handle cases where a Slack sender has no matching Copper contact without crashing the whole scenario. Make's visual Router module handles this in about 3 clicks. You also get formatDate() and string manipulation functions built directly into the field editor, which matters here because Slack's timestamps arrive as Unix epoch strings that need conversion before Copper will accept them. The one scenario where you'd skip Make: if your team already uses Zapier for everything else and the person setting this up has never used Make before. The learning curve is real, and for this specific workflow, Zapier can do it too.
The math is straightforward. Each Slack message that triggers the scenario runs through 4 modules: Watch Messages, Get User Info, Search Contacts, Create Activity. That's 4 operations per message. Make's free tier gives you 1,000 operations per month — enough for 250 logged messages. At 500 messages per month (a mid-sized team with two active customer channels), you need Make's Core plan at $9/month, which includes 10,000 operations. Zapier's equivalent would run you $20/month on the Starter plan for similar volume. Make is cheaper by $11/month at this scale, and the gap widens as volume grows.
Zapier's main advantage here is setup speed — their Slack + Copper Zap templates are pre-built and take about 6 minutes to configure if you don't need conditional logic. n8n handles this workflow well if you self-host and want to parse complex Slack message payloads using JavaScript directly in a Code node — no formula gymnastics. Power Automate technically supports both Slack and Copper but requires custom connectors for Copper since it's not a first-party Microsoft connector, which adds 45+ minutes to setup and breaks unpredictably after updates. Pipedream is worth considering if you're comfortable with Node.js and want to write the Copper API call directly — it gives you full control over the request body and handles retry logic out of the box. Make wins here for teams who want a visual setup, can tolerate 30 minutes of configuration, and don't want to write code.
Three things you will hit after going live. First, Slack threads. The 'Watch Messages' trigger fires on top-level messages but not thread replies by default — if your customer conversations happen in threads, you'll miss most of the content. You need to explicitly enable thread reply watching, which then requires a filter to avoid double-logging the parent message. Second, Copper's activity search has no deduplication — if your scenario has a bug and fires twice on the same message, you get two identical activities on the contact with no easy way to clean them up in bulk. Add an idempotency check using the Slack message ts as a unique key before writing to Copper. Third, Slack will occasionally send duplicate events for the same message during network issues. Copper doesn't deduplicate on its end, so you need to store the ts values in a Make data store and skip any message whose ts you've already processed.
Ideas for what to build next
- →Log to Copper Opportunities Too — Extend the scenario with a second Copper search that checks if the contact is linked to an open opportunity, and creates the activity on both the contact and the deal record simultaneously.
- →Build a Daily Slack Digest of Logged Messages — Add a second Make scenario on a daily schedule that pulls all Copper activities created in the last 24 hours and posts a summary to a #sales-digest Slack channel — gives leadership visibility without opening Copper.
- →Auto-create Missing Copper Contacts from Slack — On the Router's 'no contact found' path, instead of just sending an alert, add a Copper Create Contact module that auto-creates the contact using the Slack user's name and email — so no customer falls through the cracks.
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