Daily classified call reporting for a live customer tenant, matching the carrier's own usage report on 149 of 150 call legs.
The problem
The customer ran a certified third-party contact-centre app on top of native Teams call queues and auto attendants, and couldn’t trace a call end-to-end across the two. They wanted daily volume and abandonment reporting — and the solution had to deploy to any customer tenant with no tenant-specific assumptions.
What I did
- Proved the data model with real test calls first: a single Graph call record holds the whole journey — PSTN caller → resource account → queue → answering agent — as nested sessions.
- Wrote a PowerShell classifier that is fully structural, never name-based: queues by user-agent role, people by directory lookup, vendor services by app ID from a shared registry. Adding a new vendor is one JSON entry.
- Turned it into an Azure Automation runbook using managed identity, per-customer Key Vault secrets, Blob output and a locked-down Graph sendMail.
- Built GitHub Actions workflows that onboard and offboard customers with per-customer Bicep and automatically registered OIDC credentials. Validating the shared Bicep with what-if caught three drift bugs before they were applied.
- Built a single-file Call Journey Explorer dashboard with filters, KPI cards and a per-call timeline drill-down.
- Used the same data for a 21-day abandoned-call investigation that separated genuine queue abandons from calls that only ever reached the IVR — explaining why two reporting systems disagreed.
Result
The first live runs surfaced four runtime bugs (including time zones failing inside the Automation sandbox and PowerShell 7.2’s separate module list) — all fixed. Cross-checked against the carrier’s Direct Routing report, 149 of 150 call legs matched within ±15 seconds, and the compute sits comfortably inside the Automation free tier.