Skip to content

Contratos (Protobuf) ​

English version: Contracts (Protobuf).

Los esquemas de mensajes canónicos de la plataforma, dialer.v1: CallEvent, CallDetailRecord, ComplianceDecision y los mensajes de configuración de tenant/BYOC, se definen una sola vez, en Protobuf, en el repositorio contracts de la organización de Dialer Digital (privado: los comandos de abajo suponen que a tu cuenta de GitHub se le ha dado acceso de lectura).

Si dos servicios de la plataforma hablan entre sí, el mensaje que intercambian está definido ahí, nunca en structs propios de cada servicio. Esta página te muestra cómo consumir esos esquemas en tu propia integración.

Dónde encontrarás (y dónde no) estos mensajes hoy

Los contratos son la fuente de verdad entre servicios de la plataforma. La API REST pública (/v1) habla hoy su propio JSON en snake_case (ver API REST), y el piso en vivo por WebSocket tiene sus propios fotogramas de evento compactos. GET /v1/reports/cdr ya responde dialer.v1.CallDetailRecord como protojson canónico en core main (ver REST API); la entrega pública en protojson de los demás mensajes (webhooks) está en el Roadmap. Genera clientes ahora si te preparas para esas superficies o consumes directamente los flujos de la plataforma; cualquier otra respuesta de /v1 sigue sin ser protojson.

Estructura del repositorio ​

contracts/
├── proto/
│   └── dialer/
│       └── v1/
│           ├── call.proto        # CallEvent + lifecycle payloads
│           ├── cdr.proto         # CallDetailRecord + shared enums
│           ├── compliance.proto  # ComplianceDecision + EvidenceSnapshot
│           └── tenant.proto      # TenantModuleConfig, CarrierTrunk (BYOC)
├── buf.yaml                      # buf module config + lint rules
├── buf.gen.yaml                  # codegen targets (Go, Elixir, TS, Python)
└── Makefile                      # lint / generate / breaking / validate

El directorio gen/ está ignorado por git en el repo: el código generado nunca se commitea. Lo generas tú, fijado a una etiqueta de versión.

Garantías de compatibilidad ​

Dos mecanismos complementarios protegen tu integración:

  1. El paquete versionado dialer.v1. Su contenido solo evoluciona de forma compatible hacia atrás: se pueden añadir campos y valores de enum nuevos; los campos existentes nunca se renombran, cambian de tipo ni se renumeran. Un cambio incompatible en el formato de cable exige un paquete dialer.v2 nuevo, con v1 vivo durante una ventana de migración.
  2. Etiquetas de versión SemVer (vX.Y.Z) en el repo:
    • MAJOR: se introduce un paquete dialer.v(N+1) nuevo o se retira un paquete entero.
    • MINOR: adiciones compatibles hacia atrás (campos, mensajes, valores de enum).
    • PATCH: comentarios, documentación, herramientas; cero cambio en el formato de cable.

La compatibilidad se aplica de forma mecánica: buf breaking corre en el CI del repo contra main y bloquea cualquier pull request que rompa el formato de cable.

Qué significa para ti: fija una etiqueta, escribe tu consumidor para tolerar campos desconocidos y valores de enum desconocidos, y las actualizaciones dentro de v1 nunca te romperán.

Generar código ​

Requisitos previos ​

  • La CLI de buf (la versión que usa el CI del repo está fijada en su fichero de workflow).
  • Solo para el destino Elixir: un protoc-gen-elixir local (mix escript.install hex protobuf, con ~/.mix/escripts en tu PATH). El Buf Schema Registry no tiene plugin remoto de Elixir; Go, TypeScript y Python usan plugins remotos con versión fijada y no necesitan nada en local.

Desde un clon (¡fija una etiqueta!) ​

bash
gh repo clone DialerDigital/contracts
cd contracts
git checkout v1.2.0   # always pin a release tag, never main

make generate         # writes gen/go, gen/elixir, gen/ts, gen/python

O con buf directamente:

bash
buf generate

Los destinos configurados (de buf.gen.yaml):

LenguajePluginConsumidor típico
Gobuf.build/protocolbuffers/go (remoto, fijado)Servicios de backend, herramientas.
TypeScriptbuf.build/bufbuild/es (remoto, fijado — protobuf-es)UIs web, integraciones Node.
Pythonbuf.build/protocolbuffers/python + pyi (remoto, fijado)Datos/ETL, pipelines de IA.
Elixirprotoc-gen-elixir (plugin local)Servicios OTP.

¿Necesitas otro lenguaje? buf.gen.yaml es solo configuración: apunta tu propio buf generate al directorio proto/ con cualquier plugin que ofrezca el BSR.

Vendorizar en tu proyecto ​

Para la mayoría de integraciones la configuración más limpia es un pequeño target de make en tu repo:

makefile
CONTRACTS_TAG := v1.2.0

.PHONY: contracts
contracts:
	rm -rf .contracts && \
	gh repo clone DialerDigital/contracts .contracts -- --depth 1 --branch $(CONTRACTS_TAG) && \
	buf generate .contracts/proto --template buf.gen.local.yaml

con un buf.gen.local.yaml que contenga solo el destino de lenguaje que necesitas.

Consumo defensivo ​

Como dialer.v1 crece con el tiempo, escribe consumidores que sobrevivan a las adiciones:

  • Tolera campos desconocidos. Protobuf lo hace de forma nativa; si transformas a JSON, no falles ante claves inesperadas.
  • Tolera valores de enum desconocidos. Un ReasonCode o Disposition nuevo puede aparecer en una versión MINOR. Mapea los desconocidos a un cajón genérico en lugar de caerte.
  • Usa protojson donde estos mensajes aparezcan como JSON. El código generado para cada lenguaje incluye un parser protojson que hace ida y vuelta correctamente (nombres en camelCase, enteros de 64 bits como cadenas, marcas de tiempo como RFC 3339). Nota: las respuestas REST de /v1 de hoy no son protojson: ver el aviso al principio de esta página.
  • Deduplica por los campos de identidad. eventId / callId / decisionId: la entrega en cualquier punto de la plataforma es al-menos-una-vez.

Un mensaje, todas las superficies (estado objetivo) ​

Cuando se publiquen las superficies del roadmap, un CallDetailRecord obtenido de un endpoint de reportes, recibido en un webhook o decodificado de un flujo binario será el mismo mensaje, interpretable con los mismos bindings generados:

ts
import { CallDetailRecordSchema } from "./gen/dialer/v1/cdr_pb";
import { fromJson } from "@bufbuild/protobuf";

const cdr = fromJson(CallDetailRecordSchema, webhookBody);
console.log(cdr.disposition, cdr.billsec);

Mantenerse al día ​

  • Sigue el feed de releases del repo contracts.
  • Las subidas MINOR son seguras de tomar con calma; solo las necesitas cuando quieres un campo nuevo.
  • Si alguna vez se publica un dialer.v2, las notas de la versión documentarán la ventana de migración durante la cual se emiten ambos paquetes.

Nothing in these docs is legal advice — always confirm compliance posture with your own counsel.