cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
2105
Views
15
Helpful
4
Replies

UCCX Geographic Inbound call routing by query xml file

gracemaximuangu
Level 1
Level 1

Hi all,

I have a customer requirement, when a call is placed into the call center, the script needs to query an xml file using Xpath (they do not want to do a database lookup at this time)  to determine what CSQ to place the call in.

I found a similar posting in the forum https://supportforums.cisco.com/thread/206170

but the thread ended at the proposals and not detailed explanation as to how they added the logic into the call flow.

Has anyone done this before?

Or does anyone have a sample code that can be modified to satisfy this requirement?

1 Accepted Solution

Accepted Solutions

Anthony Holloway
Cisco Employee
Cisco Employee

I answered your question over on the cisco-voip mailing list, so I'll post here for those folks looking at your question.

Grace, this is how you pull an area code from the calling number.

ani = Get Call Contact Info (Calling Number)

Set area_code = ani.substring(0, 3)

And now at this point, one could use the XML file approach as Chase has pointed out.

Midwest_CSQ

East_CSQ

Of course that can be a large file considering there are almost 300 area codes in use today, and that number is growing towards its current maximum potential of 800 numbers.  In an effort to shrink that document, you could compress the data yourself like this:

01

We're just using single characters to represent the tag names, and numeric values for the CSQ names.  You will need a String Array to convert the digit value of the CSQ into the actual CSQ like this:

Variable

String[] csq_map = new String[] {"Midwest_CSQ", "East_CSQ"}

Script

result = Get XML Document Data(xml_doc, "//[@c='" + ani + "']")

Set csq = csq_map[Integer.parseInt(result)]

If you haven't worked with String Arrays yet, just know that each element in the array has an associated value, or index, and it starts with 0 on the left, and goes up incrementally from there to the right.  So in the above example, Midwest_CSQ is 0 and East_CSQ is 1.

At this point, your csq variable holds the name of the CSQ, and you saved yourself some amount of JVM heap usage.  The reason this saves space is because if you have 150 area codes for which CSQ NorthCentralSupport_CSQ (a 23 character name) serves, then without the trick you need at least 150 * length of CSQ Name, which is 3.4KB.  With the trick I used, you get the text alone down to 150Bytes (the character "0" used 150 times).  That's a 96% decrease.  Now, the String Array doesn't come for free, and there is a formula to figure it out, but I'd wager you're fine doing without the compression at all, therefore compression is just icing on the cake.  Just use RTMT perfmon counters to watch your JVM heap usage.

You could alternatively use a java switch block and keep all dependencies right inside the script, but I don't know if the XML functionality is a requirement for you or not.

Example:

Do {

  switch (area_code) {

    case "612": case "763": case "651":

      csq = "Midwest_CSQ";

      break;

    case "305": case "786":

      csq = "East_CSQ";

      break;

   default:

     csq = "Default_CSQ";

  }

}

This has the advantage of not having to assign the csq variable for each area code in the US, rather you do it for blocks of csq's rather easily, as I have demonstrated.  If you needed this to be available to a few other scripts, consider making it a sub flow which takes 1 input mapping of the ani, and provides 1 output mapping of the mapped csq name like so:

area_code_lookup.aef

Variables

String csq = ""

String ani = ""

Script

Start

On Exception (WFExecutionException) Goto End of Script

Do {

  switch (ani.substring(0, 3)) {

    case "612": case "763": case "651":

      csq = "Midwest_CSQ":

      break;

    case "305": case "786":

      csq = "East_CSQ";

      break;

  }

}

End of Script:

End

main_aa.aef

Variables

String csq = ""

String ani = ""

Script

Start

Accept(--Triggering Contact--)

ani = Get Call Contact Info (Calling Number)

csq = Call Subflow (SCRIPT[area_code_lookup.aef], Input: ani, Output: csq)

Set csq (csq == null || csq.trim() == "") ? "Default_CSQ" : csq

Select Resource (--Triggering Contact-- from csq)

  Connected

    End

  Queued

    ...queue logic...

End

There's many different ways to solve for this requirement.  Which one you pick should meet the objective first, and then be easy to troubleshoot and administer second.  The rest is subjective.  In my opinion...of course!  Haha.

Good luck.

Anthony Holloway

