Skip to content
All case studies
Automation Reporting Slack

Automating leadership reporting into Slack

Leadership wanted the key numbers in Slack every morning. Four scheduled bots now post them automatically.

4

scheduled Slack reports

9 AM

delivered on schedule, hands-off

5h+

of manual report pulling saved each week

11

funnel metrics per region & channel

The client

A whisky and wine investment platform offering individuals the opportunity to diversify their portfolios through rare and premium products. The platform combines fintech, alternative asset investing, and client advisory. It operates across multiple markets with high-volume lead generation, investor relations, and financial operations.

The problem

The CFO and growth team were assembling these updates themselves - pulling the figures from dashboards and several different sources by hand, then posting them. It took hours every time. They didn't need another dashboard to log into; they wanted the first insights pushed to them in Slack, quickly, every morning, without anyone assembling anything.

Architecture

flowchart LR SCH["Cloud Scheduler
daily / weekly / monthly cron"] -->|HTTP trigger| CF["Cloud Functions
Python"] CF -->|SQL| BQ[("BigQuery
reporting views")] BQ -->|rows| CF CF -->|Block Kit / mrkdwn| SL["Slack Web API
chat.postMessage"] SL --> A["CFO channel"] SL --> B["Marketing channel"] style SCH fill:#f0e8db,stroke:#1a1a2e style CF fill:#b6e0c2,stroke:#1a1a2e style BQ fill:#d8c8ed,stroke:#1a1a2e style SL fill:#7551c3,stroke:#1a1a2e,color:#fff style A fill:#f4c8a8,stroke:#1a1a2e style B fill:#f4c8a8,stroke:#1a1a2e

What I did

  • 01.Built four scheduled Slack reports: a combined weekly + monthly finance brief, plus daily, weekly, and monthly marketing pulses.
  • 02.Each runs as a Python Google Cloud Function, HTTP-triggered by Cloud Scheduler on its own cadence - no server, no one pressing send.
  • 03.The finance brief joins the weekly and monthly finance views on the latest week and posts revenue, budget attainment, and cash position, with an optional manual note injected via config.
  • 04.The marketing pulses post a multi-stage acquisition funnel - spend, leads, cost-per-lead, signups, qualified, meetings and the conversion rate at each step - broken down by total, region, and acquisition channel.
  • 05.Weekly and monthly pulses add period-over-period deltas on every metric; the daily pulse deliberately omits them because single-day data is too noisy for that comparison to mean anything.
  • 06.Formatted everything with Slack Block Kit and mrkdwn - headers, dividers, flag emojis, mobile-friendly layout - plus notification fallback text so the preview is still useful.

InteractiveSee it run

Pick a report - watch the scheduler post it to Slack

Sample figures - message formats mirror the live bots

# marketing-pulse

Every day · 09:00
Cloud Scheduler Cloud Function · BigQuery Post to Slack
Today

Result

What changed once the reports sent themselves.

The numbers come to them

Leadership reads the morning brief in Slack, on their phone. Nobody opens a dashboard or waits on an analyst to pull the figures.

Zero manual effort

Cloud Scheduler runs every report on cadence. No copy-paste, no recurring calendar reminder, no single point of failure if someone's away.

One source of truth

Every figure comes from the governed reporting views, so the number in Slack always matches the warehouse and the dashboards.

Built to stay signal

A tight metric set and cadence-appropriate deltas keep each message dense with signal instead of drowning the channel in noise.

Tools used

Python Google Cloud Functions Cloud Scheduler BigQuery Slack API Block Kit

A similar problem in your stack?

Send me the rough shape of it. I'll figure out scope on a 30-min call.

Book a call