Segment + HubSpot Onboarding Milestone Tracker: Auto-Escalate Stuck Users to Slack
Your trial users are churning in silence — here's how to catch them 48 hours before it's too late.
The stack in the order it runs — data flows from the source through to where it lands.
The most expensive problem in SaaS that nobody automates: 50 trial users, 12 stuck at step 2 of onboarding, and nobody knows until the trial expires. Your CS team is manually checking the product dashboard. Your HubSpot records say 'trial' — not 'stuck'. This playbook closes that gap by treating onboarding milestones as a data pipeline, not a manual review task.
Segment is the right event source because it sits upstream of both your product and your CRM. If you're already piping events to Amplitude or Mixpanel, you're almost certainly sending them through Segment too. Segment's Profile API lets you query a user's full event history without touching your database directly. HubSpot is the CRM layer because it has a clean custom properties API and a Deals/Contacts structure that maps naturally to trial lifecycle stages.
Pipedream is the orchestration choice specifically because Segment's webhook delivery via Destinations integrates with Pipedream natively — you receive Segment track() calls as HTTP webhooks without polling. That's event-driven, not scheduled. You catch a stuck user within hours of them stalling, not at the next daily batch run.
When NOT to use this: no Segment in your stack? Replicate it with PostHog webhooks or Amplitude's webhook triggers — the downstream HubSpot and Slack steps are identical. Don't use this for B2C apps with more than 500 daily signups; at that volume, route to an email automation sequence with Resend or SendGrid instead of Slack pings to a human CS team. This is built for B2B SaaS with 5–50 trials/week, where individual user attention has real ROI.
The stack (5)
How it runs
- 1
Define your onboarding milestone events in Segment
Make sure your product fires Segment track() events for each onboarding milestone — 'account_created', 'workspace_setup_completed', 'first_integration_connected', 'first_report_generated'. If these aren't instrumented yet, add them via Segment's analytics.js or your server-side SDK before you build anything else. The automation is only as good as your event coverage. Once that's in place, create a new Destination of type 'Webhooks' in Segment pointing to your Pipedream workflow HTTP trigger URL.
- 2
Create the Pipedream workflow with Segment webhook trigger
In Pipedream, create a new workflow with an HTTP trigger. Paste that trigger URL into your Segment Webhook Destination. In the first code step, parse the incoming Segment payload — pull out event name, userId, email, timestamp, and any relevant properties. Add a filter: only continue if the event is 'account_created'. This fires the workflow once per new user, and the workflow monitors their progress from there. Store userId and signup timestamp in Pipedream's built-in $checkpoint object — you'll need them later.
- 3
Check milestone completion via Segment's Profile API
Add a Pipedream code step that waits 48 hours after the initial account_created event using Pipedream's delay.resumeAfter function: await $.flow.delay(48 * 60 * 60 * 1000). After the delay, call Segment's Profile API: GET 'https://profiles.segment.com/v1/spaces/YOUR_SPACE_ID/collections/users/profiles/user_id:USER_ID/events'. That returns every event the user has fired. Check whether 'first_integration_connected' appears in the response. If yes, user is not stuck — end the workflow. If no, proceed to escalation.
- 4
Enrich and update the HubSpot contact record
Add a HubSpot action in Pipedream to search for the contact by email — POST to '/crm/v3/objects/contacts/search' with a filter on email. If found, update the contact's custom properties: set 'onboarding_status' to 'stuck_at_integration', 'onboarding_stuck_since' to the current date, and 'days_until_trial_expiry' computed from signup date plus 14 days. Create these custom properties first in HubSpot under Settings → Properties → Contact Properties. If the contact doesn't exist yet — HubSpot sync sometimes lags — create it via the Contacts API.
- 5
Generate a context-rich escalation note with Claude
Add an HTTP step calling the Claude API with model claude-3-5-sonnet-20241022. Pass the user's email, company from HubSpot, signup date, which milestones they completed, which they missed, and days remaining in trial. Prompt: 'Write a 2-sentence Slack message for a CS rep about a stuck trial user. Include what they did complete and what they haven't done. Suggest one specific outreach angle based on where they dropped off. Be concrete, no fluff.' This makes the Slack notification immediately actionable — not just an alert.
- 6
Post the escalation to Slack with a HubSpot deep link
Use Pipedream's Slack action to post to #cs-escalations. Build the message with Slack Block Kit: a Header block showing 'Trial User Stuck — Action Required', a Section block with the Claude-generated note, a Context block with signup date, trial expiry date, and completed milestones, and an Actions block with a button linking directly to the HubSpot contact record at 'https://app.hubspot.com/contacts/YOUR_PORTAL_ID/contact/CONTACT_ID'. One click to act. No dashboard hunting.
- 7
Check again at 72 hours and escalate if still stuck
After posting the 48-hour alert, add another Pipedream delay of 24 hours, then re-call the Segment Profile API for the same user. If they still haven't hit the integration milestone, post a follow-up Slack message to the same thread — use Slack's thread_ts from the original message, which you stored in $checkpoint. Include the updated days-remaining count. This keeps escalations threaded instead of spamming the channel with duplicate top-level messages. Update HubSpot with 'escalation_count' incremented to 2.
- 8
Mark resolved when activation fires
Create a second Pipedream workflow, same Segment webhook source. Filter this one for the 'first_integration_connected' event. When it fires, look up the HubSpot contact and set onboarding_status to 'activated'. Then check $checkpoint — if there's an open escalation thread for this user, post a Slack message to that same thread confirming the user activated, so the CS rep knows to close the loop. Update HubSpot's deal stage from 'Stuck Trial' to 'Active Trial'.
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
Google Analytics 4 + HubSpot Lifecycle Stage: Weekly Acquisition-Quality Digest to Slack via Pipedream with Claude Narrative
Stop reporting traffic numbers. Report whether the traffic you paid for last week actually became pipeline — with a one-paragraph executive summary written by Claude.
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.
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.