Creating an Outbound Dialer with the 3CX CFD

Introduction

This guide describes how to create an automatic dialer application using the 3CX Call Flow Designer. Using dialers you can automatically make outbound calls and connect them to internal extensions (e.g. queues or agents extensions), so your staff does not waste valuable time dialing, improving productivity.

💡 Tip: The project for this example application is available via the CFD Demos GitHub page, and is installed along with the 3CX Call Flow Designer in your Windows user documents folder, i.e. “C:\Users\YourUsername\Documents\3CX Call Flow Designer Demos”.

It is important to note that Dialers start working when the Call Flow app receives the first call, and continue working indefinitely until the 3CX Call Flow Server service is stopped. Therefore, you need to use “Create a Condition” components to decide if it is the right time to make calls. For example, you can check the time of the day, if today is a holiday or a weekend day and depending on that you can decide to make calls or not. Without this logic, the dialer starts making calls as soon as it starts, and does not stop until you stop the 3CX Call Flow Server service.

The list of numbers to call can be anywhere, for example in a text file, in a database, and so on. In this example we use numbers from a text file. We also show how to restrict outbound calls to a specific time frame for Monday to Friday, and finally how to make outbound calls only when an agent is available.

Step 1: Create the Project

First, we need to create a new project:

  1. Open the CFD and go to “File” > “New” > “Project”, select the folder where you want to save it, and enter a name for the project, e.g. OutboundDialerDemo.
  2. The project includes a callflow named “Main.flow” by default. We do not use this callflow, so you can delete it.
  3. Then add a new “Dialer” to the project, by going to the “Project Explorer” panel, right-click on the project name and select New Dialer.
  4. Set the name to MainDialer and select the new dialer object in the “Project Explorer” to  show its properties in the “Properties” panel.

You can customize the behavior of “Power Dialers” using these properties:

  • “ParallelDialers”: number of simultaneous dialer instances to be launched.
  • “PauseBetweenDialerExecution”: delay in seconds between flow executions for each instance.

To explain this using a simple example, if we set “ParallelDialers” to 3 and “PauseBetweenDialerExecution” to 30 seconds, the outcome is this:

  1. A first dialer instance is created, gets the number to call and makes the first call. Then it waits for 30 seconds.
  2. After 10 seconds, a second dialer instance is created, gets the number to call and makes the second call. Then this instance waits for 30 seconds.
  3. After 10 seconds, a third dialer instance is created, gets the number to call and makes the third call. Then this instance waits for 30 seconds.
  4. After another 10 seconds, the first instance wakes up from waiting for 30 seconds, and makes another call.
  5. After another 10 seconds, the second instance wakes up from waiting for 30 seconds, and makes another call.
  6. Etc.

This iteration continues until the 3CX Call Flow Server service is stopped, even if the app is deleted or replaced by a new version. So, always restart the 3CX Call Flow Server service when you delete a dialer or update it with a new version.

As a consequence, using these 2 properties we control the call-through rate. Setting “ParallelDialers” to 3, and “PauseBetweenDialerExecution” to 30 seconds, the app makes 6 calls per minute. If we need more or less, we can increase or decrease these values.

Step 2: Check Time to Make Calls

For this demo, we want that our dialer makes calls only from Monday to Friday, between 9:00 and 17:00. To accomplish this, we need to determine first if the current time is in that time range, using the Execute C# Code component and then use a Create a Condition component to decide what to do depending on the result:

  1. First, drag an Execute C# Code component from the toolbox, drop it into the designer and set the name to timeChecker.

Execute C# Code component configuration in 3CX CFD

  1. Use this C# code:

return ((int)DateTime.Now.DayOfWeek) > 0 && ((int)DateTime.Now.DayOfWeek) < 6 && DateTime.Now.Hour >= 9 && DateTime.Now.Hour < 17;

  1. Next, drag the Create a Condition component from the toolbox, drop it into the designer and set its name to checkTimeToCall.
  1. Configure the Create a Condition component’s branches as:
  1. timeToCall: executed when it is time to make a call,
  2. nothingToDo: when it is out of that time frame.
  1. For the timeToCall branch, set its “Condition” property to this expression, using the result of the Execute C# Code component we added previously:

timeChecker.ReturnValue

Step 3: Check Agent Availability to Take Calls

The dialer that we are creating makes outbound calls to numbers from a text file, and then connects these calls to an internal extension. The internal extension is a 3CX queue with some agents assigned, e.g. queue extension number 800 with agent extensions 201, 202 and 203. We want to check if any of these extensions is free to receive a call, using the 3CX Call Control API from an Execute C# File component.

  1. Use the C# code below for the script we need to invoke to check if there are free extensions to handle our calls. The code is pretty simple, as it gets the DN object for each extension and checks if they have any ActiveConnection attached. Save this C# code in a file named “CheckExtensionsState.cs” in the project’s “Libraries” folder:

