Mixpanel Activation Funnel + HubSpot Deal Stage Reconciliation: Weekly Ops Digest to Microsoft Teams
Your product says a user activated. Your CRM says the deal is still in 'Demo Scheduled'. Nobody follows up. The account goes cold. This workflow catches that every Monday before anyone notices.
The stack in the order it runs — data flows from the source through to where it lands.
The gap between product activation and CRM deal stage is one of the most expensive blind spots in B2B SaaS. A user completes onboarding but their HubSpot deal hasn't moved — no one follows up, the account goes cold. Flip it: a deal is 'Closed Won' and the user never hit a single activation event. Churn risk is already baked in at the point of sale, before your CS team even knows the account exists.
Mixpanel's Engage API lets you pull every user who fired a specific event — `feature_activated`, `report_created`, whatever your activation definition is — inside a rolling 7-day window. HubSpot's Contacts and Deals API gives you deal stage by associated email. The reconciliation is a join on email. Embarrassingly simple. Almost nobody automates it.
Use n8n over Zapier here. You need a programmatic join across two live data sources, which means a Code node in JavaScript. Zapier's code step is constrained, and its multi-step logic gets expensive fast at this volume. n8n self-hosted runs this free. The cloud starter plan is $20/month and handles weekly runs without breaking a sweat.
Teams is the right delivery channel if your ops and sales team live there — which most B2B SaaS teams do. The setup is minimal: create an Incoming Webhook connector in Teams, paste the URL into an n8n HTTP Request node. You do not need the Microsoft Graph API for this. Skip this playbook if your sales team doesn't actively maintain HubSpot deal stages — if deals sit in 'New' for months, the output is noise. Also skip if you're under 10 new signups per week; the value only surfaces at meaningful activation volume.
The stack (5)
The universal data scratchpad.
Still the fastest place to land tabular data everyone can read.
Chat + channels for Microsoft-365 shops.
If the company is on Outlook/365, Teams is where reports get read — push there, not a separate tool.
How it runs
- 1
Define activation events and deal stages
Before touching any tool, write down the specific Mixpanel events that mean 'activated' for your product — for example, `project_created` AND `teammate_invited` both fired within 7 days of signup. Then write down the HubSpot deal stages that SHOULD correspond to an activated user, like 'Trial Active' or 'Closed Won'. These become your reconciliation rules. Misalignment almost always traces back to teams skipping this step and reconciling against vague criteria.
- 2
Pull activated users from Mixpanel
In n8n, create a workflow triggered by a weekly cron at Monday 7 AM local time. Add an HTTP Request node calling `POST https://mixpanel.com/api/2.0/engage` with your project token and secret as Basic Auth. Set the `where` parameter to filter users who fired your activation events in the last 7 days — for example, `properties['last_event_date'] > '2024-01-01'`. The response is paginated. Loop through pages using n8n's loop node until the `page` field returns fewer than 1,000 results.
- 3
Pull matching deal stages from HubSpot
Add a second HTTP Request node calling `GET https://api.hubapi.com/crm/v3/objects/contacts/search` with a Bearer token from your HubSpot private app. Pass the Mixpanel email addresses as filter values using the `IN` filter operator on the `email` property, batched at 100 emails per request. Set `associations: ['deals']` in the response fields to get associated deal IDs back. Then call the Deals API to fetch the `dealstage` property for each deal ID. Store the joined result as an array of objects: `{email, mixpanel_activated: true/false, hubspot_dealstage: '...', deal_id: '...'}`. Pull `deal amount` here too — you'll need it in step 6.
- 4
Run reconciliation logic in a Code node
Add a Code node in JavaScript. Iterate the joined array and classify every record into one of four buckets: (1) Activated + correct deal stage — healthy; (2) Activated + stale deal stage, e.g., still 'Demo Scheduled' — needs sales follow-up; (3) Not activated + deal stage 'Closed Won' — churn risk, flag immediately; (4) Not activated + early deal stage — normal, ignore. Output two things: a `mismatches` array containing buckets 2 and 3, and a summary object with counts per bucket.
- 5
Write mismatches to Google Sheets
Add a Google Sheets node to append the `mismatches` array to a sheet named 'Reconciliation Log'. Columns: `week_start`, `email`, `deal_id`, `hubspot_dealstage`, `activation_status`, `mismatch_type`. Keep at least 12 weeks of history. The sheet does two jobs: audit trail for ops reviews, and raw data for anyone who wants to build a Looker Studio dashboard later. Always append. Never overwrite.
- 6
Format and post the Teams digest
Add an HTTP Request node targeting your Teams Incoming Webhook URL. POST a JSON payload using the Adaptive Card schema. Structure it as: a header reading '📊 Weekly Activation ↔ CRM Reconciliation — [date range]', a summary table with counts for all 4 buckets, then a bulleted list of mismatches showing partially masked email, deal stage, and mismatch type. Cap the list at the top 10 mismatches sorted by deal value — the `deal amount` you pulled in step 3. Do not dump 50 rows into Teams.
- 7
Add a threshold alert for critical mismatches
Before the Teams formatting step, insert an IF node. If the count of bucket-3 records — 'Closed Won but never activated' — exceeds 3 in a single week, fire a separate urgent Teams message to the #revenue-ops channel. Subject line: '🔴 Churn Risk: [N] Closed Won accounts not activated this week.' This is a separate Adaptive Card from the digest. It should feel like a page, not a report. Include a direct link to the Google Sheets log so the ops team can triage immediately.
- 8
Auto-flag HubSpot deals for clear bucket-2 cases
For bucket-2 mismatches where the user IS activated but the deal stage hasn't moved in 14 or more days, add a HubSpot update step. Call `PATCH https://api.hubapi.com/crm/v3/objects/deals/{deal_id}` to set a custom property `activation_reconciliation_flag: true`, and log a note in the deal timeline using the Engagements API. The sales rep sees the flag in HubSpot and knows to move the deal forward — no manual triage queue needed. One rule: auto-flag only. Never auto-advance the deal stage.
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.