Ottieni numeri locali, nazionali e internazionali direttamente online.
🤖 IVR pronto per l'IA

IVR toolkit

Crea flussi di chiamate completamente personalizzati e automatizza ogni fase delle tue interazioni con i clienti con il nostro potente toolkit di azioni IVR.

Usa comandi semplici per riprodurre audio, raccogliere cifre, connettere chiamanti, attivare logiche, trasmettere audio a sistemi di IA e molto altro - tutto all’interno della tua configurazione telefonica esistente.

  • Integra IA, automazione o logica back-end personalizzata
  • Crea flussi IVR completi senza hardware aggiuntivo
  • Controlla il comportamento delle chiamate con comandi precisi

Vantaggi della funzionalità Toolkit IVR

Scopri come le nostre funzionalità ti aiutano a lavorare in modo più intelligente, risparmiare tempo e migliorare il modo in cui la tua azienda comunica.

🧩

Automazione delle chiamate flessibile

Definisci esattamente come deve comportarsi ogni chiamata. Riproduci messaggi, raccogli input, indirizza i chiamanti o esegui logiche condizionali - tutto da un unico toolkit chiaro e adatto agli sviluppatori.

⚙️

Progettato per i team di sviluppo

Usa azioni strutturate che si adattano naturalmente alla tua logica back-end. Ogni azione ha risultati prevedibili, gestione degli errori ed esempi per aiutarti a costruire con sicurezza.

🔧

Funziona con la tua configurazione esistente

Nessuna nuova infrastruttura necessaria. Usa il tuo numero Callfactory e semplicemente estendi la tua logica di chiamata tramite l'API, i tuoi script o strumenti di automazione interni.

Toolkit di Azioni IVR

Clicca su un'azione per visualizzare la sua descrizione, firma ed esempi.

Risponde a una chiamata in arrivo. Deve essere chiamato prima di riprodurre audio o raccogliere input su una chiamata in arrivo.

Description

  • Segna la chiamata come risposta dal lato telefonia.
  • Richiesto prima di usare azioni come Play, PromptDigit, GatherDigits, Dial, Record, ecc., sulle chiamate in arrivo.

Throws

  • InvalidOperationException - se la chiamata è già stata risposta.

Signature

void Answer();

Example

protected override async Task 
HandleCallAsync(CancellationToken ct)
{
    // Rispondi sempre prima alle chiamate in arrivo
    Answer();

    await Play("welcome.wav", ct);
}

Riproduce un file audio al chiamante o a un canale in uscita.

Description

  • Riproduce un file audio (es. .wav) situato nella directory audio del server.
  • Può essere indirizzato al chiamante in arrivo o a uno specifico OutboundChannel.

Parameters

  • audioFile - Nome/percorso del file relativo alla directory audio IVR.
  • channel - (opzionale) Canale in uscita su cui riprodurre l’audio.
  • ct - Token di cancellazione; cancellato quando il chiamante o il canale si disconnette.

Returns

  • PlayResult.Success - Audio riprodotto completamente.
  • PlayResult.Fail - Riproduzione fallita (es. file non valido).
  • PlayResult.Cancel - Operazione cancellata (es. il chiamante ha riagganciato).
  • PlayResult.Error - Errore imprevisto durante la riproduzione.

Throws

  • OperationCanceledException - Se ct viene cancellato durante la riproduzione.
  • Altre eccezioni di trasporto/IO a seconda dell’implementazione.

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("Impossibile riprodurre il messaggio di benvenuto (Risultato:
        {Result})", result); return;
    }

    await Play("next_prompt.wav", ct);
}

Riproduce un messaggio audio e raccoglie una singola cifra DTMF.

Description

  • Riproduce un messaggio di menu (es. ‘Premi 1 per le vendite, 2 per il supporto, 3 per lasciare un messaggio’).
  • Attende una singola cifra DTMF: 0-9, *, o #.
  • Destinato alle selezioni del menu principale.

Parameters

  • audioFile - File del messaggio da riprodurre.
  • timeoutSeconds - Quanto tempo attendere una cifra (predefinito 10).
  • ct - Token di cancellazione; cancellato quando il chiamante si disconnette.

Returns

  • MenuResult.Success con Digit impostato quando viene ricevuta una cifra.
  • MenuResult.Timeout quando non viene ricevuta alcuna cifra entro timeoutSeconds.
  • MenuResult.Cancel quando l’operazione viene cancellata.

Throws

  • OperationCanceledException - Se ct viene cancellato (es. il chiamante riaggancia).

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);
    }
}

Riproduce un messaggio e raccoglie più cifre DTMF (es. numero conto, PIN).

