05-08-2017 12:58 PM - edited 03-14-2019 05:17 PM
Hi experts,
UCCX - Version 8.5 thru 11.5 Premium
I've seen a thread or 2 in the forums where this has been asked. In my particular scenario, we bring the call inbound into one of our Applications for call treatment. If the callers presses a particular option, we will do a redirect out to the PSTN.
The question is, how can I do a redirect to multiple numbers when calling out to the PSTN?
I have accomplished this in the past by using variables, IF/Then statements and writing 0s and 1s to an external DB. Doing a 50/50 split and even a 33.33333 percent split has worked using this method. However, that ends up becoming a large amount of DB reads and DB writes. Now the need may be even more granular to distribute %20 of calls to 1 PSTN number and the rest to the other.
So is there any other way with the UCCX script to accomplish this task? Something maybe more efficient?
Thanks
Joey
Solved! Go to Solution.
06-09-2017 08:24 AM
The only piece is seems like you are wanting to address is the DB read/write and the efficiency of that, correct?
Do you have any ill effects from these transactions today? If not, maybe there is nothing to be concerned about?
Otherwise, if you wanted to offload the data handling from the external DB and keep in 100% on UCCX, then you're looking at the Document repository for long term, non-volatile data storage. Or, if you're ok with the opposite of that, you could use a global session object that all script can access and read/write to.
I'm not sure how to measure the performance impact of such processes, but the implementation with using the Document repository should be trivial.
Example pseudo code using repo:
Set vendors = doc[vendors.txt] // Format <vendor1 call volume>,<vendor2 call volume>
Set vendor1 = (int) vendors.split(",")[0]
Set vendor2 = (int) vendors.split(",")[1]
Set total = vendor1 + vendor2
If (total == 0 || vendor1 / total < .8)
True
Set target = "+16125551212"
Increment vendor1
False
Set target = "+16125551313"
Increment vendor2
Upload Document (vendor1 + "," + vendor2, vendors.txt, overwrite)
Call Redirect (target)
The global session would really only work if you could guarantee a steady flow of calls throughout the day. If there was ever a break in phone calls longer than the Session timeout duration (default 30 minutes), then the Session data would be garbage collected and you'd start over.
05-16-2017 02:32 PM
Hmmm, yeah I see. Your old method sounds like overkill. There's no need for a database.
Generally speaking, CUCM handles call routingn If you want a particular number/pattern to route through one PRI, you would accomplish this by configuring your Dial Plan (and/or Global Dial Plan), Gateways, Trunks and so on. Most likely, your CUCM already has Route Patterns identifying a range of area codes, for example;
1.555[2-9]XXXXXX
1.666[2-9]XXXXXX
1.777[2-9]XXXXXX
Route Patterns (RP) contain Route Lists (RL) and Route Groups (RG). RL contains a list of RG. Within the RG, you define the Distribution Algorithm (i.e. Top Down or Circular)... then you add a couple of Devices (i.e. Gateways, SIP Trunks, etc.) to the RG. Remember, the Devices are listed by priority; top down.
If I understand your request, you can create a very specific Route Patterns, like;
1.5551234567
1.6667654321
That way, when someone selects Option #1... UCCX transfers the call to CUCM via 'Call Redirect' step. Next, CUCM matches the Destination Number with the RP. The Route Partition and RL/RG assigned to that RP is pre-defined by you... this ultimately determines the path of the call.
You can create numerous RP, RL, RG, Route Partitions, DN Partitions and Calling Search Spaces to influence call routing. If you have a list of frequently called numbers used by the helpdesk, then you could create a RP for each number and change the priority of the outgoing PRIs.
To address your question about redirecting to multiple numbers... you can simply use the 'Call Consult Transfer' step. Unlike the 'Call Redirect' step... the 'Call Consult Transfer' step allows you to send digits. The 'Call Consult Transfer' step is considered a warm transfer, whereas 'Call Redirect' would be a cold transfer.
Under the [Unsuccessful] branch of the 'Call Consult Transfer' step, you can 1) add another 'Call Consult Transfer' step or 2) you can change/set a couple of variables like the Destination Number referenced by the 'Call Consult Transfer' step. Then, add a new (int) variable to count the number of attempts, for example; ctLoop. With each attempt, you would increment the ctLoop counter. Under the same [Unsuccessful] branch... you can add a simple IF statement like;
ctLoop >= 1
If FLASE, you would change or set the variable and try again.
If TRUE, you would try something else or hang up.
If you wanna reference more than 2 numbers, then you should use the SWITCH statement along with the loop counter.
Good Luck!!!
05-18-2017 05:53 AM
Mark,
Hi there, thanks for the detailed response. Currently we utilize SIP trunks with our cluster for Inbound, Inbound Toll Free and Outbound. These are split between 4 circuits with 2 being for redundancy. So utilizing Route Lists, Route Patterns, etc will still route the call out the same trunk not really buying us any additional call routing at that point from the Call Manager.
As for the UCCX piece these need to be cold transfers as we are handing the call off to another company.
For example, we receive the inbound toll free call into our UCCX environment. If a caller chooses support, the call will be routed to an agent etc. However if the caller presses options for sales, we send that call externally to another vendor. These calls should always hit the successful branch of the Call Redirect step.
Right now we are looking to achieve %20 of the call volume to 1 number and %80 to the other.
Call 1 > Inbound to UCCX > Caller Presses Options for Sales > Call sent outbound to Ext Num 1
Call 2 > Inbound to UCCX > Caller Presses Options for Sales > Call sent outbound to Ext Num 2
Call 3 > Inbound to UCCX > Caller Presses Options for Sales > Call sent outbound to Ext Num 1
Call 4 > Inbound to UCCX > Caller Presses Options for Sales > Call sent outbound to Ext Num 1
Call 5 > Inbound to UCCX > Caller Presses Options for Sales > Call sent outbound to Ext Num 1
Call 6 > Inbound to UCCX > Caller Presses Options for Sales > Call sent outbound to Ext Num 1
Call 7 > Inbound to UCCX > Caller Presses Options for Sales > Call sent outbound to Ext Num 2
Call 8 > Inbound to UCCX > Caller Presses Options for Sales > Call sent outbound to Ext Num 1
Call 9 > Inbound to UCCX > Caller Presses Options for Sales > Call sent outbound to Ext Num 1
Call 10 > Inbound to UCCX > Caller Presses Options for Sales > Call sent outbound to Ext Num 1
So I am not sure if that can be accomplished in CUCM, but can be done in UCCX utilizing variables with IF/Then statements and changing those values with each call.
05-19-2017 02:03 PM
Okay. Just remember, with scripting/programming there's likely 1/2 dozen ways to accomplish the same task. With that said, I would suggest the following...
Create THREE variables (at least);
Type Name
Session SessionID
Long longSessionID
String strSessionID
Drag and drop the 'Get Contact Info' step after the 'Accept' step. Within the 'Get Contact Info' step, under the Session attribute... select the variable we just created; SessionID. Click 'Apply' and 'Ok' to exit this step.
Next, drag and drop the 'Get Session Info' step after the 'Get Contact Info' step. Within this step, we declare the Session as SessionID. Under the Attributes, we will use the longSessionID variable to collect the Session Identifier from the call event.
And finally, we will convert the value within the longSessionID variable into a string by placing a very simple Set statement after the 'Get Session Info' step, like so;
Set strSessionID = String.valueOf(longSessionID)
Then, we can strip away the "useless" SessionID numbers. We can reuse (i.e. copy) the same Set step above and paste the Set step just below. Then change the value to;
Set strSessionID = strSessionID.substring(11)
The end results should be a single digit. What can you do with that, you say?
Well, the ACD system assigns a unique Session ID Number to all calls; inbound and outbound, including private calls. That's assuming the agent's personal DN is the IPCC Extension as well.
Placing an IF Statement after the steps listed above would analyze the LAST number within the SessionID, for example;
IF (strSessionID == "0" || strSessionID == "5")
TRUE ---> Go this way...
FALSE ---> Go that way...
Likewise, you could simply do this;
IF (strSessionID <= "2")
And that way, if the value was 0... or 1... or 2... then calls would be routed one-way. All other calls would be routed the other way. Another option would be a Switch Statement, using the same principles.
I don't believe this solution is going to route calls -exactly- the way you want. The only problem I see is... abandoned calls. Again, all callers are assigned a SessionID, like "120000123456". The caller hangs up and they waste the transfer slot IF you determined "6" was the lucky number.
If you have multiple queues used by other teams, they might be assigned the lucky number. So, yeah... the solution is not 100% solid. My suggestion... perhaps you need to pick 3 numbers; 30% or whatever.
Good Luck.
05-22-2017 12:24 PM
Mark,
Yea, not sure this will work since the numbers generated from the SessionID will always differ. Once you truncate it down to the 1 digit, it will be hard to throw it into an IF Then statement or Switch String to route the call accordingly. Since it will be almost random number generated, the percentages would be random as well.
My method is working just fine, was just curious if other people have implemented this type of call flow scenario and what method they used.
05-22-2017 02:19 PM
Once you convert the SessionID from hexadecimal to decimal, the strSessionID matches the SessionID exactly. I am talking about the SessionID referenced throughout numerous CUIC Reports. The "Detailed Call By Call CCDR Report" contains the following info;
Node ID - Session ID - Sequence Number
=================================
1-555000011223-0
=================
2-555000099887-0
2-555000099887-1
In this example, the first number represents the Node ID... either 1 or 2... primary or secondary. The last number... -0, -1 and so on. Represent the call leg. The fact there's two call events with the same SessionID suggests a Ring-No-Answer event, Call Transfer, etc.
The 12 digit SessionID is unique to each call event; inbound/outbound calls, including any private calls (inbound/outbound) on the IPCC Extension.
I simply suggested using the last digit within the SessionID to accomplish the same task without an external database connection. The only "downside" would be... if you selected SessionIDs ending with "3" and "7" then only inbound ACD calls ending with 3 or 7 would be impacted, or routed differently. If someone placed/received a private call... the private call could be assigned SessionID 1-555000033333-0 and then yes, it would drop below 20%. If you selected 3 numbers, then you would potentially route up to 30% of your calls one-way. You could apply this same concept and harness the last 2 digits of the SessionID but obviously, I would suggest a Switch Statement.
I didn't know how flexible your solution was or could be. That's all. You asked for ideas. I provided a simple alternative solution to what you're doing now, without the external db dependency. I don't know of anyone else doing this type of call distribution, so I doubt anyone is going to respond. UCCX is intended for small to mid-size businesses. When UCCX redirects or transfers callers, most Engineers will let CUCM handle call routing.
05-31-2017 07:45 AM
Mark,
No worries, thanks for your ideas!
06-01-2017 08:46 PM
No problem.
You can always use IF statements... or better yet, Switch statements along with the ANI for call distribution.
This is a pretty good and simple solution if you have a small-to-mid size private organization with a specific dial plan.
However, if you manage a commercial contact center... most likely, you deal with dozens, if not, hundreds of different area codes or country codes. Having a series of IF statements might be ridiculous. In this case, you would use the Doc step to reference an xml file. Maybe csv file too, I don't recall. You would upload and maintain the list of area codes on the UCCX server. Within this Doc, you can specify variables and define parameters based on the calling number (area code). And perhaps, one of those variables could be "pstn broadcast num1".
Good luck.
06-09-2017 06:24 AM
Mark,
Yea, we have multiple applications and scripts where we utilize switch steps to get calls routed by Dialed Number. ANI routing is not something we need or use in our environment.
When callers call 1 of our hundreds of TFNs, most give options to self route to Sales,Support, etc. So this whole process of bouncing the calls back out to an external call center is only if the callers choose Sales. Then based on that decision the call is bounced out to 2 different numbers (2 different call centers) based on percentage that we need to send to each.
06-09-2017 08:24 AM
The only piece is seems like you are wanting to address is the DB read/write and the efficiency of that, correct?
Do you have any ill effects from these transactions today? If not, maybe there is nothing to be concerned about?
Otherwise, if you wanted to offload the data handling from the external DB and keep in 100% on UCCX, then you're looking at the Document repository for long term, non-volatile data storage. Or, if you're ok with the opposite of that, you could use a global session object that all script can access and read/write to.
I'm not sure how to measure the performance impact of such processes, but the implementation with using the Document repository should be trivial.
Example pseudo code using repo:
Set vendors = doc[vendors.txt] // Format <vendor1 call volume>,<vendor2 call volume>
Set vendor1 = (int) vendors.split(",")[0]
Set vendor2 = (int) vendors.split(",")[1]
Set total = vendor1 + vendor2
If (total == 0 || vendor1 / total < .8)
True
Set target = "+16125551212"
Increment vendor1
False
Set target = "+16125551313"
Increment vendor2
Upload Document (vendor1 + "," + vendor2, vendors.txt, overwrite)
Call Redirect (target)
The global session would really only work if you could guarantee a steady flow of calls throughout the day. If there was ever a break in phone calls longer than the Session timeout duration (default 30 minutes), then the Session data would be garbage collected and you'd start over.
06-12-2017 09:59 AM
Hmmm. Yeah, I was trying to recommend a solution that avoided the excessive use of the 'Upload Document' step. Please correct me if I am wrong but I thought there's limitations to the 'Upload Document' step. According to the Cisco Unified CCX Editor Step Reference Guide, they warn about;
Although the repository database is meant to hold documents used by scripts, do not use the Upload Document functionality to store all types of documents. There is no provision for a delete document operation from a script. Also, the system will not behave properly if this step is over-utilized. This means that this step has not been designed to be extensively used by all calls coming into the system. Rather, the step is meant for updating documents in the repository database from time to time.
But I like your idea, Anthony. I would assume if the call volume was fairly low throughout the day, then it wouldn't be a problem... but I don't know how many calls are presented/handled this helpdesk.
06-12-2017 11:59 AM
Yeah, the relative word choice there "extensively" is not very helpful. If we had a way to measure the impact, that would be better. I'm actually more a fan of the DB access than the Document Repo access, but I thought I'd give a sample solution nonetheless.
The global session object could be better than both, from a performance stand point, but with the draw back of only being held in memory and possibly having to start over from time to time, when the session expires.
06-12-2017 02:37 PM
Agree. Well, there you go Joey. You have a couple of potential solutions you can try to implement IF you wanna move away from the external database connection. Good Luck!!!
06-26-2017 06:38 AM
Thanks Anthony and Mark.
Anthony, yes I was more concerned about the DB read/writes etc and I too prefer the DB method. Fortunately we have a pretty robust DB infrastructure that can handle plenty of IO so I was wanting to make sure I wasn't introducing any extra loads on the UCCX server with all the read/writes etc.
No ill affects that I am aware of using my method thus far so I think we are good to go. Thanks again for the time and input.
Joey
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide