Thursday, April 16, 2026

Webex Contact Center Flow Designer Functions: Simplifying Complex Call Routing and Flow Logic

Cisco demonstrated a similar pattern at Cisco Live Amsterdam 2026 in the session “Boosting Customer Experience with Flow Orchestration in Webex Contact Center” (BRKCCT-2345). This post is written in the spirit of that demo and expands on the same core idea: when routing logic starts to sprawl across the canvas, a Function can make the flow cleaner, easier to read, and easier to maintain.

In Webex Contact Center, Flow Designer is built to route real-time calls through a sequence of activities and events. Cisco also provides Functions as a reusable component that can be created in Control Hub or Flow Designer added to multiple main flows, and used to return a JSON result that the flow can parse with JSONPath into flow variables. Functions currently support JavaScript on Node.js 22.x and Python 3.13.

That combination is useful because many voice flows start simple and then become hard to maintain. At first, everything looks clean: answer the call, play a welcome prompt, check business hours, and send the caller to a queue. But the moment you start adding country logic, language handling, brand-specific routing, or queue selection by DNIS, the visual flow can grow very quickly.

A common example is inbound routing based on the number the customer dialed. Imagine a support line where calls arrive on DNIS with these prefixes (let's say we have multiple DNs in different countries):

  • +1 for North America
  • +421 for Slovakia
  • +33 for France
  • +49 for Germany
  • +34 for Spain
  • +39 for Italy

You can absolutely build that logic directly in the main flow. One branch checks whether the DNIS starts with 421, another checks 33, another checks 49, and so on. After each condition, you set the country, choose the target queue, and continue the call treatment.

That works, but only for a while.

The problem is not whether the logic is valid. The problem is readability. Once the flow contains several repeated conditions, multiple Set Variable activities, and several queue decisions, the visual canvas stops telling a clear story. It still works, but it becomes harder to explain, harder to review, and harder to update.

This is where a Function becomes a much better fit.

Instead of spreading the country-routing logic across the main flow, you move it into one small function. The flow passes DNIS into the function, the function resolves the destination, and the flow receives a simple output such as:

{
"Country": "Germany",
"queueName": "Support_DE"
}

From there, the main flow remains focused on orchestration:

  1. Accept the call
  2. Pass DNIS into the function
  3. Read the returned country and queue
  4. Play the right prompt if needed
  5. Queue the contact

That is a cleaner separation of responsibilities. The flow handles call progression. The function handles decision logic.

A Practical Example

For a blog-friendly example, the function can do something very simple: look at the normalized DNIS prefix and return the target country and support queue.

If the number starts with 421, return Slovakia and Support_SK.
If it starts with 33, return France and Support_FR.
If it starts with 49, return Germany and Support_DE.
If it starts with 34, return Spain and Support_ES.
If it starts with 39, return Italy and Support_IT.
If it starts with 1, return North America and Support_NA.
If nothing matches, return Unknown and a default queue.

This is not about “writing code instead of using the UI.” It is about putting repeated logic in the right place.

So, let's create our function first for this Demo. We will create the function via the Flow Designer, but it is possible to do it via the Control Hub as well. Start a new flow (or open an existing flow of course), click Functions in the Palette and then click Create Functions:


Select Start from Scratch, then enter a name for the function and choose the code language.



Then in the function configuration window provide the JS code of your function and its description. Feel free to use AI like ChatGPT to write the JS code if you are not able to do it yourself. 


For our example the JS code is as follows:

export const handle = async (request, response) => {
  // Expected function input:
  // DNIS (String)

  const rawDnis = String(request.inputs.DNIS ?? "").trim();

  // Normalize DNIS to digits only
  const normalizedDnis = rawDnis.replace(/\D/g, "");

  let result = {
    Country: "Unknown",
    queoueName: "Support_Default"
  };

  if (normalizedDnis.startsWith("421")) {
    result = {
      Country: "Slovakia",
      queoueName: "Support_SK"
    };
  } else if (normalizedDnis.startsWith("33")) {
    result = {
      Country: "France",
      queoueName: "Support_FR"
    };
  } else if (normalizedDnis.startsWith("49")) {
    result = {
      Country: "Germany",
      queoueName: "Support_DE"
    };
  } else if (normalizedDnis.startsWith("34")) {
    result = {
      Country: "Spain",
      queoueName: "Support_ES"
    };
  } else if (normalizedDnis.startsWith("39")) {
    result = {
      Country: "Italy",
      queoueName: "Support_IT"
    };
  } else if (normalizedDnis.startsWith("1")) {
    result = {
      Country: "North America",
      queoueName: "Support_NA"
    };
  }

  response.data = result;
  return response;
};

Also we need to create the function input variable. For our code, we need exactly one variable:

Name: DNIS
Type: String

Why we should do this: the code uses request.inputs.DNIS, so the variable name in the function settings must be exactly DNIS, with the same letter case.


Then we need to provide an example of the JSON structure that your function returns in response.data. In Cisco documentation, this field is called Output Variable Definition and is used to show flow developers what output data the function returns. In Webex Contact Center, a function returns a single JSON output, and the individual fields are then parsed in the main flow using JSONPath.

For our current code, let's insert this:

{Country: "North America", queueName: "Support_NA"}

That is enough. We do not need to create separate output variables here.


Finally, we can test the execution of our function. Here is a Test Panel for the function. Let's enter one of our DNIS there and see the result of the function. Once tested, don't forget to Publish the function. 


Now our function appears in the Palette:


Here is a sample flow which demonstrates the operation of our function. 


In the Function activity we have to map our Inbound DNIS variable to the Function input variable DNIS to pass the called number from the flow to the function:

Next, map the function output variables from its JSON to the flow variables:


The name of the Queue is set dynamically to the value of the queueName variable:


Let’s test it by making a call to our North America number and confirming that it is routed to the Support_NA queue. We can verify this easily in the flow debug view.


Why This Design Works Better

The first benefit is clarity.

A main flow should be easy to read even for someone opening it for the first time. If the canvas is filled with repetitive country checks, it becomes harder to understand the actual customer journey. A single function keeps that logic out of the visual path and makes the main flow easier to follow.

The second benefit is maintainability.

If routing changes tomorrow, you update one function instead of several scattered branches. Cisco’s documentation also notes that published functions are available to the organization and can be added across multiple main flows, which makes this approach especially useful when the same routing logic is reused in more than one call scenario.

The third benefit is consistency.

When the same country-routing logic is reused everywhere, you reduce the chance that one flow sends France to one queue while another flow sends it somewhere else. Centralizing that decision in a function gives you one place to review and one place to change.

Final Thought

Visual flows are excellent for showing the path of a call. Functions are excellent for compact decision-making. When a routing rule starts turning your flow into a long sequence of repetitive branches, that is usually the signal that the logic belongs in a function instead.

So the point is not that code is somehow better than the UI. The point is simpler: use the UI for orchestration, and use a function for repeated logic. In Webex Contact Center, that design is often the difference between a flow that merely works and a flow that is still easy to understand six months later.

No comments:

Post a Comment