Description

  • Riproduce un messaggio chiedendo al chiamante di inserire diverse cifre.
  • Si ferma quando:
    • viene raggiunto maxDigits
    • viene premuta una cifra di terminazione (es. #)
    • scade il timeout

Parameters

  • audioFile – Messaggio da riprodurre (es. “Inserisci il tuo numero di conto seguito da #”).
  • maxDigits – Numero massimo di cifre da raccogliere prima di fermarsi.
  • terminationDigits – Stringa di cifre che terminano la raccolta quando inserite.
  • timeoutSeconds – Tempo massimo di attesa per l’input.
  • ct – Token di cancellazione.

Returns

  • Tuple (GatherResult Result, string? Digits):
  • GatherResult.Success e Digits impostati quando l’input è raccolto.
  • GatherResult.Timeout quando non viene ricevuto alcun input.
  • GatherResult.Cancel quando l’operazione viene cancellata.
  • GatherResult.Error in caso di errore imprevisto.

Throws

  • OperationCanceledException - Se ct viene cancellato (il chiamante riaggancia).

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);
    }
}

Chiama uno o più numeri di telefono in uscita e restituisce un OutboundChannel quando viene risposta.

Description

  • Avvia una chiamata in uscita verso una singola destinazione o verso più destinazioni in parallelo.
  • Per destinazioni multiple, il primo che risponde vince; tutte le altre vengono cancellate.

Parameters

  • destination / destinations – Numero(i) di telefono da chiamare.
  • callerId – Numero da presentare come ID chiamante.
  • ringTimeoutSeconds – Tempo massimo di squillo prima di rinunciare.
  • ct – Token di cancellazione.

Returns

  • Singola destinazione:
  • (DialerResult Result, OutboundChannel? Channel)
  • Multiple destinazioni:
  • (DialerResult Result, string? AnsweredDestination, OutboundChannel? Channel)
  • DialerResult può essere: Init, Ringing, Answered, Busy, Rejected, NoAnswer, Failed, Cancel.

Throws

  • OperationCanceledException – Se l’operazione viene cancellata durante la composizione.

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);

Esempio (singola destinazione)

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);
    }
}

Esempio (multiple destinazioni)

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("Connesso all'agente di vendita {Number}", answeredNumber);
        await Connect(channel, ct);
    }
    else
    {
        await Play("sales_unavailable.wav", ct);
        await HandleVoicemail(ct);
    }
}

Collega l'audio tra due canali.

Description

  • Per i flussi in arrivo: collega il chiamante in arrivo a un canale in uscita.
  • Solo per scenari in uscita: collega due canali in uscita insieme.
  • Blocca finché un lato non riaggancia o la connessione non viene altrimenti terminata.

Parameters

  • channel – Canale in uscita da connettere alla chiamata in arrivo.
  • primary, secondary – Due canali in uscita da collegare.
  • ct – Token di cancellazione.

Returns

  • ConnectResult.Success – Connessione terminata normalmente (chiamata terminata).
  • ConnectResult.Error – Impossibile stabilire la connessione o connessione fallita.

Throws

  • OperationCanceledException – Se ct viene cancellato mentre connesso.

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("Connessione terminata con risultato: {Result}", connectResult);
    }
    else
    {
        await Play("agent_unavailable.wav", ct);
    }

    await Hangup(ct);
}

Registra l'audio dal chiamante o da un canale in uscita.

Description

  • Avvia la registrazione dal chiamante in arrivo o da uno specifico canale in uscita.
  • Termina quando:
    • viene raggiunto timeLimitSeconds
    • viene premuta una cifra di terminazione (se configurata)
    • il chiamante o il canale riaggancia

Parameters

  • timeLimitSeconds – Durata massima della registrazione.
  • fileName – Nome file personalizzato opzionale (generato automaticamente se null).
  • terminationDigits – Cifre DTMF che fermano la registrazione.
  • playBeep – Se riprodurre un bip prima della registrazione.
  • channel – Canale in uscita opzionale.
  • ct – Token di cancellazione.

Returns

  • Tuple (RecordResult Result, string? FilePath):
  • RecordResult.Success con FilePath salvato.
  • RecordResult.Timeout, MaxDurationReached, TerminationDigit, Cancel, Error.

Throws

  • OperationCanceledException se cancellato.

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("Messaggio vocale salvato in {Path}", filePath);
        await Play("thank_you_message_received.wav", ct);
    }
    else
    {
        Logger.LogWarning("Registrazione fallita: {Result}", recordResult);
        await Play("recording_failed.wav", ct);
    }

    await Hangup(ct);
}

