E-commerce Sales Operations Data Pipeline Analytics Automation

Multi-Channel Agent Performance Analytics for a Fitness Equipment Retailer

GrowwStacks unified a fitness equipment manufacturer and retailer's calling and support platforms into a single reporting layer. Calls from JustCall and tickets from Gorgias flow through an automated pipeline into BigQuery, where a cross-platform identity resolution step attributes every conversation to the right agent — feeding live Looker Studio dashboards that refresh daily with no manual exports or copy-pasting between tools.

Multi-Channel Agent Performance Analytics Demo
3
Platforms unified into a single reporting layer
100%
Of calls and tickets logged against the right agent
Zero
Manual exports or copy-pasting between tools
Daily
Refreshed dashboards with no human involvement

The Problem: No Single View of Agent Activity

The client manufactures and sells fitness equipment through a team of sales agents who talk to customers constantly — across calls, emails, and SMS. The conversations were happening; what was missing was any way to see the whole picture. There was no single view of who talked to whom, when the conversation happened, or how it went.

The data existed, but it was scattered across separate platforms with no awareness of each other. The calling tool knew about calls. The support tool knew about tickets. Neither knew about the other, and nothing tied them to the same person. Tracking an individual agent's progress meant opening several tools and manually stitching together a story from fragments. Tracking collective team performance was, in practice, impossible.

The Solution: Automated Ingestion at the Source

GrowwStacks connected directly into the client's communication platforms: JustCall for calls and SMS, and Gorgias for support tickets. Using a combination of webhooks and scheduled HTTP calls, the system pulls in every agent, every call, and every ticket the moment it happens. There are no manual exports and no copy-pasting between tools — the data moves itself.

Ingestion is defensive by design. Duplicate events are removed before anything is written, and any record that fails to insert is logged to a dedicated failure table and raises an alert in the team's messaging channel. A broken feed announces itself rather than quietly leaving gaps in the numbers — which is exactly the property you need when the whole point of the system is to be the source of truth.

Automation workflow receiving call and SMS events by webhook, removing duplicates, and inserting records into BigQuery with error logging
The ingestion workflow — a webhook receives each call and SMS event the moment it happens, duplicates are stripped, and records are written straight into the raw BigQuery tables. Failed events are logged separately and raise an alert rather than disappearing silently.

The Data Pipeline in BigQuery

From ingestion, everything flows into a full data pipeline built in BigQuery. Raw platform data lands first in its own tables, then gets cleaned and de-duplicated into staged tables, then resolves into canonical tables that the reporting layer reads from. Every call and every ticket is logged against the agent who actually handled it, so attribution is exact rather than approximate.

The reporting views sit on top as a deliberate seam. Dashboards read from views, never from raw tables directly, so the pipeline underneath can be restructured — tables renamed, staging logic changed, a new source added — without breaking a single chart. The interface the client sees stays stable while the plumbing behind it stays free to evolve.

BigQuery dataset listing raw and staged tables for calls, tickets and users alongside the canonical agent table and three reporting views
The BigQuery dataset — raw platform tables land first, feed into staged and canonical tables, and surface through three reporting views that the dashboards read from.

Identity Resolution Across Platforms

This is the part that makes the numbers trustworthy. The same agent exists as a separate record on each platform, with no shared identifier between them. Left alone, that means one person is counted twice and every per-agent metric is quietly wrong.

GrowwStacks built an identity resolution layer that normalises each platform's user records, matches them against the existing agent list, and classifies the result. An unrecognised person is inserted as a new canonical agent with a generated unique ID. A recognised person updates the record that already exists rather than creating a second one. One agent, one record, one accurate set of numbers — regardless of how many platforms they appear in.

Agent synchronisation workflow normalising platform users, classifying matches, and either inserting a new canonical agent or updating an existing record
The identity resolution workflow — each platform user is normalised, matched against the existing agent list, and classified. A new person becomes a canonical agent with a generated unique ID; a recognised person updates the record that already exists.

💡 Why identity resolution matters: Without it, a dashboard built on two platforms does not show one team twice as productive. It shows a team of phantom agents, each carrying half their real activity. Every metric above that inherits the error. Resolving identity at the pipeline stage is what makes everything downstream worth reading.

