HubSpot + Slack: close stale deals, stay in sync
Nothing wrecks a forecast like a pipeline full of “maybe” deals that quietly went cold three weeks ago. They sit there, your team assumes someone is working them, and reporting turns into a guessing game.
This HubSpot Slack automation hits Sales Ops first, but a sales manager and a founder feel it just as fast. You get a cleaner pipeline, deals closed out consistently after 21 days of inactivity, and a Slack update your team actually sees.
Below, you’ll see exactly how the workflow flags stale deals, marks them Closed Lost, emails the contact for feedback via Gmail, and posts the outcome in Slack.
How This Automation Works
See how this solves the problem:
n8n Workflow Template: HubSpot + Slack: close stale deals, stay in sync
flowchart LR
subgraph sg0["Scheduled Automation Start Flow"]
direction LR
n0@{ icon: "mdi:play-circle", form: "rounded", label: "Scheduled Automation Start", pos: "b", h: 48 }
n1["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/hubspot.svg' width='40' height='40' /></div><br/>Retrieve HubSpot Deals"]
n2["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Map Deal Attributes"]
n3@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Filter Stale Deals 21d", pos: "b", h: 48 }
n4["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/hubspot.svg' width='40' height='40' /></div><br/>Mark Deals Closed Lost"]
n5["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Pull Deal Associations"]
n6["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Parse Contact Identifiers"]
n7["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/hubspot.svg' width='40' height='40' /></div><br/>Fetch Contact Details"]
n8["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Derive Contact Email"]
n9@{ icon: "mdi:message-outline", form: "rounded", label: "Dispatch Gmail Feedback", pos: "b", h: 48 }
n10["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/slack.svg' width='40' height='40' /></div><br/>Post Slack Alert"]
n0 --> n1
n1 --> n2
n6 --> n7
n2 --> n3
n7 --> n8
n8 --> n9
n5 --> n6
n4 --> n5
n9 --> n10
n3 --> n4
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n0 trigger
class n3 decision
class n5 api
class n2,n6,n8 code
classDef customIcon fill:none,stroke:none
class n1,n2,n4,n5,n6,n7,n8,n10 customIcon
The Challenge: Stale deals that distort your pipeline
Stale deals are sneaky because they don’t “fail” loudly. They just stop moving. A rep gets busy, a prospect ghosts, the next follow-up never happens, and 21 days later the deal is still inflating your pipeline like it has a chance. Then leadership asks why the quarter missed, and everyone starts digging through old notes, half-written tasks, and last-contact dates that should have been acted on weeks ago. It’s not just messy. It makes your CRM feel untrustworthy, so the team stops using it properly.
The friction compounds. Here’s where it breaks down in real life.
- Deals stay “Open” because nobody wants to be the one to close them out, so your forecasts keep lying to you.
- Reps waste about an hour a week each combing through old deals to figure out what to do next.
- Follow-up is inconsistent, which means you lose feedback that could fix your messaging or qualification.
- When someone finally updates the CRM, the team doesn’t notice, so the same deal gets discussed again in standups.
The Fix: Auto-close cold deals and notify the team
This workflow runs on a schedule and scans your HubSpot deals for the ones that haven’t been updated in 21+ days. When it finds them, it standardizes the deal fields (so your filtering is reliable), then automatically updates each stale deal to Closed Lost. Next, it pulls the deal’s associated contact, fetches that contact’s details, and extracts the email address. With that in hand, the workflow sends a personalized Gmail message that thanks the contact and asks for quick feedback on what stopped the process. Finally, it posts a Slack notification so your team has visibility, without needing another meeting or spreadsheet.
The workflow starts with a scheduled run, then HubSpot provides the deal list. After the 21-day filter and status update, it maps deals to contacts, sends the Gmail feedback request, and ends with a Slack alert to keep everyone aligned.
What Changes: Before vs. After
| What This Eliminates | Impact You’ll See |
|---|---|
|
|
Real-World Impact
Say you manage a pipeline with about 60 active deals, and each week you spend maybe 5 minutes per deal checking last activity, next steps, and whether it’s truly alive. That’s roughly 5 hours of CRM cleanup. With this workflow, the “cold deal” decision happens automatically on a schedule, the deal is closed, the contact gets a feedback email, and Slack gets the update. You still review important deals, but the dead ones stop stealing attention.
Requirements
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- HubSpot for deal and contact data access
- Slack to notify your team automatically
- Gmail to send the feedback request email
- HubSpot private app token (get it from HubSpot Settings → Integrations → Private Apps)
Skill level: Intermediate. You’ll connect accounts, confirm HubSpot permissions, and adjust email/Slack message content.
Need help implementing this? Talk to an automation expert (free 15-minute consultation).
The Workflow Flow
A scheduled run kicks things off. You decide the interval (daily is common). The workflow starts without anyone clicking anything, which means the cleanup habit is finally consistent.
HubSpot deals are pulled and normalized. The workflow retrieves your deals, then maps key fields into a consistent structure so the stale-deal filter behaves the same way every time.
Stale deals are filtered and closed. Anything untouched for 21+ days is marked Closed Lost in HubSpot. That alone makes your pipeline more honest, frankly.
Contacts are found, emailed, and reported in Slack. The workflow fetches the deal-to-contact association, grabs contact details, extracts the email, sends the Gmail feedback request, then posts a Slack message about what was closed.
You can easily modify the 21-day threshold to 14 days (or 30) based on your sales cycle. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Scheduled Trigger
Set the schedule that kicks off the workflow and pulls your HubSpot deal data.
- Add and open Scheduled Automation Start.
- Configure the schedule rule under rule to match how often you want stale deals checked.
- Connect Scheduled Automation Start to Retrieve HubSpot Deals.
Step 2: Connect HubSpot Deals Retrieval
Pull all relevant deal properties from HubSpot to identify stale opportunities.
- Open Retrieve HubSpot Deals and set Resource to
dealand Operation togetAll. - Enable Return All as
true. - Under filters → properties, confirm the properties list includes
dealname,hs_lastmodifieddate,notes_last_updated, andnotes_last_contacted. - Credential Required: Connect your
hubspotAppTokencredentials in Retrieve HubSpot Deals.
Step 3: Set Up Deal Processing and Staleness Filtering
Normalize the deal fields and filter only those inactive for 21 days.
- Open Map Deal Attributes and keep the JavaScript that maps
dealId,dealname,lastmodifieddate,notes_last_updated, andnotes_last_contacted. - In Filter Stale Deals 21d, set the condition to compare
={{ $json.lastmodifieddate.toNumber() }}with={{ Date.now() - 21 * 24 * 60 * 60 * 1000 }}using theltoperator. - Confirm the execution order: Retrieve HubSpot Deals → Map Deal Attributes → Filter Stale Deals 21d.
toNumber().Step 4: Update Deals and Pull Associated Contacts
Mark stale deals as Closed Lost and gather their associated contacts for outreach.
- Open Mark Deals Closed Lost and set Deal ID to
={{ $json.dealId }}. - Set Update Fields → stage to
closedlost. - Credential Required: Connect your
hubspotAppTokencredentials in Mark Deals Closed Lost. - In Pull Deal Associations, set URL to
=https://api.hubapi.com/crm/v3/objects/deals/{{ $json.dealId }}?associations=contacts. - Enable Send Headers and set Authorization to
Bearer [CONFIGURE_YOUR_TOKEN]using a valid HubSpot access token. - Confirm the chain: Filter Stale Deals 21d → Mark Deals Closed Lost → Pull Deal Associations → Parse Contact Identifiers.
[CONFIGURE_YOUR_TOKEN] before running the workflow.Step 5: Fetch Contact Details and Derive Emails
Extract associated contact IDs, fetch their profiles, and prepare email addresses.
- Open Parse Contact Identifiers and keep the JavaScript that extracts
contactId,dealId, anddealName. - In Fetch Contact Details, set Contact ID to
={{ $json.contactId }}and confirm the properties list includesemail,firstname,lastname, andhs_full_name_or_email. - Credential Required: Connect your
hubspotAppTokencredentials in Fetch Contact Details. - Open Derive Contact Email and keep the JavaScript that outputs
emailfromitem.json.properties.email.value.
Step 6: Configure Email and Slack Notifications
Send the feedback email via Gmail and post a Slack alert after each email is dispatched.
- Open Dispatch Gmail Feedback and set Send To to
=[YOUR_EMAIL](replace with your recipient or derived email field). - Set Subject to
=Thank You — We'd Value Your Feedback. - Set Message to the provided HTML template and keep the personalization token
{{ $('Fetch Contact Details').item.json.properties.firstname.value }}. - Credential Required: Connect your
gmailOAuth2credentials in Dispatch Gmail Feedback. - Open Post Slack Alert and set Text to
=Deals which are moved to Closed Lost: {{ $('Parse Contact Identifiers').item.json.dealId }}. - Select the Slack channel using Channel (e.g.,
[YOUR_ID]). - Credential Required: Connect your
slackOAuth2Apicredentials in Post Slack Alert.
={{ $json.email }}.Step 7: Test and Activate Your Workflow
Run a manual test to verify the full chain before activating the schedule.
- Click Execute Workflow to run Scheduled Automation Start manually.
- Confirm that stale deals pass through Filter Stale Deals 21d and are updated by Mark Deals Closed Lost.
- Verify that Dispatch Gmail Feedback sends the email and Post Slack Alert posts the deal ID message.
- When satisfied, toggle the workflow to Active to run on the schedule.
Watch Out For
- HubSpot credentials can expire or need specific permissions. If things break, check the HubSpot Private App scopes and the n8n credential test first.
- If you’re using Wait nodes or external rendering, processing times vary. Bump up the wait duration if downstream nodes fail on empty responses.
- Default prompts in AI nodes are generic. Add your brand voice early or you’ll be editing outputs forever.
Common Questions
Usually about an hour once your HubSpot and Gmail permissions are ready.
Yes. No coding is required, but someone needs to be comfortable connecting accounts and testing with a few sample deals.
Yes. n8n has a free self-hosted option and a free trial on n8n Cloud. Cloud plans start at $20/month for higher volume. You’ll also need to factor in Gmail and HubSpot usage limits (usually $0 for typical volumes).
Two options: n8n Cloud (managed, easiest setup) or self-hosting on a VPS. For self-hosting, Hostinger VPS is affordable and handles n8n well. Self-hosting gives you unlimited executions but requires basic server management.
Start with the “Filter Stale Deals 21d” logic and change the age threshold to match your cycle. You can also swap the “Dispatch Gmail Feedback” email copy to match your brand voice, or change the Slack destination in “Post Slack Alert” to notify a specific rep channel instead of a general one. If your process uses a different loss stage than “Closed Lost,” update the “Mark Deals Closed Lost” action to set the right stage and reason.
Most of the time it’s an expired token or missing scopes on your HubSpot private app. Regenerate the token, update the n8n HubSpot credential, and confirm you allowed read/write access for deals and read access for contacts. If it fails only on some deals, check association access and confirm the deals actually have linked contacts.
On a typical n8n Cloud plan, this can handle hundreds of stale deals per run for most small teams. If you self-host, capacity is mostly about your server and HubSpot API limits. Practically, if you’re pulling thousands of deals daily, you’ll want pagination checks and a slightly slower pace to avoid rate limits.
Often, yes, because this workflow needs multi-step logic: filtering by “last updated,” updating the deal, pulling associations, fetching contact details, then sending Gmail and Slack. n8n handles that kind of branching and data shaping cleanly, and you can self-host for unlimited executions. Zapier or Make can still do it, but it tends to sprawl into more steps, which gets expensive and harder to debug. If you only need a simple Slack ping when a deal changes stage, those tools may be quicker. Talk to an automation expert if you’re not sure which fits.
Once this is running, “pipeline hygiene” stops being a weekly fire drill. The workflow handles the boring cleanup and the follow-up nudge, and your team stays in sync in Slack.
Need Help Setting This Up?
Our automation experts can build and customize this workflow for your specific needs. Free 15-minute consultation—no commitment required.