Reading the conversations nobody had time to read.
Company WhatsApp became a company record, with agents that classify conversations and alert management. Later, the same data showed who the team was really talking to.
- < 6%of the contacts found in conversations were already in the CRM.
- 46% → 79%CRM to WhatsApp match rate after normalizing phone numbers.
- Managers → agentsManagement sets what the agents look for, without code changes.
At a glance
- Problem
- Sales work happened on corporate phones' WhatsApp, and the history stayed on each person's device, outside the company.
- My part
- Architecture, stack and production rollout, CRM integration and operational diagnosis.
- Hard call
- Build instead of paying for a more expensive market platform, and let management define what the agents look for, without code changes. Later, pause triage to prioritize the AI budget.
- How I validated
- The data showed fewer than 6% of contacts in conversations were already in the CRM, and normalizing phone numbers raised the match rate from 46% to 79%. A delivery delay reached management in time through the report.
- What changed
- Sales conversations stayed with the company, management got a daily read, and the same data showed the CRM who the team was really talking to.
Sales history has to stay with the company.
Sales work happened on WhatsApp, on company phones. Conversations and contacts lived on each person's device, and the company needed to keep that history.
A market platform did something similar, but it cost more than building our own. I designed the architecture, chose the stack and put it into production in June 2026.
From the company phone to the report.
Each company WhatsApp Business account is mirrored through webhooks into a C# / .NET API that stores conversations and contacts in PostgreSQL. Python and LangGraph agents classify contacts and conversations every few minutes, with a small model and a minimum confidence, and prepare reports for management. A Next.js dashboard shows sessions and conversations in real time.
The team signed a responsibility agreement, only company phones are mirrored and access to conversations is restricted to administrators.
- 01
WhatsApp Business
Conversations on company phones, under a signed agreement.
- 02
C# / .NET API
Webhooks store conversations and contacts.
- 03
PostgreSQL
The company's record of sales history.
- 04
Python agents
Triage with a small model and reports for management.
Management decides what to look for.
Instead of hard-coding what the agents look for, I built settings where management writes what to watch for in conversations and what goes into the daily report.
With that reading, a customer unhappy about a late delivery reached management in time, and a customer harassing a sales rep was identified.
From conversations to the CRM.
When the CRM launched, the data showed who the team was really talking to: fewer than 6% of the contacts found in conversations were already registered. A language model extracts company and context, and deterministic code does the matching, never the other way around.
Normalizing phone numbers raised the CRM to WhatsApp match rate from 46% to 79%. The same conversations became the tone reference for the AI SDR.
Failures that make no noise.
One session showed as connected while receiving no messages at all. The diagnosis came from a field with a single writer that had never been written. The rule that stuck: monitor the absence of writes, not only their presence.
On the conversations screen, an unbounded query accounted for more than half of the database egress. Pagination and fetching only the affected conversation fixed it.
Pausing to prioritize.
I paused triage to free AI budget for IARA inside the CRM and for the AI SDR.
It will come back with structured-output classification and a language model only as a fallback, now under evaluation.

