Todo el trabajo

Sistema de tracking de llamadas end-to-end

Un sistema de doble ingesta — app Android a medida para pre-venta, webhooks de Twilio para operativa — unificando cada punto de contacto del cliente desde la primera llamada hasta el cierre.

Rol
Software Engineer — diseño, construcción, operación
Período
2024 — Actualidad
Empresa
Agencia de marketing digital (confidencial)

100%

de las llamadas registradas con audio, transcripción y resumen IA

2→1

flujos de captura (Android + Twilio) convergiendo en un solo historial

1 click

para re-transcribir y re-resumir cualquier llamada bajo demanda

#Contexto

La agencia opera ventas para múltiples clientes, con dos equipos que llaman a los clientes de formas completamente distintas. El equipo de pre-venta trabaja desde celulares Android rooteados de la agencia; el equipo operativo llama desde un sistema web con un teléfono embebido. Nada de esa actividad era visible: no había registro de quién llamó a quién, cuánto duró o qué se dijo. Las cotizaciones avanzaban en Kommo CRM sin conexión con las llamadas que las impulsaban, y la gerencia no podía medir el desempeño comercial más allá de las ventas cerradas.

#Problema y restricciones

  • Las llamadas de pre-venta ocurren en celulares Android rooteados de la agencia — ninguna API de grabación de Play Store funciona ahí; capturar audio requiere una app a medida con acceso root (Magisk/superusuario).
  • En el flujo Android no había otro lugar donde guardar las grabaciones — el audio solo existe en el dispositivo, así que el audio completo tiene que vivir en nuestro servidor, y el costo de almacenamiento crece con el volumen de llamadas.
  • Las llamadas de operativa corren por un teléfono Twilio embebido en el sistema web — una vía de captura completamente separada, con grabaciones hospedadas en el proveedor.
  • Los datos de llamadas, los cambios de estado de cotizaciones y la identidad del cliente vivían en sistemas desconectados (celulares, Twilio, Kommo) — sin trazabilidad de punta a punta de pre-venta a post-venta.

#Arquitectura

Android approot · Magisk · loginOwn serverfull audio storedWeb phoneembedded · operationsTwiliowebhook · URL onlyWhisper + LLMtranscript & summaryMongoDBunified timelineKommo CRMquote webhooksKPI dashboardReact
Dos flujos de captura — Android de pre-venta (audio completo) y Twilio de operativa (solo URL) — convergen en un solo historial por cliente.

Flujo 1 — pre-venta: una app Android a medida en los celulares rooteados sigue el estado de llamada del equipo en tiempo real (ringing / offhook / idle vía TelephonyManager). La vendedora se loguea con su cuenta de la agencia, así cada llamada queda vinculada a su ID de trabajador. Al finalizar la llamada, la app sube la metadata (duración, número, entrante/saliente) más el audio completo a nuestro servidor — la grabación solo existe en el dispositivo, así que nuestro servidor es su hogar permanente. Flujo 2 — operativa: las llamadas salen del teléfono Twilio embebido en el sistema web; al terminar, Twilio dispara un webhook a nuestro endpoint y guardamos solo la URL de grabación del proveedor. Un pipeline en segundo plano descarga el audio temporalmente, lo transcribe con Whisper, lo resume con un LLM y descarta la copia local. Ambos flujos — más los webhooks de Kommo que replican cambios de estado de cotizaciones — convergen en el mismo historial unificado por cliente en MongoDB, con trazabilidad completa pre-venta → post-venta, incluyendo señales de interés en otros servicios de la agencia. Cualquier llamada del historial se puede re-transcribir y re-resumir bajo demanda con un botón, reusando el mismo pipeline. Un dashboard en React muestra el embudo (lead → prospecto → cliente) con KPIs por vendedora: llamadas realizadas, cotizaciones por estado, reuniones agendadas.

sales.internal/dashboard

117

Calls

28

Quotes

12

Meetings

Lead
100%
Prospect
58%
Client
24%
SellerCallsQuotesMeetings
A. Torres
47
125
M. Quispe
39
94
L. Ramos
31
73

* Interfaz recreada con datos sintéticos — el sistema productivo contiene datos confidenciales de clientes.

#Decisiones clave y tradeoffs

01App Android a medida con acceso root