📞
Calls & Tickets
JustCall & Gorgias
📥
Automated Ingestion
Webhooks, de-duplicated
🗄️
BigQuery Pipeline
Raw → staged → canonical
🧩
Identity Resolution
One agent, one record
📊
Live Dashboards
Looker Studio
✓ One Source of Truth
📊 Daily Refresh

Live Reporting

The cleaned, resolved data feeds into Looker Studio, where the client has live dashboards: individual agent scorecards, daily call metrics, and daily ticket metrics, all visualised so performance is readable at a glance rather than reconstructed from raw rows. Each dashboard is built on a dedicated view, so the pipeline underneath can change without breaking what the client sees.

Dashboard views showing daily call metrics, daily ticket metrics, and a combined per-agent scorecard comparing calls and tickets
The reporting layer — daily call metrics, daily ticket metrics, and a combined agent scorecard, each built on a dedicated view so the underlying pipeline can change without breaking the dashboards.

The Outcome

Instead of digging through three different applications trying to piece together what happened, the client opens one dashboard that tells him everything. It updates automatically, every single day, without anyone touching it. The manual reconciliation that used to stand between the team and an honest view of its own performance is simply gone.

The Right Fit — and When It Isn't

This build suits businesses running customer conversations across several disconnected platforms, where per-person accountability matters and where the same people appear in more than one system. Sales teams, support teams, and agencies with distributed agents fit naturally — the more channels a single agent works across, the more valuable a resolved, unified view becomes.

It is less suited to teams operating entirely inside one platform that already reports well on its own, or to teams small enough that a manual weekly review is still faster than building and maintaining a pipeline. The value here scales with fragmentation; where there is little fragmentation, there is little to unify.

Got Questions? We've Got Answers.

Each tool only knows its own activity. The calling platform knows nothing about the support platform, and neither can attribute a person's total workload. Reporting from each tool in isolation means opening several dashboards and manually stitching a story together, and it makes cross-platform per-agent numbers impossible. Landing everything in a BigQuery warehouse creates one place where calls and tickets live side by side, keyed to the same canonical agent, so a single dashboard can show the whole picture without any manual reconciliation.

Normalise, match, then insert or update. The same person exists as a separate record on each platform with no shared identifier between them. A dedicated identity resolution workflow normalises each platform's user records, matches them against the existing canonical agent list, and classifies the result. An unrecognised person is inserted as a new canonical agent with a generated unique ID; a recognised person updates the record that already exists rather than creating a duplicate. From then on, every call and every ticket that person handles is attributed to that single canonical ID, regardless of how many platforms they appear in.

Ingestion is real-time; reporting is daily. Calls and tickets are ingested the moment they happen — a webhook receives each event in real time and writes it into the raw BigQuery tables. The reporting layer then refreshes on a daily cadence with no human involvement, so the dashboards the client opens each morning already reflect the previous day's activity without anyone running an export or touching a spreadsheet.

The views absorb it. Because the dashboards read from reporting views rather than from raw tables directly, a new platform is added by ingesting its data into its own raw tables and extending the identity resolution step to normalise and match that platform's users into the same canonical agent list. Once a new source flows through the staged and canonical tables, its calls or tickets appear against the right agents in the existing views — and the dashboards inherit the new data without needing to be rebuilt.

Yes, through the same logic as live events. Alongside the real-time webhook ingestion, historical records can be pulled in and run through the same de-duplication, staging, and identity resolution steps that live events pass through. That means past calls and tickets are attributed to the same canonical agents as new activity, so the dashboards can show trends over time rather than starting from zero on the day the pipeline goes live.

It is logged and alerted, never lost. Ingestion is defensive by design. Duplicate events are removed before anything is written, and any record that fails to insert is logged to a dedicated failure table and raises an alert in the team's messaging channel. A broken feed announces itself rather than quietly leaving gaps in the numbers — so a failed event can be investigated and replayed instead of silently corrupting the reporting.

See every conversation your team is having.

Unify your calling, support, and messaging platforms into one reporting layer — with accurate per-agent attribution and dashboards that update themselves.