Please use the star ratings to help drive great content to the top of searches.

View solution in original post

4 Replies 4

Anthony Holloway
Cisco Employee
Cisco Employee

I answered your question over on the cisco-voip mailing list, so I'll post here for those folks looking at your question.

Grace, this is how you pull an area code from the calling number.

ani = Get Call Contact Info (Calling Number)

Set area_code = ani.substring(0, 3)

And now at this point, one could use the XML file approach as Chase has pointed out.

Midwest_CSQ

East_CSQ

Of course that can be a large file considering there are almost 300 area codes in use today, and that number is growing towards its current maximum potential of 800 numbers.  In an effort to shrink that document, you could compress the data yourself like this:

01

We're just using single characters to represent the tag names, and numeric values for the CSQ names.  You will need a String Array to convert the digit value of the CSQ into the actual CSQ like this:

Variable

String[] csq_map = new String[] {"Midwest_CSQ", "East_CSQ"}

Script

result = Get XML Document Data(xml_doc, "//[@c='" + ani + "']")

Set csq = csq_map[Integer.parseInt(result)]

If you haven't worked with String Arrays yet, just know that each element in the array has an associated value, or index, and it starts with 0 on the left, and goes up incrementally from there to the right.  So in the above example, Midwest_CSQ is 0 and East_CSQ is 1.

At this point, your csq variable holds the name of the CSQ, and you saved yourself some amount of JVM heap usage.  The reason this saves space is because if you have 150 area codes for which CSQ NorthCentralSupport_CSQ (a 23 character name) serves, then without the trick you need at least 150 * length of CSQ Name, which is 3.4KB.  With the trick I used, you get the text alone down to 150Bytes (the character "0" used 150 times).  That's a 96% decrease.  Now, the String Array doesn't come for free, and there is a formula to figure it out, but I'd wager you're fine doing without the compression at all, therefore compression is just icing on the cake.  Just use RTMT perfmon counters to watch your JVM heap usage.

You could alternatively use a java switch block and keep all dependencies right inside the script, but I don't know if the XML functionality is a requirement for you or not.

Example:

Do {

  switch (area_code) {

    case "612": case "763": case "651":

      csq = "Midwest_CSQ";

      break;

    case "305": case "786":

      csq = "East_CSQ";

      break;

   default:

     csq = "Default_CSQ";

  }

}

This has the advantage of not having to assign the csq variable for each area code in the US, rather you do it for blocks of csq's rather easily, as I have demonstrated.  If you needed this to be available to a few other scripts, consider making it a sub flow which takes 1 input mapping of the ani, and provides 1 output mapping of the mapped csq name like so:

area_code_lookup.aef

Variables

String csq = ""

String ani = ""

Script

Start

On Exception (WFExecutionException) Goto End of Script

Do {

  switch (ani.substring(0, 3)) {

    case "612": case "763": case "651":

      csq = "Midwest_CSQ":

      break;

    case "305": case "786":

      csq = "East_CSQ";

      break;

  }

}

End of Script:

End

main_aa.aef

Variables

String csq = ""

String ani = ""

Script

Start

Accept(--Triggering Contact--)

ani = Get Call Contact Info (Calling Number)

csq = Call Subflow (SCRIPT[area_code_lookup.aef], Input: ani, Output: csq)

Set csq (csq == null || csq.trim() == "") ? "Default_CSQ" : csq

Select Resource (--Triggering Contact-- from csq)

  Connected

    End

  Queued

    ...queue logic...

End

There's many different ways to solve for this requirement.  Which one you pick should meet the objective first, and then be easy to troubleshoot and administer second.  The rest is subjective.  In my opinion...of course!  Haha.

Good luck.

Anthony Holloway

Please use the star ratings to help drive great content to the top of searches.

The Solution was implemented without a hitch.

Thank, Thank you and Thank you.

Hello Gracemaximuangu,

        Question for you. I am about to implement the same solution and i was wondering if you mind sharing what you did (XML file and CCX Script).

Hi Anthony,

Need your inputs ,I have similar requirement but instead of Area codes , I need to route calls based on Caller input in a variable. Caller input is for a model they use. A group of model codes can be routed to a CSQ. Is it possible to follow the above steps and what can be changed.

If you have an example script will help

 

Thank You much