Raphael Napoleon Atikpo
Project 5 of 10 — Marketing Operations & Automation portfolio

Nobody should have to remember to run the weekly report.

A Make.com scenario that pulls GA4 and HubSpot every Monday, writes the week to a historical log without duplicating it, and sends a rule-based executive digest — designed to keep Project 3's dashboard alive without anyone touching it, on free tiers only. Fully designed; not yet built.

GA4 + HubSpot (API)→ Make.com (weekly)→ Historical Log (Sheets)→ Looker Studio + Digest
The planned data path. Phases 0–2 — accounts, schema, connections — are designed click-by-click; Phases 3–11 are roadmapped but not yet built.
3
phases designed in full
12
phases planned, total
~90
est. credits / month
$0
budget

The problem

Project 3 turned four systems into one executive dashboard — but a dashboard is only as current as the last time someone manually re-exported and re-pasted the data behind it. Project 4 named this limitation directly: HubSpot's free tier has no Sheets sync, so every update means re-exporting CSVs by hand, and nothing stops that habit from quietly lapsing. This project's brief was to remove the hands entirely: pull the same kind of marketing data on a schedule, log it so trends become visible instead of overwritten each time, and have the system flag a number that looks wrong — rather than wait for someone to notice the dashboard went stale.

What I set out to build

How the pieces fit together

The system runs as two layers that meet at one place: the Historical Performance Log. One layer pulls and writes; the other reads and reports.

Track A — Write layer (Make.com)

One scheduled scenario reads GA4 and HubSpot through their APIs, checks the log for an existing row, and writes or updates it — never appends blindly.

Track B — Read layer (Sheets + Looker Studio)

WoW formulas and digest-ranking logic live in the Sheet, so Looker Studio and the weekly email read the same numbers instead of each recalculating them separately.

Five layers, each with one job:

Layer 1
Sources

GA4's Data API (sessions, totalUsers, engagementRate, keyEvents by sessionDefaultChannelGroup) and HubSpot's CRM API (contacts, lifecyclestage, deals) — read live through Make, not exported by hand.

Layer 2
Pull

One weekly-scheduled Make.com scenario, built on Make's own OAuth connection rather than a custom Google Cloud project — specifically to avoid a documented weekly-reauthorization trap.

Layer 3
Log

GA4_Weekly_Log and HubSpot_Weekly_Log — wide format, one row per week (per channel, for GA4) — each with a Row_Key formula that makes re-running a week idempotent by design.

Layer 4
Report

The same Sheet feeds Looker Studio's historical trend view and a rule-based Gmail/Slack digest — no second data model to keep in sync.

Layer 5
Delivery

Looker Studio's native scheduled email delivery, plus Make's own digest send — both free-tier features, confirmed against current documentation rather than assumed.

Stack

GA4 Data API HubSpot CRM (Free) Make.com (Free) Google Sheets Looker Studio (Free)

The build, phase by phase

Phases 0–2 — designed in full, not yet executed

The first three phases are written click-by-click: confirming GA4 and HubSpot access, designing the Sheet schema, and proving all three Make connections before any real logic gets built. None of it has run in my own accounts yet — this project starts from a complete plan rather than a blank canvas.

SCREENSHOT TO CAPTURE — Phase 2

Make's three test modules (GA4, HubSpot CRM, Google Sheets) each returning real data on "Run once," before being deleted and rebuilt as the real scenario.

GA4 — pulled live, not snapshotted

Unlike Project 4's one-time GA4 export, this pipeline reads GA4's Data API directly every week through Make's "Generate a Report" module, filtered to sessionDefaultChannelGroup so each channel gets its own log row. The trade-off Project 4 avoided by snapshotting — a live connection that can silently break — is handled here with Phase 9's planned failure notifications instead of a human checking in.

SCREENSHOT TO CAPTURE — Phase 3

The GA4 "Generate a Report" module configured with Property ID, date-range logic, and the channel-group dimension, returning a real weekly bundle.

HubSpot — read through Make's API, no CSV step

Project 4's dashboard depends on someone remembering to export and re-import HubSpot CSVs by hand — a limitation it names directly. This pipeline reads the same lifecyclestage and deal data through Make's HubSpot CRM search modules on the same weekly schedule as GA4, removing that manual step entirely.

SCREENSHOT TO CAPTURE — Phase 4

The HubSpot "Search for Contacts" and "Search for Deals" modules, filtered to the current week, returning real counts.

The idempotency key — decided before any code

Each log row carries a Row_Key formula — the week's date joined to its channel on the GA4 tab, the date alone on the HubSpot tab — so Make can check what already exists before writing. Re-running the same week updates or skips it; it never duplicates. Wide format (one row per week per channel) was chosen over long format specifically because it keeps that check to one lookup per tab per run, not one per metric.

SCREENSHOT TO CAPTURE — Phase 5 / Phase 10

The log after two consecutive runs for the same week: the row count unchanged, Last_Updated_UTC changed.

The operations budget — a worked estimate, not a guess

Before writing a single module, I built a credit table against Make's documented pricing: roughly 19–27 credits per run, 82–117 a month in steady state, against the free plan's 1,000-credit cap. The one honest gap: Make's own documentation doesn't say definitively whether its Iterator module bills per row in addition to the module that processes each row — the estimate covers both cases rather than quoting the flattering one.

What's left

Phases 3–11 — the GA4 pull, the HubSpot pull, idempotent writes, WoW formulas and digest-ranking logic, the Looker Studio connection, digest delivery, scheduling and error handling, testing, and portfolio evidence capture — are roadmapped with time estimates per phase, not yet executed.

What Phase 10 will check

This hasn't been run yet, so this section is the test plan, not test results. These are the checks Phase 10 specifies, with blanks where the real numbers go once it executes.

On results: nothing above has numbers yet because nothing has run. Once built, this section gets real credit counts from Make's execution history, real row counts from two consecutive runs, and a real screenshot of the digest email — not projections.

What I'd tell a hiring manager directly

Decisions and reversals

The instructive moments so far were all in the design, not a debugging session — because there's nothing running yet to debug.

Open at the time of writing

Three things are unresolved because the build hasn't started: whether Make's Iterator module bills credits per row in addition to the write module it feeds (the budget above covers both cases, but I don't yet know which is real); how Phase 7 should connect this Sheet to Project 3's dashboard without disturbing its existing live-GA4 data source; and whether the GA4 demo account would in fact have worked as a Make data source — the real property had enough traffic that the fallback was never tested.

Limitations

What I'd build next