Rifiuta una chiamata in arrivo con un codice motivo SIP e termina la chiamata.

Description

  • Usato per filtrare le chiamate, bloccare e gestire il comportamento fuori orario.
  • Restituisce un codice di errore SIP all’operatore a monte.

Parameters

  • reasonRejectReason.Busy, .TemporarilyUnavailable, .Declined.
  • ct – Token di cancellazione.

Returns

  • RejectResult.Success – Chiamata rifiutata.
  • RejectResult.AlreadyAnswered – Chiamata già risposta.
  • RejectResult.Error – Impossibile rifiutare.

Throws

  • OperationCanceledException se cancellato.

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;
    }

    // Flusso normale
    Answer();
    await Play("welcome.wav", ct);
}

Termina in modo pulito la chiamata attiva.

Description

  • Termina la chiamata dal lato IVR.

Returns

  • HangupResult.Success – Chiamata terminata con successo.
  • HangupResult.NotAnswered – Mai risposto.
  • HangupResult.AlreadyDisconnected – Il chiamante ha riagganciato.
  • HangupResult.Error – Riaggancio fallito.

Throws

  • OperationCanceledException se cancellato.

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("Risultato del riaggancio: {Result}", result);
}

Mette in pausa l'esecuzione per un dato numero di secondi.

Description

  • Attende per durationSeconds mantenendo la chiamata aperta.
  • Può essere interrotto da input DTMF a seconda dell’implementazione.

Parameters

  • durationSeconds – Durata in secondi.
  • ct – Token di cancellazione.

Returns

  • PauseResult.Success – Pausa completata normalmente.
  • PauseResult.Interrupted – Il chiamante ha premuto un tasto durante la pausa (se supportato).
  • PauseResult.Cancel – Operazione cancellata.
  • PauseResult.Error – Pausa fallita.

Throws

  • OperationCanceledException – Se ct viene cancellato.

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);
}

Invia un segnale di occupato al chiamante e termina la chiamata.

Description

  • Presenta un tono di occupato standard.
  • Comunemente usato quando tutti gli agenti/linee sono occupati.

Returns

  • BusyResult.Success – Segnale di occupato inviato e chiamata terminata.
  • BusyResult.Cancel – Operazione cancellata.
  • BusyResult.Error – Impossibile inviare il segnale di occupato o terminare la chiamata.

Throws

  • OperationCanceledException – Se ct viene cancellato.

Signature

Task<BusyResult> Busy(CancellationToken ct = default);

Example

protected override async Task HandleCallAsync(CancellationToken ct)
{
    if (AllAgentsBusy())
    {
        var result = await Busy(ct);
        Logger.LogInformation("Risultato occupato: {Result}", result);
        return;
    }

    // Altrimenti, procedi con il flusso normale
    Answer();
    await Play("welcome.wav", ct);
}

Avvia lo streaming dell'audio live della chiamata verso un endpoint esterno (es. IA o motore STT).

Description

  • Apre un flusso multimediale in tempo reale dalla chiamata all’url dato (es. endpoint WebSocket).
  • Tipicamente usato per inviare audio a:
    • un assistente IA,
    • un motore speech-to-text,
    • un servizio di analisi/monitoraggio personalizzato.
  • È raccomandato un solo flusso attivo per chiamata.

Parameters

  • url – Endpoint di streaming di destinazione (es. wss://ai.callfactory.nl/voice-stream).
  • options – Configurazione di streaming opzionale (direzione, metadati, nome).
  • ct – Token di cancellazione. Se cancellato, il flusso viene interrotto.

Throws

  • OperationCanceledException – Se ct cancellato durante la configurazione.
  • Eccezioni di connessione/trasporto a seconda dell’implementazione.

Firme

Task<StreamResult> StartStream(
    string url,
    StreamOptions? options = null,
    CancellationToken ct = default
);

Parametri

public class StreamOptions
{
    public string? Name { get; set; }                           //
Nome flusso opzionale
    public StreamDirection Direction { get; set; } =
        StreamDirection.Both;
    public Dictionary<string, string>? Metadata { get; set; }
}

public enum StreamDirection
{
    Inbound,   // Dal chiamante all'IA
    Outbound,  // Dall'agente/sistema all'IA
    Both       // Entrambi
}

Ritorni

public enum StreamResult
{
    Started,        // Flusso avviato con successo
    Stopped,        // Flusso fermato con successo (per
StopStream)
    AlreadyStarted, // Un flusso è già attivo
    NotActive,      // Nessun flusso attivo (per StopStream)
    Error           // Avvio/arresto fallito
}

Example