using System;

using TCX.Configuration;

public class ExtensionStateHelper

{

    public bool IsThereAnyFreeExtension()

    {

      return PhoneSystem.Root.GetDNByNumber("201").GetActiveConnections().Length == 0 ||

             PhoneSystem.Root.GetDNByNumber("202").GetActiveConnections().Length == 0 ||

             PhoneSystem.Root.GetDNByNumber("203").GetActiveConnections().Length == 0;

    }

}

Execute C# File component configuration in 3CX CFD

  1. Then, drag an Execute C# File component from the toolbox to the designer, inside the timeToCall branch and name it as checkFreeExtensions. Configure it as in the example above, using the “CheckExtensionsState.cs” C# code saved previously.

Example callflow in 3CX CFD

  1. Now, we need to check the result of this script, using another Create a Condition component, just underneath the “checkFreeExtensions” component. Use isThereAnyFreeExtension for the name, and add 2 branches to it: yesMakeCall and noFreeExtensions, as in the example callflow above.
  2. Finally, set the “Condition” property for the branch yesMakeCall to be met when the previous script returned true, i.e.:

checkFreeExtensions.ReturnValue

At this point, when the branch yesMakeCall is executed, all our validations are satisfied, in the appropriate time frame, and there is at least one free extension, so we can proceed to make the call.

Step 4: Get the Number to Call from Text File and Call

For this example, we get the numbers to call from a text file, e.g. “NumbersToCall.txt”, containing a number in each line, with these steps:

  1. To get the number to call, we need an index variable, to select the line to read from the text file, which we need to share between all the parallel dialers. This way, when we increment the index, the following dialer instance uses the incremented index, and so on. To do this, we need to create a static variable defined in a new “CallIndexHolder.cs” C# script in the project “Libraries” folder, using this code:

using System;

public class CallIndexHolder

{

    private static int callIndex = 0;

   

    public int GetCallIndex()

    {

      return callIndex;

    }

   

    public void SetCallIndex(int index)

    {

      callIndex = index;

    }

}

📄 Note: The variable “callIndex” is declared as static, i.e. only one instance of this variable exists in the entire 3CX Call Flow Server service process, shared between all the dialer instances.

Execute C# File component configuration in 3CX CFD

  1. Now we need to use an Execute C# File component to get the “CallIndex” variable. Place it inside the branch yesMakeCall, name it getCallIndex and configure it as in the example above.

Read / Write to File component configuration in 3CX CFD

  1. Then we need to read the number to call from the text file: Add a new Read / Write to File component, just below the getCallIndex component, name it readNumberToCall, and configure it as in the above example.

Note: You need to adjust the specified path to the file containing the numbers to call to a path on your 3CX server.

  1. The index may go beyond the number of lines in the text file, i.e. the component readNumberToCall reads an empty string. To check if this is the case or not before making the call, we need to add another Create a Condition component to verify this case, with a single branch to check if there is a number available. Set the “Condition” property to:

GREAT_THAN(LEN(readNumberToCall.Result),0)

Make Call component configuration in 3CX CFD.

  1. When that condition is met, we have a number to call. In that case, we increment the CallIndex, using another Execute C# File” component. Finally, make the call using a Make Call component configured as in the above example.

Using this configuration, we can make a call from the number retrieved from the text file to the example queue extension 800, having agents 201, 202 and 203. The external number is set as the originator of the call, so 3CX calls that number first, and only when the call is connected, 3CX calls the queue and binds both parties.

Example callflow in 3CX CFD

Consider the example call flow above for the yesMakeCall branch with all the components added.

Step 5: Build and Deploy to 3CX Phone System

The project is ready to build and upload to our 3CX Phone System server, with these steps:

  1. Select “Build” > “Build All” and the CFD generates the file  “OutboundDialerDemo.zip”.
  2. Go to the “3CX Management Console” > “Advanced” > “Call Flow Apps” > “Add/Update”, and upload the file created by the CFD in the previous step.
  3. The dialer is ready to start making calls as soon as the Call Flow app receives a call.

💡 Tip: When you delete a dialer or update it with a new version, always restart the 3CX Call Flow Server service. The dialer continues running until the 3CX Call Flow Server service is stopped, even if the app is deleted or replaced by a new version.

See Also

Last Updated
This document was last updated on 29th April 2021
https://www.3cx.com/docs/cfd-creating-outbound-dialer/