Appearance
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 / validateEl 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:
- 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 paquetedialer.v2nuevo, conv1vivo durante una ventana de migración. - 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.
- MAJOR: se introduce un paquete
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-elixirlocal (mix escript.install hex protobuf, con~/.mix/escriptsen tuPATH). 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/pythonO con buf directamente:
bash
buf generateLos destinos configurados (de buf.gen.yaml):
| Lenguaje | Plugin | Consumidor típico |
|---|---|---|
| Go | buf.build/protocolbuffers/go (remoto, fijado) | Servicios de backend, herramientas. |
| TypeScript | buf.build/bufbuild/es (remoto, fijado — protobuf-es) | UIs web, integraciones Node. |
| Python | buf.build/protocolbuffers/python + pyi (remoto, fijado) | Datos/ETL, pipelines de IA. |
| Elixir | protoc-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.yamlcon 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
ReasonCodeoDispositionnuevo 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
/v1de 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.