protected override async Task
HandleCallAsync(CancellationToken ct)
{
    Answer();

    // Avvia lo streaming dell'audio del chiamante all'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("Impossibile avviare il flusso IA:
{Result}", streamResult);
        await Play("ai_unavailable.wav", ct);
        await Hangup(ct);
        return;
    }

    await Play("connected_to_ai.wav", ct);

    // Continua la logica IVR mentre lo streaming è attivo...
    var (menuResult, digit) = await
PromptDigit("ai_menu.wav", 30, ct);

    if (menuResult == MenuResult.Success && digit == '0')
    {
        // Il chiamante vuole un agente umano
        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);
    }
}

Ferma un flusso audio attivo che è stato precedentemente avviato con StartStream.

Description

  • Chiude in modo pulito il flusso multimediale attivo.
  • Non riaggancia la chiamata - smette solo di inviare audio.
  • Sicuro da chiamare anche se nessun flusso è attivo (restituisce NotActive).

Parameters

  • ct – Token di cancellazione.

Returns

  • StreamResult.Stopped – Flusso fermato con successo.
  • StreamResult.NotActive – Nessun flusso attivo trovato.
  • StreamResult.Error – Impossibile fermare il flusso.

Throws

  • OperationCanceledException – Se ct viene cancellato.

Signatures

Task<StreamResult> StopStream(
    CancellationToken ct = default);

Example

private async Task TransferToHuman(CancellationToken ct)
{
    // Ferma lo streaming IA prima di trasferire all'umano
    var stopResult = await StopStream(ct);
    Logger.LogInformation("Risultato 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);
    }
}

Perché è importante

Il toolkit IVR offre al tuo team il controllo completo sui flussi di chiamata. Dai menu semplici alle interazioni complesse guidate dall’IA - tutto è possibile con la nostra libreria di azioni.

Questi strumenti sono particolarmente utili per i team che costruiscono soluzioni telefoniche personalizzate, implementano integrazioni IA o estendono i sistemi esistenti con logiche di chiamata avanzate.

Questa funzione è inclusa gratuitamente in ogni numero aziendale o numero internazionale.

Scopri di più su altre funzionalità

Trova maggiori informazioni sulle nostre funzionalità che possono potenziare le comunicazioni della tua azienda.

FAQ Toolkit IVR

Ottieni risposte chiare sul toolkit IVR e su come funziona per la tua azienda.

Puoi creare flussi usando le nostre azioni IVR nella tua dashboard. Ogni azione include esempi, firme e comportamenti prevedibili, così puoi implementare logiche senza bisogno di nuovo hardware telefonico.

Puoi creare flussi semplici senza programmare, ma il toolkit è costruito per i team che vogliono automatizzare o integrare logiche. Gli sviluppatori possono usare azioni strutturate per attivare messaggi, catturare cifre o connettere chiamanti programmaticamente.

Sì. Puoi attivare chiamate API, inviare dati al tuo back-end o trasmettere audio a servizi di IA o STT. Il toolkit si adatta naturalmente alla tua infrastruttura esistente.

Assolutamente. Non hai bisogno di cambiare la tua configurazione. Tutte le azioni IVR funzionano con i tuoi numeri Callfactory esistenti, il routing e le impostazioni di chiamata.

Sì. Puoi costruire e visualizzare in anteprima i tuoi flussi in sicurezza. Il toolkit ti permette di simulare messaggi, raccolta di input e comportamenti di routing prima di attivare le modifiche per i chiamanti reali.

Tu decidi il comportamento. Puoi riprodurre nuovamente un messaggio, indirizzare alla segreteria, connettere al supporto o terminare la chiamata. Ogni azione IVR supporta la gestione degli errori personalizzata.

Sì. Ogni azione include la gestione dei timeout e una logica di fallback opzionale. Puoi definire cosa succede quando non viene ricevuto alcun input o quando un chiamante riaggancia.

Sì. Il toolkit è stato progettato per concatenare le azioni. Puoi riprodurre audio, raccogliere cifre, eseguire logiche, chiamare un’API e trasferire chiamanti - tutto in un unico flusso.

Sì. Il sistema è progettato per affidabilità e scalabilità. Che tu gestisca una piccola impresa o un call center ad alto volume, tutte le azioni offrono prestazioni prevedibili.

Se il tuo team ha bisogno di guida, possiamo aiutare a revisionare il design del tuo flusso, testare la tua configurazione o supportare logiche di routing più avanzate.

Clienti soddisfatti di Callfactory:

SignDirect logo
Bosch logo
Trigion logo
ANWB logo
UWV logo
Sogeti logo
Dille & Kamille logo
Nationale Ombudsman logo
KRO-NCRV logo
Swiss Sense logo