Olmec Dynamics
A
·8 min read

Automate HubSpot deals reports to Slack using Make.com, Google Sheets, and Slack blocks

Automate HubSpot deals reports to Slack with Make.com, using Google Sheets for last-run windows, idempotency, and Slack failure alerts.

Introduction

Manually writing a weekly or daily “what happened in HubSpot” message for Slack is one of those admin tasks that quietly eats hours. You end up exporting reports, copying numbers into Slack, fixing timezone confusion, and then double-checking you did not repost the same results when someone hits rerun.

This guide shows you how to automate HubSpot deals reports to Slack using Make.com, with Google Sheets handling your last-run timestamp, idempotency via a unique run id, and failure notifications back to Slack. By the end, you will have a workflow you can run every weekday or weekly without babysitting.

If you want the bigger picture behind Cross-Platform Automation (XPA), see this overview of Cross-Platform Automation (XPA).

What You'll Need

  • Make.com account with access to Scheduler, Google Sheets modules, HubSpot modules, and Slack posting modules.
  • HubSpot access via a Make.com-connected account, with permissions to read Deals and related fields.
  • Slack app permissions to post messages to the channel(s) you will target.
  • Google Sheets for two things:
    1. storing last_run_at
    2. logging run outcomes and run ids

Prerequisites you should set up before building:

  • Decide your report window (for example, “yesterday local time” or “last 7 days”).
  • Know which HubSpot deal properties you want to include in the output (examples below: deal stage, amount, close date, owner).

How It Works (The Logic)

The automation runs on a schedule in Make.com.

  1. Scheduler trigger starts the scenario on a fixed cadence.
  2. Google Sheets reads last_run_at to define the time window.
  3. HubSpot query pulls only deals changed/closed within the window (delta processing).
  4. Make.com aggregates the metrics you care about (counts, sums by stage/owner, won vs open, etc.).
  5. Slack message posting sends a structured summary using blocks, plus a compact table of key numbers.
  6. Google Sheets writes a new run_id and updates last_run_at only after a successful Slack post.
  7. If anything fails, the scenario posts an error alert to Slack and does not advance last_run_at.

That last detail is what keeps you from skipping data or duplicating reports after retries.

Step-by-Step Setup

Below is a build that works well for “HubSpot deals report to Slack” and scales as your team adds more metrics.

1) Create your Google Sheet state and log

In a single Google Sheet, create two tabs (names are up to you, but be consistent):

  • State tab
    • Cell A1: last_run_at
    • Cell B1: start value (for first run, set it to something like 2026-07-01T00:00:00Z)
  • Log tab
    • Columns:
      • run_id
      • scheduled_time
      • window_start
      • window_end
      • status (success/failure)
      • posted_slack_ts (blank if failure)
      • error_message (blank if success)

2) Build the Make.com scenario skeleton

Create a new scenario in Make.com.

Add these modules in this order:

  1. Scheduler (Trigger)
  2. Google Sheets: Get a cell or read row (to fetch last_run_at)
  3. HubSpot: Search/List Deals (filtered by a date window)
  4. Tools: Parse/Aggregate (Make.com mapping and calculations)
  5. Slack: Post message (with Slack blocks)
  6. Google Sheets: Update last_run_at
  7. Google Sheets: Append row to Log

Then add an error handling route:

  • Slack error alert
  • Google Sheets log row with status=failure

3) Configure the schedule and time zone

In Scheduler:

  • Set Frequency: Daily or Weekly depending on your cadence.
  • Set Time zone to match your reporting expectations.
  • Store the Scheduler’s “scheduled time” in a variable for logging.

Gotcha: do not rely on Slack showing dates in your preferred time zone. You are going to compute the window using your Make.com time zone setting, then you will display both dates and UTC in the message context.

4) Define the report window using last_run_at

Use Google Sheets: read last_run_at from the State tab.

Create variables:

  • window_start = last_run_at
  • window_end = now (Make.com current timestamp)

If you want “daily closed deals” instead of “updated deals”, clamp window_start and window_end to local-day boundaries, but only do it if your HubSpot date property behaves the way you expect.

5) Pull only the relevant deals from HubSpot

