4dim / Notas
A qué hora le escriben a un negocio
Nadie ha publicado la curva por hora en Colombia. Tenemos las bandejas delante y todavía no podemos publicarla: esto es por qué.
La pregunta, y por qué esta nota no la contesta
«¿A qué hora le escriben a un negocio?» Nos la hacen en cada reunión de Connection, y la contestábamos con una intuición.
Esta nota no trae la curva. Trae por qué no la tenemos: lo medido, lo que circula sin fuente, y lo que podemos medir y todavía no publicar.
Lo que sí está medido, y no es la hora
La mejor encuesta de tiempo del país es la ENUT del DANE: cerca de 33.500 hogares, boletín preliminar del 28 de octubre de 2025. Mide cuántas horas al día dedica cada quien a cada actividad. No a qué hora del día: le extrajimos el texto al PDF y buscamos «franja», «hora del día» y «por hora». Ninguna aparece, el 13-09-2026.
DataReportal da la conectividad a octubre de 2025 —41,7 millones de usuarios de internet, el 77,8 % de la población— pero nada por hora, ni penetración de WhatsApp: el «92,1 %» que se le atribuye no está ahí.
| Fuente | Qué mide | Resolución temporal | Comprobado |
|---|---|---|---|
| DANE, ENUT 2024-2025 | tiempo diario por actividad | día, no hora | 13-09-2026 |
| DataReportal, Digital 2026 | usuarios de internet y de redes | ninguna (foto anual) | 13-09-2026 |
| Meta + BCG, Brasil | mensajería empresarial | no publicada (tras formulario) | 13-09-2026 |
| Meta + BCG, México | mensajería empresarial | no publicada (tras formulario) | 13-09-2026 |
Ninguna fila dice «hora». Los informes de Meta y BCG abren, pero sus cifras están tras un formulario: no las hemos leído.
La cifra que circula, y dónde se corta el rastro
El 27 de agosto de 2026, Administradores (Brasil) publicó que el 42,2 % de los mensajes llega fuera del horario comercial, a partir de un estudio de AgeuBot. Fuimos a buscarlo. No está.
| Eslabón | Qué dice | Metodología | Original |
|---|---|---|---|
| Administradores, 27-08-2026 | 57,8 % en horario, 42,2 % fuera; 19 h = +24 % sobre las 8 h; fin de semana = 20 % | no | no enlaza |
| AgeuBot, autor declarado | 1,3 M de mensajes, 62 mil clientes | no | no está en su sitio |
| Blog del proveedor, estadísticas | cita Meta, Statista, Opinion Box, Sebrae y datos internos | ninguna | no |
| Blog, fuera de horario | cita «Meta Business Report 2025», Opinion Box, RD Station, HBR, Gartner, Zendesk | ninguna | no |
Comprobado el 13 de septiembre de 2026. Mide la base de clientes de un vendedor de chatbots, no un mercado, y ni eso se puede comprobar. Ni es la única cifra por franja: en la misma página hay un «38 % de las compras entre las 19 h y las 23 h» de RD Station, igual de suelto.
Tenemos la base de datos delante y aun así no podemos publicar la curva. Decir exactamente por qué es la nota.
Curvas por hora sí hay, de otro continente y otro canal
Aledavood y otros publicaron en PLOS ONE, en 2015, el patrón horario de 74.124 llamadas del Reino Unido; Pintér y Felde lo mismo en Budapest en 2022. La versión de conferencia del primero trae el matiz que más nos importa, y se cita como está escrito: los patrones «pueden diferir» entre llamadas y textos. Potencial, no indicativo — y aun así, la razón de que nuestra consulta separe por canal.
El único conjunto colombiano de alta resolución es de Bogotá y mide desplazamiento; el estudio más cercano al tema, 200 empresas de México y España, consultó solo en horario de atención. Buscamos en DANE, DataReportal, PLOS ONE, SciELO, arXiv y Meta/BCG: existen los métodos, no la medición. Una afirmación negativa vale lo que valga la búsqueda, y por eso va dicho dónde buscamos.
Nuestro dato: la consulta, publicada antes de correrla
Esto es lo que habría que ejecutar sobre las bandejas de Connection, publicado antes de correrlo para que nadie tenga que creernos. created_at es timestamptz: sin huso guardado, la hora local no se recupera y esta nota no existiría.
WITH entrantes AS (
SELECT
EXTRACT(hour FROM m.created_at AT TIME ZONE 'America/Bogota')::int AS hora,
CASE WHEN EXTRACT(isodow FROM m.created_at AT TIME ZONE 'America/Bogota') <= 5
THEN 'lun-vie' ELSE 'sab-dom' END AS dia,
cn.kind AS canal, cv.tenant_id AS negocio, cv.id AS hilo
FROM messages m
JOIN conversations cv ON cv.id = m.conversation_id
JOIN tenants t ON t.id = cv.tenant_id
JOIN connections cn ON cn.id = cv.connection_id
WHERE m.author = 'cliente' -- entrante
AND m.external_id IS NOT NULL -- pasó por Meta de verdad
AND cn.external_id IS NOT NULL -- bandeja con número, no escaparate
AND t.is_demo = false -- cinturón, no tirantes (ap. 07)
AND m.created_at >= timestamptz '2026-08-15 00:00:00-05'
AND m.created_at < date_trunc('month', now() AT TIME ZONE 'America/Bogota')
AT TIME ZONE 'America/Bogota'
)
SELECT canal, dia, hora,
count(DISTINCT hilo) AS hilos,
count(DISTINCT negocio) AS negocios,
round(100.0 * count(*) / sum(count(*)) OVER (PARTITION BY canal, dia), 2) AS pct
FROM entrantes
GROUP BY canal, dia, hora
ORDER BY canal, dia, hora;No hay conteos absolutos en la salida, y es a propósito: la regla del apartado siguiente. Hace falta una segunda, sobre la misma ventana, que cuente lo que la primera tira en silencio — connection_id es ON DELETE SET NULL:
SELECT
count(*) AS entrantes_en_ventana,
count(*) FILTER (WHERE m.external_id IS NULL) AS sin_id_de_meta,
count(*) FILTER (WHERE cv.connection_id IS NULL) AS sin_bandeja,
count(DISTINCT cv.tenant_id) AS negocios, count(DISTINCT cn.id) AS bandejas
FROM messages m
JOIN conversations cv ON cv.id = m.conversation_id
LEFT JOIN connections cn ON cn.id = cv.connection_id
WHERE m.author = 'cliente'
AND m.created_at >= timestamptz '2026-08-15 00:00:00-05'
AND m.created_at < date_trunc('month', now() AT TIME ZONE 'America/Bogota')
AT TIME ZONE 'America/Bogota';Es la que dice cuántas bandejas reales hay. Verificado contra el repositorio del 13 de septiembre de 2026: revalidar el día de correrlo.
Qué no sale de la base, y cómo se impone
La anonimización no es promesa: la salida no tiene una columna de texto libre. Se impone con un rol de solo lectura por columna, no con disciplina:
CREATE ROLE notas_horas NOLOGIN;
GRANT USAGE ON SCHEMA public TO notas_horas;
GRANT SELECT (id, conversation_id, author, external_id, created_at) ON messages TO notas_horas;
GRANT SELECT (id, tenant_id, connection_id) ON conversations TO notas_horas;
GRANT SELECT (id, tenant_id, kind, external_id) ON connections TO notas_horas;
GRANT SELECT (id, is_demo) ON tenants TO notas_horas;Que SELECT * falle bajo privilegios parciales no lo dice la documentación de PostgreSQL: hay que ejecutarlo y publicar el permission denied. Queda una tensión que no conviene esconder: lo único que diría si quien escribe está en otro huso es el indicativo de su número, justo la columna que el rol prohíbe. Proteger el teléfono y saber el país del contacto son incompatibles: elegimos proteger.
La regla: porcentajes, nunca conteos absolutos, porque un conteo por hora deja reconstruir el volumen de un negocio. Se suprime toda celda con menos de 5 negocios o 20 hilos distintos, y de dos en dos — una sola celda tapada se deduce por resta del 100 %. Con un negocio conectado, ese umbral suprime la tabla entera.
Marco: la Ley 1581 de 2012 distingue al Responsable, que decide sobre la base de datos, del Encargado, que la trata por cuenta de aquel. Cada negocio es responsable de sus clientes; nosotros, encargados. Que un agregado sin celdas pequeñas deje de ser dato personal es lectura nuestra, no de la Superintendencia: el permiso lo da el contrato.
Tres trampas de nuestro propio esquema
Guardamos la hora equivocada. created_at es timestamptz DEFAULT now() y el INSERT del webhook no pasa fecha: Meta manda la hora a la que el cliente le dio a enviar y la tiramos — no aparece ni una vez en las 413 líneas del webhook. La curva de hoy sería de cuándo nos llegaron, no de cuándo los escribieron. Cota del sesgo: el webhook espera hasta 8 segundos por el adjunto antes de insertar, lo que como mucho mueve de casilla al 0,222 % de los mensajes con archivo — cálculo nuestro, 8 sobre 3.600, cota superior con llegada uniforme supuesta. Añadir sent_at lo arregla; hasta entonces la hora de envío es irrecuperable.
No sabemos en qué huso vive nadie. tenants no tiene columna de huso: ni «timezone» ni «America/Bogota» aparecen en las migraciones. Y la curva es de los clientes, de los que no sabemos ni eso ni el país.
La razón que nos habíamos contado era falsa. Creíamos que is_demo hacía falta porque el demo fabrica entrantes. No los fabrica: su escalera lleva AND m.author <> 'cliente'. Lo humano se separa de lo fabricado por el id de Meta, vacío cuando llama el simulador.
Cuándo publicaremos la curva
El primer canal de WhatsApp real de 4dimntion se conectó el 15 de agosto de 2026: son 29 días. Cuántas bandejas hay hoy no lo decimos de memoria — desde el 16 de agosto un formulario las da de alta sin pasar por nadie. Publicar la curva ahora sería publicar la agenda de un negocio, el nuestro, y dejar que se cite como la de Medellín. Las tres condiciones:
- Que
sent_atexista y lleve 90 días llenándose. - Que haya cinco bandejas de negocios distintos, para que ninguna celda sea el retrato de uno solo.
- Que el contrato diga expresamente que podemos publicar agregados anonimizados.
Importa más allá de nosotros: la Ley 2191 de 2022 obliga a toda empresa a tener política de desconexión laboral — el derecho a no recibir contacto de trabajo «por fuera de la jornada ordinaria»— y quien no sabe a qué hora le escriben no la escribe con datos.
Al pie: America/Bogota es UTC−5 sin horario de verano desde 1993, según la base de IANA. Si se reinstaurara, las curvas de años distintos dejarían de compararse.
Esta nota sale de nuestro trabajo en Agentes conversacionales.