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.

The flow
Microsoft Outlook logo
Source
Microsoft Outlook
HubSpot logo
Process
HubSpot
Make logo
Process
Make
Claude logo
Process
Claude
Microsoft Teams logo
Destination
Microsoft Teams

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

Why this stack

Sales leaders waste hours every week pulling two reports by hand: HubSpot pipeline changes and Outlook calendar utilization. Then they stare at CRM data with zero visibility into whether reps had the capacity to execute in the first place. That correlation — deal velocity against meeting volume — is the insight that actually tells you whether to coach, hire, or fix the pipeline. Nobody does it because it means merging two data sources that don't talk to each other.

HubSpot is the right CRM source here. Its API has clean deal stage history endpoints that return stage transitions with timestamps, not just current state. Outlook's Microsoft Graph API exposes calendar event counts, durations, and attendees in a structured format — Gmail's API makes that same data significantly harder to extract. Make (formerly Integromat) handles Graph's OAuth complexity better than n8n does in the current stable release, and has a native HubSpot module so you're not hand-rolling API calls.

Google Sheets is the aggregation layer. Ops folks who want to spot-check the underlying data can do it without touching the automation. Claude writes the narrative paragraph so the Teams message reads like an ops memo, not a spreadsheet export.

Skip this if your team is fully on Google Workspace — swap Outlook for Google Calendar, replace the Graph API calls with Google Calendar API, and the architecture is identical. Don't use this if your HubSpot plan doesn't include the Deals API; check your tier first. And if you have fewer than 3 reps or fewer than 10 deals a week, the correlation isn't meaningful — just read HubSpot manually.

The stack (5)

  1. Microsoft Outlook logo

    Mail + calendar at the center of most companies.

    Graph API turns the inbox/calendar into a programmable source for ops automations.

  2. HubSpot logo

    CRM + marketing for go-to-market.

    Pipeline data becomes an automatable input for revenue reports.

  3. Make logo

    No-code automation builder. Visual scenarios that chain APIs and AI calls.

    Per-operation pricing is cheaper than Zapier at the volumes I run, and the visual editor handles branching cleanly.

  4. Claude logo

    Long-context reasoning model from Anthropic — my daily driver for nuanced writing and orchestration.

    Better tone-matching and longer working memory than GPT for the tasks I care about most: guest messages, drafts, code review.

  5. Microsoft Teams logo

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

    Register an Azure app for Microsoft Graph access

    Go to portal.azure.com → Azure Active Directory → App Registrations → New Registration. Name it 'Ops Digest Bot'. Under API Permissions, add Microsoft Graph → Delegated → 'Calendars.Read' and 'User.Read.All'. Grant admin consent. Generate a client secret under Certificates & Secrets. Write down your Client ID, Tenant ID, and Client Secret — you'll need all three in Make. This is the step most people skip and then wonder why Graph keeps returning 403s.

  2. 2

    Build the HubSpot deal pull in Make

    Create a new Make scenario. Set the trigger to Schedule → every Monday at 07:30. Add a HubSpot 'Search CRM Objects' module for object type 'deals'. Filter by 'hs_lastmodifieddate' greater than 7 days ago. Request these properties: dealname, dealstage, amount, closedate, hubspot_owner_id, and hs_date_entered_[stage] for each relevant stage. That gives you every deal that moved stages last week. Run a Make Array Aggregator to group results by owner_id — you'll need that grouping when you correlate against calendar data per rep.

  3. 3

    Pull calendar event counts per rep from Microsoft Graph

    Add an HTTP module in Make: method GET, URL 'https://graph.microsoft.com/v1.0/users/USER_ID/calendarView', query params 'startDateTime' and 'endDateTime' set to last Monday and last Sunday using Make's date functions ({{formatDate(addDays(now; -7); 'YYYY-MM-DDTHH:mm:ss')}}). Add the Authorization header with your OAuth token from the connection you set up in step 1. Repeat this module per rep by running a Make Iterator over your rep list. Store rep email, total_meetings, and total_meeting_hours as outputs. Filter out internal 1:1s by checking attendee count > 1.

  4. 4

    Aggregate into Google Sheets for the audit trail

    Add a Google Sheets 'Add Row' module targeting a sheet called 'Weekly Ops Log'. Columns: Week_Start, Rep_Name, Deals_Moved_Forward, Deals_Stuck, Pipeline_Added ($), Meetings_Count, Meeting_Hours, Avg_Deal_Velocity_Days. Deals_Moved_Forward = count of deals where dealstage changed to a later stage. Deals_Stuck = deals unmodified for more than 14 days. Meeting_Hours = sum of event durations from Graph. When someone questions the Claude summary, this sheet is where you point them.

  5. 5

    Compute team-level summary metrics

    Add a Make aggregator that rolls all rep rows into a single team summary: Total_Pipeline_Added, Total_Deals_Closed_Won, Total_Deals_Closed_Lost, Win_Rate (Closed_Won divided by Closed_Won plus Closed_Lost), Team_Total_Meetings, and a 'Capacity_Flag' boolean that flips true if any rep logged more than 25 hours of meetings last week. That 25-hour threshold is a heuristic for reps who were too over-scheduled to actually execute on deals. These team metrics are what you'll feed into the Claude prompt.

  6. 6

    Generate the narrative with Claude

    Add an HTTP module: POST to https://api.anthropic.com/v1/messages, model claude-3-5-sonnet-20241022. Build a prompt that passes all team-level metrics and the per-rep table as a structured list. The instruction to Claude: 'You are a sales ops analyst. Write a 4-sentence weekly digest for a sales leader. Lead with pipeline added and win rate. Call out any rep where deal velocity is low AND meeting load is high — that is a capacity problem. Call out any rep where both are low — that is a different problem. Be direct, use the numbers, no filler.' Set max_tokens to 300.

  7. 7

    Post the Adaptive Card to Microsoft Teams

    Add an HTTP module POSTing to your Teams channel incoming webhook URL. Build an Adaptive Card with three sections: (1) Team Summary — pipeline added, win rate, deals closed; (2) Per-Rep Table — rep name, deals moved, meetings, hours, velocity; (3) Claude's narrative in a TextBlock with wrap: true. Color code the win rate: green above 30%, yellow for 20–30%, red below 20%. Post to your #sales-ops channel. Keep the card under 28KB — Teams silently drops anything larger and gives you no error.

  8. 8

    Add a Slack fallback for teammates not on Teams

    If ops or finance lives in Slack while sales lives in Teams, add a parallel branch in Make that posts a stripped-down version — just the Claude narrative plus three top-line numbers — to a Slack channel via webhook. It's a 10-minute addition to the scenario. Use Make's Router module to branch right after the Claude call: one branch to Teams, one to Slack. This kills the 'I don't use Teams' excuse before it starts.

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