Decisión
Construir una app dedicada que captura el estado de llamada (ringing / offhook / idle) vía acceso root (Magisk), con login de la agencia que vincula cada llamada a un ID de trabajador.
Alternativas
Plataformas comerciales de call tracking, u obligar a las vendedoras a registrar llamadas manualmente en el CRM.
Por qué
Ninguna herramienta comercial puede capturar audio en este hardware, y el registro manual falla desde el primer día. El acceso root era una restricción que podíamos convertir en control total de la captura — y el login obligatorio convirtió la atribución en un problema resuelto en vez de una tabla de mapeo.
Costo de equivocarse
Somos dueños del mantenimiento de Android para siempre — una actualización del SO puede romper la captura, y no hay proveedor al que escalar.

02Flujo Android: guardar el audio completo en nuestro servidor

Decisión
Persistir la grabación completa de cada llamada de pre-venta en nuestro propio almacenamiento, junto a su transcripción y resumen.
Alternativas
Procesar el audio en el dispositivo y descartarlo, o subir-y-borrar después de transcribir (conservando solo texto).
Por qué
Son llamadas celulares nativas — no hay ningún proveedor guardando una copia; la grabación solo existe en el celular. Sin almacenamiento en el servidor no hay audio para re-transcribir, auditar una conversación con un cliente o resolver una disputa. Conservarlo además alimenta el botón de re-procesamiento bajo demanda.
Costo de equivocarse
El costo de almacenamiento crece linealmente con el volumen de llamadas — exactamente el tradeoff que rechazamos en el flujo Twilio, aceptado aquí porque no había alternativa. Requiere políticas de retención y monitoreo que el otro flujo no necesita.

03Flujo Twilio: guardar URLs de grabación, no archivos de audio

Decisión
Guardar solo la URL de la grabación hospedada en el proveedor; descargar el audio temporalmente para transcribir y luego descartar la copia local.
Alternativas
Descargar cada grabación permanentemente a nuestro propio object storage para control total.
Por qué
Aquí el proveedor ya hospeda el audio de forma duradera — la transcripción + el resumen es lo que el negocio realmente lee. Duplicar el audio en nuestro storage multiplicaría costos por un valor marginal casi nulo.
Costo de equivocarse
Si Twilio purga grabaciones antiguas, el audio original se pierde — aceptado, porque las transcripciones y resúmenes son el registro duradero en este flujo.

04Un solo historial por cliente en todo el embudo

Decisión
Modelar ambos flujos de llamadas, transcripciones y eventos del CRM como entradas de un solo historial por cliente en MongoDB, en vez de colecciones separadas por fuente.
Alternativas
Mantener llamadas Android, llamadas Twilio y eventos del CRM en esquemas separados y unirlos en el dashboard.
Por qué
Todo consumidor de estos datos — el dashboard, reportes, automatizaciones futuras — quiere 'todo lo que pasó con este cliente', en orden cronológico, sin importar qué equipo o canal lo tocó. Un modelo de eventos unificado hace que esa sea la consulta barata y preserva la trazabilidad pre-venta → post-venta, incluyendo señales de interés en otros servicios de la agencia.
Costo de equivocarse
La ingesta tiene que normalizar dos formatos de evento muy distintos (subida desde el dispositivo vs. webhook del proveedor) desde el inicio — más trabajo de diseño de esquema, y migraciones cuando una fuente cambia su payload.

#Resultados

100%

visibilidad de llamadas — cada llamada registrada, transcrita y resumida

3→1

sistemas consolidados en un solo historial del cliente

Live

panel de KPIs usado a diario para gestionar al equipo de ventas

#Qué haría diferente

Diseñaría antes el esquema de eventos del historial unificado — lo migramos una vez cuando cambiaron los payloads de Kommo, y un envelope versionado desde el día uno lo habría hecho gratis. También agregaría políticas de retención de almacenamiento para el audio del flujo Android desde el inicio; las añadimos después, cuando el volumen hizo visible el costo. Y colas dead-letter en la ingesta de webhooks más temprano — los reintentos transitorios de Twilio nos enseñaron esa lección en producción.

#Stack

AndroidMagisk (root)TwilioNode.jsTypeScriptMongoDBWhisperOpenAIKommo CRMReact