Send a weekly sales forecast from Airtable to Slack with Make.com: scheduled pulls, aggregation, idempotent logging, Slack Blocks, and reliable run tracking.
Introduction
A predictable weekly sales forecast gives stakeholders one number they can act on. If you still export Airtable views, compute sums manually, and paste the results into Slack each Monday, you already know the delays and errors this creates.
This guide shows how to build a weekly sales forecast from Airtable to Slack using Make.com, with an idempotent run log in Google Sheets so the report never posts twice and you can always trace the window it covered. What you will know by the end: the scheduled trigger, the Airtable query pattern, the aggregation steps, how to format a Slack Blocks message, and how to test and monitor the first runs.
Primary keyword: weekly sales forecast from Airtable to Slack
What You'll Need
- A Make.com account with a Scheduler and Airtable, Google Sheets, and Slack connections
- An Airtable base with your deals or revenue table and a reliable date property (for example
closed_dateorcreated_at) - A Google Sheet to store the
last_run_attimestamp and an audit log of past runs - A Slack channel for the forecast message and a Slack bot token in Make.com
- Permissions to read the Airtable dataset and post into Slack
Note: If you already run a similar BigQuery pipeline, this pattern is intentionally simpler and focused on Airtable as the single source of truth. For a comparable approach using BigQuery, see our guide on How to Send a Weekly Sales Forecast from BigQuery to Slack Using Make.com. For daily Airtable digests see our Airtable to Gmail digest walkthrough.
How It Works (The Logic)
Trigger (scheduled) → read last_run_at from Google Sheets → query Airtable for the window (last_run_at → now) → aggregate metrics (orders, revenue, average deal value, top accounts) → format Slack Blocks message → post to Slack → write new last_run_at and append run details to the audit sheet.
The key reliability idea is this: update last_run_at only after Slack confirms the message posted successfully, and store a run_id so you can always replay a window if a failure occurs.
Step-by-Step Setup
1) Design the Google Sheet state and audit tabs
Create a Google Sheet with two tabs:
-
Statewith a single row/column:last_run_at(ISO timestamp). Initialise to a sensible past date for the first run, for example2026-07-01T00:00:00Z.
-
Auditwith columns:run_id,window_start,window_end,total_revenue,total_orders,top_account,posted_at,slack_ts,status,error_msg
You will update last_run_at only after the Slack post succeeds and append an Audit row for each run.
2) Create the Make.com scenario and schedule
- New Scenario in Make.com.
- Add Scheduler module, set to run weekly on your chosen day and time. For testing use manual runs or a shorter cadence.
- Add a Google Sheets: Get a cell (or read row) module to fetch
last_run_atfrom theStatetab.
Store those values into window_start and compute window_end = now in Make.com variables.
3) Query Airtable for the relevant records
- Add Airtable: Search Records or List records module.
- Query the table that holds deals or orders using a filter formula or view that selects rows where the chosen date property is between
window_start(exclusive) andwindow_end(inclusive). Example Airtable formula:
AND(IS_AFTER({close_date}, DATETIME_PARSE("{window_start}")), IS_BEFORE({close_date}, DATETIME_PARSE("{window_end}")))
- Request the fields you need for aggregation: amount, account name, owner, stage.
Gotcha: Airtable formula functions vary; test the search with a known window first.
4) Aggregate metrics in Make.com
Use Make.com built-in array and aggregator tools to compute:
- total_orders = count of returned records
- total_revenue = sum of
amount - average_deal_value = total_revenue / max(1,total_orders)
- top_account = the account with the highest summed
amountin the window
Also compute a small distribution by stage (counts per stage) if your team finds that useful.
5) Build the Slack Blocks message
Use a Slack Post Message module with Blocks. A compact structure that reads well in a channel:
- Header block:
:bar_chart: Weekly Sales Forecast — Week of {week_start_local} - Section:
Total orders: {total_orders} • Revenue: {total_revenue_formatted} • AOV: {average_deal_value} - Divider
- Section:
Top account: {top_account} • Close rate or stage note(if you compute it) - Fields block: small bullets for stage distribution like
Proposal: 5, Negotiation: 3, Won: 1 - Context or footer:
Run id: {run_id} • Window: {window_start} → {window_end}and a link to a sheet/dashboard
Make.com can format numbers and dates. Use formatNumber() and formatDate() helpers so Slack shows currency and local dates correctly.
6) Post to Slack and confirm
Add the Slack Blocks payload and run a test. If Slack returns a message timestamp (ts), capture it to the audit row.
7) Only update the last_run_at after Slack success
If Slack response is successful, run these two steps in this exact order:
- Google Sheets: Append row to
Auditwith fields includingrun_id,window_start,window_end,total_revenue,total_orders,top_account,posted_at=now,slack_ts, andstatus=success. - Google Sheets: Update the
Statetablast_run_at=window_end.
If Slack fails or the scenario errors in posting, write a failure Audit row and do not update last_run_at. That way the next run will attempt the same window again rather than skip data.
8) Add an error branch for failed Slack or Sheets writes
Configure Make.com error handling so that if Slack or Sheets fails, the scenario:
- Appends a
status=failurerow toAuditwitherror_msg - Posts an alert to your ops Slack channel including
run_idand a short error summary
This makes it easy to find and replay failed runs.
9) Test: run the scenario manually for two windows
Testing checklist:
- Run once with a small recent window to verify the aggregation logic and Slack formatting.
- Force a failure (for example, change the Slack token to invalid) and confirm the
Auditrow reflectsstatus=failureandlast_run_atremains unchanged. - Correct the error and re-run manually to confirm the same window posts successfully and
last_run_atupdates.
10) Optional extensions
- Create a dashboard link: add a URL to a Looker Studio dashboard that queries your
Auditsheet or Airtable data and include it in the Slack message. - Add owner-level digests: route per-owner summaries to private messages by adding a router that groups deals by owner and posts targeted messages.
- Add CSV attach: if stakeholders want the raw rows, generate a CSV from the returned Airtable records and attach it (upload to Drive and include link in Slack).
Real-World Business Scenario
A subscription company replaced their manual Monday morning pipeline email with a Make.com-driven forecast. The scheduled Make scenario runs early Monday and posts one Slack message with total orders, weekly revenue, AOV, top accounts, and a stage distribution. The ops lead checks the Audit sheet if any number looks unexpectedly high or low. Because last_run_at only updates after a successful Slack post, the team never misses a window due to transient API errors.
Common Variations
- Hourly reporting for ops: reduce the scheduler cadence and keep the same
last_run_atlogic for incremental windows. - Include refunds and net revenue: compute complementary metrics by adding refund events to your Airtable query.
- Use BigQuery or Data Warehouse for larger volumes: if Airtable grows unwieldy, move to a BI table and run the same Make.com aggregation against BigQuery (we have a related guide for Shopify to BigQuery weekly digests).
Closing notes
You now have a repeatable pattern to automate a weekly sales forecast from Airtable to Slack using Make.com. The important production rules are: compute the window from a persisted last_run_at, aggregate only the records in the window, post a single Slack Blocks message, and update the last_run_at only after a successful post so you never skip data.
If you want this implemented for your Airtable schema, templates, and Slack formatting, Olmec Dynamics builds and runs these automations for real teams. See what we do at Olmec Dynamics.