Nota de idioma
Esta versión en español es una traducción abreviada: las secciones «3. Validate before you publish», «7. The visual builder — the same graph, without the JSON» y «8. Version and roll back» existen solo en inglés: /en/guides/build-ivr-flow. Los bloques de código, rutas de endpoints, nombres de campos de API y códigos de error permanecen en inglés.Construir y publicar su primer flujo IVR
Un flujo IVR es un grafo{ nodes, edges } que se envía a un único conjunto de endpoints. En la creación y en cada edición, el validador de grafos corre antes de persistir; publicar copia el borrador al snapshot en vivo; y un simulador le permite conducir un llamante guionizado por el grafo antes de que suene un DID.
Construiremos un pequeño flujo de estilo aerolínea: saludar al llamante, enrutar los intents de reserva o reembolso a una cola ACD y caer al buzón de voz si nada coincide.
1. Primitivas IVR
Las definiciones de flujo las ejecuta el runtime de voice contra el pipeline de verbos de Jambonz. El validador de grafos — que corre en cada create y update — verifica exactamente un nodo de entrada (tipoivrStart), al menos un nodo terminal (hangup, transfer, voicemail, ringGroup, dialByName, offerCallback, offerSmsCallback, scheduleCallback), que cada edge referencie ids de nodos existentes, que todo nodo sea alcanzable desde la entrada y que ningún nodo alcanzable quede atrapado en un ciclo sin ruta a un terminal. Los bloques reflejan la DSL de voice programmable — vea la Programmable Voice DSL reference.
Los intents de voz complementan los menús DTMF: los tipos de nodo speechInput y dialByName comparan un enunciado libre contra speechIntents por nodo. La página de concepto IVR intents explica esos buckets.
2. Construir el flujo
Envíe la definición aPOST /api/v1/voice/ivr-flows. El cuerpo acepta name, el grafo definition y un flag active opcional. El validador corre antes de persistir, así que un grafo malformado devuelve 422 IVR_FLOW_GRAPH_INVALID y nada se almacena.
cURL
id del flujo nuevo (un identificador ivr_*) — guárdelo; cada paso posterior lo usa.
Los nodos menu ramifican una edge por tecla DTMF presente en menuOptions; el validador rechaza claves vacías, duplicadas o no DTMF con menu_empty_key, menu_duplicate_key o menu_invalid_key.
4. Probar con el simulador
Conduzca un llamante guionizado por el grafo antes de adjuntarlo a un DID.POST /api/v1/voice/ivr-flows/:id/simulate consume turns (cada una con digits, speech y/o intent) y devuelve, por cada paso, el id del nodo visitado, el handle tomado, las categorías de verbos emitidas y el termination_reason.
cURL
reached_nodes: ["start","welcome","menu","bookings"], emitted_verbs con gather en el menú y enqueue en la cola, y termination_reason: "queue_answered". Una simulación en rojo atrapa regresiones de enrutado antes de quemar un minuto en vivo.
Opciones útiles: source: "published" recorre el snapshot en vivo, source: "draft" (defecto) el borrador sin guardar.
5. Adjuntar el flujo a un DID
La configuración de enrutado entrante de cada DID lleva la referencia al flujo. Fijetype: "ivr" con config.flowId:
cURL
6. Entregar a un agente
Enrute la ramasupport a una cola ACD vía un nodo queue para que un miembro del equipo atienda desde el dashboard, o dirija el flujo entero a un agente de IA cuyo endpoint de handback conserva la conversación y devuelve al AI una vez resuelta la excepción por un humano.