HubSpot Deal Stage Lag + Gmail Thread Age + Stripe Invoice Status: Daily Sales Friction Digest to Slack via Zapier
Every morning, surface every HubSpot deal stuck for 5+ days, cross-check the last Gmail thread timestamp and the Stripe invoice status, then post a prioritized action list to Slack — so your AEs know exactly which deals to touch before noon.
The stack in the order it runs — data flows from the source through to where it lands.
The real problem isn't lazy AEs. It's that no single tool shows you stage lag, email silence, and an unpaid invoice at the same time. HubSpot shows deal age. It does not tell you the last email in that thread was 9 days ago AND the invoice has been sitting unpaid for 6 days. Those three signals together are a clear 'this deal is dying' indicator. That's the gap this stack closes.
Zapier is the pragmatic choice because it has native HubSpot, Gmail, and Stripe integrations — no API auth to write from scratch. The tradeoff is real: Zapier's multi-step filtering is clunky for complex logic, and you'll hit task limits fast with 50+ active deals. If you're consistently above 50 deals, move this to Make or n8n where looping is more efficient.
Stripe's invoice API is the underused signal here. A deal sitting in 'Contract Sent' with an overdue invoice is a completely different problem from a deal with no invoice yet. If you conflate them in the Slack message, your AE wastes time figuring out which action to take. Splitting the two cases — follow up vs. re-engage — means the digest is actionable the moment they read it.
Skip this if your sales cycle is under 3 days (pure self-serve flows, for example) — stage lag thresholds don't apply. Also skip it if your AEs don't use Gmail; the email thread age signal will be empty and the digest loses half its value. HubSpot's built-in task reminders handle simpler cases. This stack is for teams who need cross-tool signal correlation.
The stack (5)
How it runs
- 1
Define HubSpot deal stage lag thresholds
Go to HubSpot → CRM → Deals → Pipeline Settings. Write down the expected duration for each stage: 'Proposal Sent' should move within 5 days, 'Contract Sent' within 3 days. You'll use these numbers in Zapier filters later. While you're here, check that every deal has an 'Associated Contact' with an email address — the Gmail lookup in step 4 depends on it. If deals are missing contact associations, fix that now. The Gmail step will return empty if you don't, and the whole digest falls apart.
- 2
Create a Zapier scheduled trigger
Create a new Zap in Zapier. Use a 'Schedule by Zapier' trigger — no webhooks needed. Set it to run daily at 08:00 in your sales team's timezone. Name it 'Daily Sales Friction Digest'. One thing to know: Zapier's scheduler passes no data itself. It's just a clock. Your first real data step is the HubSpot search that follows.
- 3
Search HubSpot for stale deals
Add a HubSpot action: 'Find Deals'. Filter by: `dealstage != closedwon`, `dealstage != closedlost`, and `days_in_stage >= 5`. The property to filter on is `hs_time_in_current_stage`, which HubSpot measures in milliseconds — 5 days = 432000000 ms. Return these properties: `dealname`, `dealstage`, `hubspot_owner_id`, `amount`, `hs_time_in_current_stage`, `associated_contact_email`. Limit results to 20. Zapier's standard plan loop limits make anything above 20 unreliable. If you're regularly seeing more than 20 stale deals, that's a pipeline hygiene problem to fix separately — not a reason to push Zapier's limits.
- 4
Loop over deals and fetch Gmail thread age
Add a 'Looping by Zapier' step. Inside the loop, add a Gmail action: 'Find Email'. Search by `to:{{associated_contact_email}} OR from:{{associated_contact_email}}`, sorted by date descending, limit 1. Extract `internalDate` from the result — it's a Unix millisecond timestamp. Calculate days since last email: `Math.floor((Date.now() - internalDate) / 86400000)`. If no email is found, set `daysSinceLastEmail = 'unknown'`. Any deal where `daysSinceLastEmail > 7` gets flagged HIGH PRIORITY.
- 5
Check Stripe invoice status for each deal
Inside the same loop, add a Webhooks by Zapier step (GET request). Call `https://api.stripe.com/v1/invoices?customer={{stripe_customer_id}}&status=open&limit=1`. Authenticate with Basic Auth using your Stripe secret key. The `stripe_customer_id` should be stored as a HubSpot deal property — if it isn't, add it as a custom property and populate it when deals reach 'Proposal Sent'. Extract `due_date` and calculate days overdue. If no open invoice exists, set `invoiceStatus = 'none'`. Any invoice overdue more than 3 days gets marked URGENT.
- 6
Score and sort deals by urgency
Add a Zapier Code step (JavaScript). For each deal in the loop output, compute an urgency score: +3 if `daysSinceLastEmail > 7`, +2 if `invoiceOverdueDays > 3`, +1 if `daysInStage > 10`. Sort deals descending by score. Truncate to the top 10 for the Slack message — if you post 20 items, AEs ignore the list. Format each deal as: `[URGENT] {{dealname}} — Stage: {{dealstage}} for {{daysInStage}}d | Last email: {{daysSinceLastEmail}}d ago | Invoice: {{invoiceStatus}}`.
- 7
Build and post the Slack digest
Add a Slack action: 'Send Channel Message'. Target #sales-daily. Build the message in Slack Block Kit markdown: header reads 'Sales Friction Digest — {{today}}', followed by a numbered list of the top 10 deals sorted by urgency score, then a footer: 'Total stale deals in pipeline: {{totalStaleDeals}} | Generated at 08:00 by Zapier'. Use `*bold*` for URGENT items, plain text for everything else. Post as your bot user so it's visually distinct from human messages in the channel.
- 8
Add a direct HubSpot link per deal
In the Slack message, append a HubSpot deep link to each deal line: `https://app.hubspot.com/contacts/{{portal_id}}/deal/{{deal_id}}`. This is the single most important UX detail in the whole setup. AEs will click through and act if the link is one tap away. They won't if they have to search HubSpot manually. Get `portal_id` from your HubSpot app settings — it's the number in your HubSpot URL. Get `deal_id` from the HubSpot search step output as `hs_object_id`.
- 9
Test with a single deal and verify all three signals
Before activating, manually create a test deal in HubSpot in 'Proposal Sent' stage. Associate a contact with a real Gmail thread. Optionally create a test Stripe invoice. Run the Zap manually. Check three things: the deal appears in the output, `daysSinceLastEmail` matches the actual thread date, and the Stripe invoice status is correct. The most common failure here: Gmail returns the wrong thread because the contact has multiple addresses. Verify that `associated_contact_email` in HubSpot exactly matches the Gmail thread sender — not an alias, not a CC.
Want me to build this for you instead?
Product Audit and CTO Mode run out of this same thinking. If you’re reading this thinking “I want this, but in my product” — let’s talk.
See servicesMore like this
Gmail Thread Aging + Stripe Invoice Overdue: Unified AR Follow-Up Digest to Slack via Zapier
Surface overdue Stripe invoices and the exact age of your last Gmail thread with that customer — every morning at 8:30, automatically — so AR follow-up stops living in someone's head.
Intercom Ticket Volume + Razorpay Failed Payments: Daily Support-Cost-per-Revenue Alert to Slack via Zapier
Catch the support cost blowout from Razorpay failed payments before your agents are already buried.
Outlook Calendar Load + HubSpot Deal Velocity: Weekly Ops Digest to Microsoft Teams
Every Monday at 07:30, your revenue team gets one Teams card: last week's deal pipeline movement next to each rep's actual meeting load — so you stop guessing whether low close rates are a pipeline problem or a capacity problem.