Skip to content
miguelm
ProjectsExperienceApproachMy storyBlog
PTEN
Let's talk
Back to projects2026 / Explore the case

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.

C# / .NETPythonLangGraphPostgreSQLReact / Next.js
  • < 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.
Same modernization effort
  • A CRM that becomes part of the day.
  • An AI SDR that showed what was missing.
In this project01 / Sales history has to stay with the company.02 / From the company phone to the report.03 / Management decides what to look for.04 / From conversations to the CRM.05 / Failures that make no noise.06 / Pausing to prioritize.
01

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.

02

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.

From company WhatsApp to the report, simplified.
  1. 01

    WhatsApp Business

    Conversations on company phones, under a signed agreement.

  2. 02

    C# / .NET API

    Webhooks store conversations and contacts.

  3. 03

    PostgreSQL

    The company's record of sales history.

  4. 04

    Python agents

    Triage with a small model and reports for management.

03

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.

04

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.

05

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.

06

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.

Collage portrait of Miguel Minotti over paper with blue, red and yellow cutouts.
Art in the eye. Engineering in the delivery.

Let's build
something that matters.

Professional communication in Portuguese and English.

Location: Brazil (UTC-3), remote

Send an email Talk on LinkedIn

miguelminotti.mm@gmail.com

  • Résumé in English (PDF)
  • Résumé in Portuguese (PDF)
Miguel MinottiPop Engineeringmiguelminotti.mm@gmail.com LinkedIn GitHub Back to top