IVR toolkit
Construya flujos de llamadas totalmente personalizados y automatice cada paso de sus interacciones con clientes con nuestro potente kit de herramientas de acciones IVR.
Utilice comandos simples para reproducir audio, recopilar dígitos, conectar llamadas, activar lógica, transmitir audio a sistemas de IA y más - todo dentro de su configuración de telefonía existente.
- Integre IA, automatización o lógica back-end personalizada
- Construya flujos IVR completos sin hardware adicional
- Controle el comportamiento de las llamadas con comandos precisos
Beneficios de la función IVR toolkit
Descubra cómo nuestras funciones le ayudan a trabajar de manera más inteligente, ahorrar tiempo y mejorar cómo se comunica su negocio.
Automatización de llamadas flexible
Defina exactamente cómo debe comportarse cada llamada. Reproduzca indicaciones, recopile entradas, enrute llamadas o ejecute lógica condicional - todo desde un kit de herramientas claro y fácil para desarrolladores.
Diseñado para equipos de desarrollo
Utilice acciones estructuradas que encajen naturalmente en su lógica back-end. Cada acción tiene resultados predecibles, manejo de errores y ejemplos para ayudarle a construir con confianza.
Funciona con su configuración existente
No se necesita nueva infraestructura. Utilice su número de Callfactory y simplemente extienda su lógica de llamadas a través de la API, sus scripts o herramientas de automatización interna.
Kit de herramientas de acciones IVR
Haga clic en una acción para ver su descripción, firma y ejemplos.
Contesta una llamada entrante. Debe llamarse antes de reproducir audio o recopilar entradas en una llamada entrante.
Description
- Marca la llamada como contestada en el lado de la telefonía.
- Requerido antes de usar acciones como
Play,PromptDigit,GatherDigits,Dial,Record, etc., en llamadas entrantes.
Throws
InvalidOperationException- si la llamada ya ha sido contestada.
Signature
void Answer();Example
protected override async Task
HandleCallAsync(CancellationToken ct)
{
// Siempre contestar primero en llamadas entrantes
Answer();
await Play("welcome.wav", ct);
}
Reproduce un archivo de audio para la persona que llama o para un canal saliente.
Description
- Reproduce un archivo de audio (por ejemplo,
.wav) ubicado en el directorio de audio del servidor. - Puede apuntar a la persona que llama entrante o a un OutboundChannel específico.
Parameters
audioFile- Nombre/ruta del archivo relativo al directorio de audio IVR.channel- (opcional) Canal saliente para reproducir audio.ct- Token de cancelación; se cancela cuando la persona que llama o el canal se desconecta.
Returns
PlayResult.Success- Audio reproducido completamente.PlayResult.Fail- Reproducción fallida (por ejemplo, archivo no válido).PlayResult.Cancel- Operación cancelada (por ejemplo, la persona que llama colgó).PlayResult.Error- Error inesperado durante la reproducción.
Throws
OperationCanceledException- Si ct se cancela durante la reproducción.- Otras excepciones de transporte/IO dependiendo de la implementación.
Signatures
Task<PlayResult> Play(
string audioFile,
CancellationToken ct = default);
Task<PlayResult> Play(
string audioFile,
OutboundChannel channel,
CancellationToken ct = default);
Example
protected override async Task HandleCallAsync(CancellationToken ct)
{
Answer();
var result = await Play("welcome.wav", ct);
if (result != PlayResult.Success)
{
Logger.LogWarning("Error al reproducir mensaje de bienvenida (Resultado:
{Result})", result); return;
}
await Play("next_prompt.wav", ct);
}
Reproduce una indicación de audio y recopila un solo dígito DTMF.
Description
- Reproduce una indicación de menú (por ejemplo, ‘Presione 1 para ventas, 2 para soporte, 3 para dejar un mensaje’).
- Espera un solo dígito DTMF: 0-9, *, o #.
- Destinado a selecciones de menú principal.
Parameters
audioFile- Archivo de indicación para reproducir.timeoutSeconds- Cuánto tiempo esperar por un dígito (predeterminado 10).ct- Token de cancelación; cancelado cuando la persona que llama se desconecta.
Returns
MenuResult.Successcon Digit establecido cuando se recibe un dígito.MenuResult.Timeoutcuando no se recibe ningún dígito dentro detimeoutSeconds.MenuResult.Cancelcuando la operación es cancelada.
Throws
OperationCanceledException- Si ct es cancelado (por ejemplo, la persona que llama cuelga).
Signatures
Task<(MenuResult Result, char? Digit)> PromptDigit(
string audioFile,
int timeoutSeconds = 10,
CancellationToken ct = default);
Example
protected override async Task HandleCallAsync(CancellationToken ct)
{
Answer();
await Play("welcome.wav", ct);
var (menuResult, digit) = await PromptDigit(
"main_menu.wav",
timeoutSeconds: 10,
ct);
if (menuResult == MenuResult.Success && digit.HasValue)
{
switch (digit.Value)
{
case '1':
await HandleSales(ct);
break;
case '2':
await HandleSupport(ct);
break;
default:
await Play("invalid_option.wav", ct);
await Hangup(ct);
break;
}
}
else if (menuResult == MenuResult.Timeout)
{
await Play("no_input_goodbye.wav", ct);
await Hangup(ct);
}
else
{
await Play("system_error.wav", ct);
await Hangup(ct);
}
}
Reproduce una indicación y recopila múltiples dígitos DTMF (por ejemplo, número de cuenta, PIN).
Description
- Reproduce una indicación pidiendo a la persona que llama que ingrese varios dígitos.
- Se detiene cuando:
- se alcanza
maxDigits
- se alcanza
- se presiona un dígito de terminación (por ejemplo, #)
- El tiempo de espera expira
Parameters
audioFile– Indicación para reproducir (por ejemplo, “Por favor ingrese su número de cuenta seguido de #”).maxDigits– Máximo de dígitos a recopilar antes de detenerse.terminationDigits– Cadena de dígitos que terminan la recopilación cuando se ingresan.timeoutSeconds– Tiempo máximo para esperar la entrada.ct– Token de cancelación.
Returns
- Tuple (
GatherResult Result,string? Digits): GatherResult.Successy Digits establecidos cuando se recopila la entrada.GatherResult.Timeoutcuando no se recibe entrada.GatherResult.Cancelcuando la operación es cancelada.GatherResult.Erroren error inesperado.
Throws
OperationCanceledException- Si ct es cancelado (la persona que llama cuelga).
Signatures
Task<(GatherResult Result, string? Digits)> GatherDigits(
string audioFile,
int maxDigits = 20,
string terminationDigits = "#",
int timeoutSeconds = 30,
CancellationToken ct = default);
Example
protected override async Task
HandleCallAsync(CancellationToken ct)
{
Answer();
await Play("welcome.wav", ct);
var (result, digits) = await GatherDigits(
"enter_account.wav",
maxDigits: 10,
terminationDigits: "#",
timeoutSeconds: 30,
ct);
if (result == GatherResult.Success && !string.IsNullOrEmpty(digits))
{
await ProcessAccountNumber(digits, ct);
}
else if (result == GatherResult.Timeout)
{
await Play("no_input_goodbye.wav", ct);
await Hangup(ct);
}
else
{
await Play("system_error.wav", ct);
await Hangup(ct);
}
}
Marca uno o más números de teléfono salientes y devuelve un OutboundChannel cuando se contesta.
Description
- Inicia una llamada saliente a un solo destino o a múltiples destinos en paralelo.
- Para múltiples destinos, el primero en contestar gana; todos los demás son cancelados.
Parameters
destination/destinations– Número(s) de teléfono para marcar.callerId– Número para presentar como identificador de llamadas.ringTimeoutSeconds– Tiempo máximo para sonar antes de rendirse.ct– Token de cancelación.
Returns
- Destino único:
(DialerResult Result, OutboundChannel? Channel)- Múltiples destinos:
(DialerResult Result, string? AnsweredDestination, OutboundChannel? Channel)DialerResultpuede ser: Init, Ringing, Answered, Busy, Rejected, NoAnswer, Failed, Cancel.
Throws
OperationCanceledException– Si la operación se cancela mientras se marca.
Signatures
Task<(DialerResult Result, OutboundChannel? Channel)> Dial(
string destination,
string callerId,
int ringTimeoutSeconds = 60,
CancellationToken ct = default);
Task<(DialerResult Result, string? AnsweredDestination,
OutboundChannel? Channel)> Dial(
string[] destinations,
string callerId,
int ringTimeoutSeconds = 40,
CancellationToken ct = default);
Ejemplo (destino único)
private async Task TransferToSupport(CancellationToken ct)
{
var (dialResult, channel) = await Dial(
destination: "18885554444",
callerId: Context.Ani,
ringTimeoutSeconds: 30,
ct);
if (dialResult == DialerResult.Answered && channel != null)
{
await Play("connecting_to_support.wav", ct);
await Connect(channel, ct);
}
else
{
await Play("support_unavailable.wav", ct);
await HandleVoicemail(ct);
}
}
Ejemplo (múltiples destinos)
private async Task TransferToSalesHuntGroup(CancellationToken ct)
{
var salesTeam = new[]
{
"18885551111",
"18885552222",
"18885553333"
};
var (result, answeredNumber, channel) = await Dial(
destinations: salesTeam,
callerId: Context.Ani,
ringTimeoutSeconds: 40,
ct);
if (result == DialerResult.Answered && channel != null)
{
Logger.LogInformation("Conectado con el agente de ventas {Number}", answeredNumber);
await Connect(channel, ct);
}
else
{
await Play("sales_unavailable.wav", ct);
await HandleVoicemail(ct);
}
}
Une el audio entre dos canales.
Description
- Para flujos entrantes: une a la persona que llama entrante con un canal saliente.
- Para escenarios solo salientes: une dos canales salientes juntos.
- Bloquea hasta que un lado cuelga o la conexión se termina de otra manera.
Parameters
channel– Canal saliente para conectar con la llamada entrante.primary,secondary– Dos canales salientes para unir.ct– Token de cancelación.
Returns
ConnectResult.Success– Conexión terminada normalmente (llamada terminada).ConnectResult.Error– No se pudo establecer la conexión o falló.
Throws
OperationCanceledException– Si ct es cancelado mientras está conectado.
Signatures
Task<ConnectResult> Connect(
OutboundChannel channel,
CancellationToken ct = default);
Task<ConnectResult> Connect(
OutboundChannel primary,
OutboundChannel secondary,
CancellationToken ct = default);
Example
protected override async Task HandleCallAsync(CancellationToken ct)
{
Answer();
await Play("connecting_you_now.wav", ct);
var (dialResult, channel) = await Dial(
destination: "18885550000",
callerId: Context.Ani,
ringTimeoutSeconds: 30,
ct);
if (dialResult == DialerResult.Answered && channel != null)
{
var connectResult = await Connect(channel, ct);
Logger.LogInformation("Conexión terminada con resultado: {Result}", connectResult);
}
else
{
await Play("agent_unavailable.wav", ct);
}
await Hangup(ct);
}
Graba audio de la persona que llama o un canal saliente.
Description
- Inicia la grabación ya sea de la persona que llama entrante o un canal saliente específico.
- Termina cuando:
- se alcanza
timeLimitSeconds
- se alcanza
- Se presiona un dígito de terminación (si está configurado)
- La persona que llama o el canal cuelga
Parameters
timeLimitSeconds– Duración máxima de grabación.fileName– Nombre de archivo personalizado opcional (generado automáticamente cuando es nulo).terminationDigits– Dígitos DTMF que detienen la grabación.playBeep– Si reproducir un pitido antes de grabar.channel– Canal saliente opcional.ct– Token de cancelación.
Returns
- Tuple (
RecordResult Result,string? FilePath): RecordResult.SuccessconFilePathguardado.RecordResult.Timeout,MaxDurationReached,TerminationDigit,Cancel,Error.
Throws
OperationCanceledExceptionsi se cancela.
Signatures
Task<(RecordResult Result, string? FilePath)> Record(
int timeLimitSeconds = 120,
string? fileName = null,
string? terminationDigits = null,
bool playBeep = true,
CancellationToken ct = default);
Task<(RecordResult Result, string? FilePath)> Record(
OutboundChannel channel,
int timeLimitSeconds = 120,
string? fileName = null,
string? terminationDigits = null,
bool playBeep = true,
CancellationToken ct = default);
Example
private async Task HandleVoicemail(CancellationToken ct)
{
await Play("leave_message_after_beep.wav", ct);
var (recordResult, filePath) = await Record(
timeLimitSeconds: 180,
fileName: null,
terminationDigits: "#",
playBeep: true,
ct: ct);
if (recordResult == RecordResult.Success && !string.IsNullOrEmpty(filePath))
{
Logger.LogInformation("Correo de voz guardado en {Path}", filePath);
await Play("thank_you_message_received.wav", ct);
}
else
{
Logger.LogWarning("Grabación fallida: {Result}", recordResult);
await Play("recording_failed.wav", ct);
}
await Hangup(ct);
}
Rechaza una llamada entrante con un código de motivo SIP y termina la llamada.
Description
- Utilizado para filtrado de llamadas, bloqueo y comportamiento fuera de horario.
- Devuelve un código de error SIP al operador upstream.
Parameters
reason–RejectReason.Busy,.TemporarilyUnavailable,.Declined.ct– Token de cancelación.
Returns
RejectResult.Success– Llamada rechazada.RejectResult.AlreadyAnswered– Llamada ya contestada.RejectResult.Error– Fallo al rechazar.
Throws
OperationCanceledExceptionsi se cancela.
Signatures
Task<RejectResult> Reject(
RejectReason reason = RejectReason.Busy,
CancellationToken ct = default);
Example
protected override async Task HandleCallAsync(CancellationToken ct)
{
if (IsBlockedNumber(Context.Ani))
{
await Reject(RejectReason.Declined, ct);
return;
}
if (!IsWithinBusinessHours(DateTime.UtcNow))
{
await Reject(RejectReason.TemporarilyUnavailable, ct);
return;
}
// Flujo normal
Answer();
await Play("welcome.wav", ct);
}
Termina limpiamente la llamada activa.
Description
- Termina la llamada desde el lado del IVR.
Returns
HangupResult.Success– Llamada terminada exitosamente.HangupResult.NotAnswered– Nunca contestada.HangupResult.AlreadyDisconnected– La persona que llama colgó.HangupResult.Error– Fallo al colgar.
Throws
OperationCanceledExceptionsi se cancela.
Signature
Task<HangupResult> Hangup(CancellationToken ct = default);
Example
protected override async Task HandleCallAsync(CancellationToken ct)
{
Answer();
await Play("goodbye.wav", ct);
var result = await Hangup(ct);
Logger.LogInformation("Resultado de Hangup: {Result}", result);
}
Pausa la ejecución por un número dado de segundos.
Description
- Espera durante durationSeconds mientras mantiene la llamada abierta.
- Puede ser interrumpido por entrada DTMF dependiendo de la implementación.
Parameters
durationSeconds– Duración en segundos.ct– Token de cancelación.
Returns
PauseResult.Success– Pausa completada normalmente.PauseResult.Interrupted– La persona que llama presionó una tecla durante la pausa (si es compatible).PauseResult.Cancel– Operación cancelada.PauseResult.Error– Pausa fallida.
Throws
OperationCanceledException– Si ct es cancelado.
Signatures
Task<PauseResult> Pause(
int durationSeconds,
CancellationToken ct = default
);
Example
protected override async Task HandleCallAsync(CancellationToken ct)
{
Answer();
await Play("please_wait.wav", ct);
var result = await Pause(3, ct);
if (result == PauseResult.Interrupted)
{
await Play("you_pressed_a_key.wav", ct);
}
else
{
await Play("thank_you_for_waiting.wav", ct);
}
await Hangup(ct);
}
Envía una señal de ocupado a la persona que llama y termina la llamada.
Description
- Presenta un tono de ocupado estándar.
- Comúnmente utilizado cuando todos los agentes/líneas están ocupados.
Returns
BusyResult.Success– Señal de ocupado enviada y llamada terminada.BusyResult.Cancel– Operación cancelada.BusyResult.Error– Fallo al enviar señal de ocupado o terminar la llamada.
Throws
OperationCanceledException– Si ct es cancelado.
Signature
Task<BusyResult> Busy(CancellationToken ct = default);
Example
protected override async Task HandleCallAsync(CancellationToken ct)
{
if (AllAgentsBusy())
{
var result = await Busy(ct);
Logger.LogInformation("Resultado de Busy: {Result}", result);
return;
}
// De lo contrario, proceder con el flujo normal
Answer();
await Play("welcome.wav", ct);
}
Inicia la transmisión del audio en vivo de la llamada a un punto final externo (por ejemplo, motor de IA o STT).
Description
- Abre una transmisión de medios en tiempo real desde la llamada a la url dada (por ejemplo, endpoint WebSocket).
- Típicamente utilizado para enviar audio a:
- un asistente de IA,
- un motor de voz a texto,
- un servicio de análisis/monitoreo personalizado.
- Solo se recomienda una transmisión activa por llamada.
Parameters
url– Endpoint de transmisión de destino (por ejemplo,wss://ai.callfactory.nl/voice-stream).options– Configuración de transmisión opcional (dirección, metadatos, nombre).ct– Token de cancelación. Si se cancela, la transmisión se cierra.
Throws
OperationCanceledException– Si ct se cancela durante la configuración.- Excepciones de conexión/transporte dependiendo de la implementación.
Firmas
Task<StreamResult> StartStream(
string url,
StreamOptions? options = null,
CancellationToken ct = default
);
Parámetros
public class StreamOptions
{
public string? Name { get; set; } //
Nombre de transmisión opcional
public StreamDirection Direction { get; set; } =
StreamDirection.Both;
public Dictionary<string, string>? Metadata { get; set; }
}
public enum StreamDirection
{
Inbound, // De la persona que llama a la IA
Outbound, // Del agente/sistema a la IA
Both // Ambos
}
Devoluciones
public enum StreamResult
{
Started, // Transmisión iniciada exitosamente
Stopped, // Transmisión detenida exitosamente (para StopStream)
AlreadyStarted, // Una transmisión ya está activa
NotActive, // No hay transmisión activa (para StopStream)
Error // Fallo al iniciar/detener
}
Example
protected override async Task
HandleCallAsync(CancellationToken ct)
{
Answer();
// Iniciar transmisión de audio de la persona que llama a la IA
var streamResult = await StartStream(
url: "wss://ai.callfactory.nl/voice-stream",
options: new StreamOptions
{
Name = "support-ai",
Direction = StreamDirection.Inbound,
Metadata = new Dictionary<string, string>
{
["caller"] = Context.Ani,
["dnis"] = Context.Dnis
}
},
ct
);
if (streamResult != StreamResult.Started)
{
Logger.LogWarning("Fallo al iniciar transmisión de IA:
{Result}", streamResult);
await Play("ai_unavailable.wav", ct);
await Hangup(ct);
return;
}
await Play("connected_to_ai.wav", ct);
// Continuar lógica IVR mientras la transmisión está activa...
var (menuResult, digit) = await
PromptDigit("ai_menu.wav", 30, ct);
if (menuResult == MenuResult.Success && digit == '0')
{
// La persona que llama quiere un agente humano
await StopStream(ct);
await Play("transferring_to_human_agent.wav", ct);
await TransferToHuman(ct);
}
else
{
await Play("thank_you_goodbye.wav", ct);
await StopStream(ct);
await Hangup(ct);
}
}
Detiene una transmisión de audio activa que se inició previamente con StartStream.
Description
- Cierra con gracia la transmisión de medios activa.
- No cuelga la llamada - solo deja de enviar audio.
- Seguro de llamar incluso si no hay transmisión activa (devuelve
NotActive).
Parameters
ct– Token de cancelación.
Returns
StreamResult.Stopped– Transmisión detenida exitosamente.StreamResult.NotActive– No se encontró transmisión activa.StreamResult.Error– Fallo al detener la transmisión.
Throws
OperationCanceledException– Sictes cancelado.
Signatures
Task<StreamResult> StopStream(
CancellationToken ct = default);
Example
private async Task TransferToHuman(CancellationToken ct)
{
// Detener transmisión de IA antes de transferir a humano
var stopResult = await StopStream(ct);
Logger.LogInformation("Resultado de StopStream: {Result}",
stopResult);
await Play("transferring_to_agent.wav", ct);
var (dialResult, channel) = await Dial(
destination: "18005550000",
callerId: Context.Ani,
ringTimeoutSeconds: 30,
ct
);
if (dialResult == DialerResult.Answered && channel !=
null)
{
await Connect(channel, ct);
}
else
{
await Play("agent_unavailable.wav", ct);
await Hangup(ct);
}
}
Por qué es importante
El kit de herramientas IVR le da a su equipo control total sobre los flujos de llamadas. Desde menús simples hasta interacciones complejas impulsadas por IA - todo es posible con nuestra biblioteca de acciones.
Estas herramientas son especialmente útiles para equipos que construyen soluciones de telefonía personalizadas, implementan integraciones de IA o extienden sistemas existentes con lógica de llamadas avanzada.
Esta función se incluye de forma gratuita con cada número de empresa español o número internacional.
Aprenda más sobre otras funciones
Encuentre más información sobre nuestras funciones que pueden impulsar las comunicaciones de su negocio.
FAQ del kit de herramientas IVR
Obtenga respuestas claras sobre el kit de herramientas IVR y cómo funciona para su negocio.
Puede construir flujos utilizando nuestras acciones IVR dentro de su panel. Cada acción incluye ejemplos, firmas y comportamiento predecible, por lo que puede implementar lógica sin necesitar nuevo hardware de telefonía.
Puede crear flujos simples sin codificación, pero el kit de herramientas está construido para equipos que desean automatizar o integrar lógica. Los desarrolladores pueden usar acciones estructuradas para activar indicaciones, capturar dígitos o conectar llamadas programáticamente.
Sí. Puede activar llamadas API, enviar datos a su back-end o transmitir audio a servicios de IA o STT. El kit de herramientas encaja naturalmente en su infraestructura existente.
Absolutamente. No necesita cambiar su configuración. Todas las acciones IVR funcionan con sus números, enrutamiento y configuración de llamadas existentes de Callfactory.
Sí. Puede construir y previsualizar sus flujos de forma segura. El kit de herramientas le permite simular indicaciones, recopilación de entradas y comportamiento de enrutamiento antes de activar cambios para llamadas reales.
Usted decide el comportamiento. Puede reproducir una indicación, enrutar a correo de voz, conectar con soporte o terminar la llamada. Cada acción IVR admite manejo de errores personalizado.
Sí. Cada acción incluye manejo de tiempo de espera y lógica de respaldo opcional. Puede definir qué sucede cuando no se recibe entrada o cuando una persona que llama cuelga.
Sí. El kit de herramientas fue diseñado para encadenar acciones juntas. Puede reproducir audio, recopilar dígitos, ejecutar lógica, llamar a una API y transferir llamadas - todo en un solo flujo.
Sí. El sistema está diseñado para confiabilidad y escala. Ya sea que dirija una pequeña empresa o un centro de llamadas de alto volumen, todas las acciones ofrecen rendimiento predecible.
Si su equipo necesita orientación, podemos ayudar a revisar su diseño de flujo, probar su configuración o apoyar una lógica de enrutamiento más avanzada.