Add your HubSpot deals module, typically Search/List Deals.

Filter logic you want:

  • Date filter: choose one consistent property to drive the window.
    • If you care about changes, use deal updated date.
    • If you care about close performance, use close date.
  • Fields: request only what you need to compute metrics.

Practical field set to request:

  • deal name
  • deal id
  • amount
  • deal stage
  • close date
  • deal owner id (or owner name)
  • last modified date (if available)

Gotcha: if your dataset is large, ensure the HubSpot module is using pagination or that you loop until all results are retrieved. Otherwise your Slack numbers will drift as the business grows.

6) Aggregate metrics in Make.com

Compute the metrics you want to show.

Example metrics that work well in Slack:

  • Total deals in window
  • Won deals count and won revenue sum
  • Open deals count
  • Top 3 owners by won revenue
  • Stage distribution (top 5 stages by count)

Implementation pattern:

  • Group deals by deal stage and owner
  • Sum amount where appropriate
  • Count records
  • Sort and keep top N

Important: keep amounts numeric until the final Slack formatting step.

7) Post to Slack using blocks, not plain text

Add the Slack: Post message module.

Message structure you can standardise:

  • Header block: “HubSpot Deals Report”
  • Context block: reporting window in both local and ISO format
  • Fields block: key numbers (won deals, won revenue, new deals, open deals)
  • Optional section: stage distribution bullets
  • Optional section: top 3 owners

Also include a deterministic run_id in the message footer:

  • run_id = YYYYMMDD-HHmm derived from the scheduled time

8) Make idempotency real with run_id and update order

Prevent duplicates by only advancing state after Slack post succeeds.

Implementation approach:

  • Generate run_id at the start of the scenario.
  • After the Slack post succeeds:
    • Update State tab last_run_at = window_end
    • Append a success row to Log
  • If the Slack post fails:
    • Do not update last_run_at
    • Append failure row to Log

Why this matters: Make.com retries can cause partial progress. With the wrong update order, you either double-post or skip a window.

9) Add failure handling that alerts Slack and logs the error

Create an error route:

  • Slack module posts to an “ops” channel, not your main sales channel.
  • Slack error message includes:
    • scenario name
    • run_id
    • window start/end
    • error message (shortened)

Then add Google Sheets: append row with status=failure.

Gotcha: keep the error message short enough for Slack readability, but include enough identifiers to correlate with Make.com logs and the window.

Real-World Business Scenario

A mid-market SaaS company runs a weekly “pipeline health” message in Slack for the sales lead and founders. Before automation, the ops coordinator manually pulled a HubSpot report, copied a few numbers, then rechecked whether the report window matched what they discussed last week.

With this setup:

  • The team posts every Monday morning.
  • Slack shows won count, won revenue, top owners, and stage distribution for the previous 7 days.
  • The report never duplicates after retries because last_run_at is only updated after the Slack post succeeds.

The operational win is confidence. When a number looks wrong, you can trace it back to run_id and the exact window_start/window_end saved in Google Sheets.

Common Variations

  1. Split by pipeline or owner team

    • Filter HubSpot deals by pipeline or owner.
    • Post one message per pipeline to different Slack channels.
  2. Attach a CSV export link to Slack

    • Generate a small CSV table of deals used to compute the metrics.
    • Store it in Google Drive (or Make.com storage) and include the link in the Slack message.
  3. Add threshold-based alerts

    • After aggregation, if open deals in certain stages exceed a threshold (for example, more than 21 days in stage), post an extra Slack alert.

A workflow you can trust at 8am

You built an advanced Cross-Platform Automation (XPA) workflow that turns HubSpot deal activity into scheduled Slack reports, using Google Sheets for time-window state, run ids for idempotency, and Slack alerts for failures. This keeps reporting accurate as your dataset grows and reduces admin work to essentially zero.

If you want more implementations like this, Olmec Dynamics builds XPAs for businesses, and you can start by reviewing our Cross-Platform Automation (XPA).

Internal linking note: no related posts found for this specific HubSpot to Slack + Make.com angle in the internal blog index during retrieval, so there are no additional news links to include in this run.