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 flow
HubSpot logo
Source
HubSpot
Gmail logo
Process
Gmail
Stripe logo
Process
Stripe
Zapier logo
Process
Zapier
Slack logo
Destination
Slack

The stack in the order it runs — data flows from the source through to where it lands.

Why this stack

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)

  1. HubSpot logo

    CRM + marketing for go-to-market.

    Pipeline data becomes an automatable input for revenue reports.

  2. Gmail logo

    Google Workspace mail with a solid API.

    Labels + the Gmail API make it easy to trigger flows off inbound mail.

  3. Stripe logo

    Global payments with first-class APIs.

    Events + Sigma let you wire billing into any ops report or alert.

  4. Zapier logo

    No-code automation across 6k+ apps.

    Fastest path from "when X happens, do Y" without standing up infrastructure.

  5. Slack logo

    Team chat where most ops alerts and reports land.

    The default place a small team already lives — pipe reports here instead of email nobody opens.

How it runs

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

More like this