[cisco-voip] UCCX Callback Script

Anthony Holloway avholloway+cisco-voip at gmail.com
Fri Nov 8 12:43:38 EST 2019


[image: image.png]

On Wed, Nov 6, 2019 at 6:18 PM Anthony Holloway <
avholloway+cisco-voip at gmail.com> wrote:

> To your last point about CIE: it doesn't work for me anyway, and I'm not
> trying to have the script do anything else, so threadlocking doesn't sound
> all that bad.  Unless of course you're trying to tell me that it's not just
> the thread my script is running within, but the entire CCX Engine as a
> thread, then yeah, that's pretty terrible.  Though, I just did a test,
> where I thread slept for 100 seconds in script A, and during that time,
> called into script B, and made sure everything worked fine while the
> threadlocking should have been taking place.  So, I would say it's not the
> CCX Engine as a whole, and likely each script is executed in its own
> thread.  This should be acceptable in this one use case.
>
> It's still a mystery to me how you're handling script 1.
>
> It kind of sounds like you are doing a 999s delay loop, but are you
> checking for the contact to be active still with the Get Contact Info
> step?  So, essentially the same thing I was doing, but with script steps
> instead (and less frequently)?  If so, then your script 1 stays active for
> ~15 minutes, worst case scenario, after the callback has been completed,
> correct?
>
> E.g.,
>
> CL1 = Place Call ()
>     Successful
>         LABEL0:
>         Delay 999s
>         is_active = Get Contact Info (CL1)
>         If (is_active)
>             True
>                 Goto LABEL0
> End
>
> On Wed, Nov 6, 2019 at 5:55 PM Tanner Ezell <tanner.ezell at gmail.com>
> wrote:
>
>> I place an exception handler for contact inactive, checking for the
>> callback contact via get Contact Info step to make sure the caller hanging
>> up didn't catch the exception.
>>
>> From there I have programmed in resiliency for the callback to be hung up
>> by the agent, but beyond that there is a Delay 999s loop. You'll never hit
>> the limit as you've discovered.
>>
>> Would not recommend Thread.sleep inside your code as it will thread lock
>> the task and may interfere; for example, it may prevent the CIE to be
>> caught properly in that script. Use Delay step, it's thread safe and is
>> built in a way that allows exceptions to be handled.
>>
>> On Wed, Nov 6, 2019 at 4:46 PM Anthony Holloway <
>> avholloway+cisco-voip at gmail.com> wrote:
>>
>>> Ok, so I solved the looping thing by...well...looping.  :/
>>>
>>> So, loops themselves are not the problem, rather it's the finite script
>>> steps we can execute which are the problem...err...challenge.
>>>
>>> Since the CIE doesn't get thrown in script 1 properly (bug?), I used a
>>> Do step in the success branch of the Place Call step to wait for the active
>>> state of CL1 to change.  Like so:
>>>
>>> Do {
>>>     do {
>>>         java.lang.Thread.sleep(1000);
>>>     } while (contact_leg_1.isActive());
>>> }
>>>
>>> CL1 only becomes inactive once the Agent acknowledges the callback and
>>> the call redirect is successful.  Therefore, I get all the benefits of
>>> Tanner's solution, plus I can keep the max steps at 1,000, and technically
>>> queue for 12 hours (the CallManager default max call timer).
>>>
>>> I think this should work just fine, though, more rigorous testing will
>>> be needed.  What do you think?
>>>
>>> On Wed, Nov 6, 2019 at 5:10 PM Anthony Holloway <
>>> avholloway+cisco-voip at gmail.com> wrote:
>>>
>>>> I see that the contact in both scripts is actually the same contact,
>>>> but each script views the contact from a different leg/sequence number
>>>> (I.e., Outbound leg versus Inbound leg)
>>>>
>>>> *Contact Created with Place Call Step (AKA CL1 for Call Leg 1)*
>>>>
>>>> §com.cisco.wf.subsystems.jtapi.CallImpl§JTAPICallContact[id=155,
>>>> implId=633001/1,state=STATE_ANSWERED_IDX,inbound=false,App
>>>> name=App1,task=26000000240,session=3000000115,seq num=0
>>>> ,cn=2411,dn=null,cgn=2402,ani=null,dnis=null,clid=null,atype=OUTBOUND
>>>> ,lrd=null,ocn=2411,route=RP[num=0000],OrigProtocolCallRef=null,DestProtocolCallRef=000000000009A8A902F728A200000000,TP=2402]§
>>>>
>>>>
>>>> *--Triggering Contact-- in the Queuing Script (AKA CL2 for Call Leg 2)*
>>>>
>>>> §com.cisco.wf.subsystems.jtapi.CallImpl§JTAPICallContact[id=156,
>>>> implId=633001/1,state=STATE_ANSWERED_IDX,inbound=true,App
>>>> name=App2,task=26000000241,session=3000000115,seq num=1
>>>> ,cn=2411,dn=2411,cgn=2402,ani=null,dnis=null,clid=null,atype=DIRECT
>>>> ,lrd=null,ocn=2411,route=RP[num=2411],OrigProtocolCallRef=000000000009A8A902F728A400000000,DestProtocolCallRef=null,TP=2401]§
>>>>
>>>>
>>>> So, things like Set/Get Enterprise Call Info work on the same contact,
>>>> because they are leg independent, whereas things requiring media, like Play
>>>> Prompt, are call leg dependent, and need to reference the correct call leg
>>>> of the contact.  Hence, you have to pass the CL1 object into Script 2, in
>>>> order to interact with the Agent from CL1.
>>>>
>>>> Unfortunately, if script 1 ends, there seems to be some clean up tasks
>>>> which run at the end of script 1 to unload CL1 from memory, and I am
>>>> getting an abort event in script 2, when trying to reference CL1.  As is
>>>> the case when I try to play media to the Agent or Call Redirect them to the
>>>> callback number.  If prevent script 1 from ending, and thus cleaning up
>>>> after itself, CL1 stays alive and script 2 works great.  The question for
>>>> me now is, how do I release script 1, without also releasing CL1?
>>>>
>>>> One thought I had was to setup a Contact Inactive listener in script 1,
>>>> and use the Delay step in script 1 for an absurd amount of time, like 12
>>>> hours, and then rely on the fact that once CL1 transfers the Agent to the
>>>> callback number, CL1 goes inactive, and thus the 12 hour delay is
>>>> interrupted and script 1 can now end.  In theory that is.  In practice,
>>>> script 1 never receives a CIE event, and the delay continues for the 12
>>>> hours.  No Beuno.
>>>>
>>>> Second thought was to signal something from script 2 to script 1, but
>>>> that requires looping in script 1 (polling).  No beuno.
>>>>
>>>> Which by the way, I should mention, I am looking at your solution as a
>>>> way to avoid looping, though you didn't specifically say that you have
>>>> figured out a way to avoid looping.  I was just being hopeful that somehow
>>>> your method did avoid looping.
>>>>
>>>> Like Brian Meade already mentioned, we have solved the "only once an
>>>> Agent answers" dilemma by using polling in script 1, and setting a flag in
>>>> script 2 once the agent answers, using Enterprise variables.  Polling
>>>> solves the Agent only hearing the message from the top, versus in the
>>>> middle, but it doesn't solve the finite script steps issue.
>>>>
>>>> Therefore, I am wondering how you are handling script 1, post
>>>> successful place call.
>>>>
>>>> Don't get me wrong, I'm still #TeamTanner, and will be converting my
>>>> callback method to yours, since there are some advantages.  I just have to
>>>> solve the script 1 clean up problem first.
>>>>
>>>> On Wed, Nov 6, 2019 at 4:09 PM Anthony Holloway <
>>>> avholloway+cisco-voip at gmail.com> wrote:
>>>>
>>>>> I actually got that part to work.  What I'm wondering about is what
>>>>> you are doing in script 1 (place call script) after the successful branch.
>>>>> Like, are you looping, are you delaying, are just ending?
>>>>>
>>>>> On Wed, Nov 6, 2019 at 3:52 PM Tanner Ezell <tanner.ezell at gmail.com>
>>>>> wrote:
>>>>>
>>>>>> It's really not all that complicated. Think of it this way, the place
>>>>>> call is the contact the agent is exposed to when they answer the queued
>>>>>> call, which of course is just the IVR.
>>>>>>
>>>>>> Pass the generated contact to the agent script (the one that has the
>>>>>> select resource), under the connected branch is when you know that your
>>>>>> other IVR application contact (from place call), connected to the agent.
>>>>>> Use the passed contact and play media just like you would any other
>>>>>> contact. In essence, you take the agent menu out of script 1 and put it in
>>>>>> script 2 :)
>>>>>>
>>>>>> With all that you can do some cool stuff, like ensuring the agent
>>>>>> doesn't just hang up (aka callback resiliency) and what to do if they do
>>>>>> (like re-queue, email a supervisor, re-call the agent, etc), can control if
>>>>>> the designated callback destination doesn't answer and some other fun stuff.
>>>>>>
>>>>>> happy hacking!
>>>>>>
>>>>>> On Wed, Nov 6, 2019 at 2:20 PM Anthony Holloway <
>>>>>> avholloway+cisco-voip at gmail.com> wrote:
>>>>>>
>>>>>>> Tanner, Can you describe, or show what you're doing in script 1,
>>>>>>> which has the Place Call step, inside the Successful branch?
>>>>>>>
>>>>>>> On Tue, Nov 5, 2019 at 4:30 PM Tanner Ezell <tanner.ezell at gmail.com>
>>>>>>> wrote:
>>>>>>>
>>>>>>>> Pssshhht....I'll share a "secret" for playing the agent menu only
>>>>>>>> when the agent answers..
>>>>>>>>
>>>>>>>> Pass the contact to the agent script, then play your agent menu
>>>>>>>> after they connect.
>>>>>>>>
>>>>>>>> Ez pz.
>>>>>>>>
>>>>>>>> Regards,
>>>>>>>> Tanner Ezell
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On Tue, Nov 5, 2019 at 2:54 PM Brian Meade <bmeade90 at vt.edu> wrote:
>>>>>>>>
>>>>>>>>> Anthony,
>>>>>>>>>
>>>>>>>>> I'm curious how you handle catching when the agent answers the
>>>>>>>>> callback request.
>>>>>>>>>
>>>>>>>>> I've got my scripts checking to see if the CallBack contact was
>>>>>>>>> answered by setting some Enterprise Info in my callback queue script but I
>>>>>>>>> still have to check every few seconds to see if that Enterprise Info is set.
>>>>>>>>>
>>>>>>>>> I just max out the max steps to account for that.
>>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> Brian Meade
>>>>>>>>>
>>>>>>>>> On Tue, Nov 5, 2019 at 4:19 PM Anthony Holloway <
>>>>>>>>> avholloway+cisco-voip at gmail.com> wrote:
>>>>>>>>>
>>>>>>>>>> Hi Tim,
>>>>>>>>>>
>>>>>>>>>> I think the idea of a flawless script is in the eyes of the
>>>>>>>>>> beholder.
>>>>>>>>>>
>>>>>>>>>> I don't personally use the example script from the repo; are you
>>>>>>>>>> talking about the one here:
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> script_respository_902\script_respository\release3\BaseLineAdvQueuing\BaseLineAdvQueuing.aef
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> If so, there a few things wrong with that script.
>>>>>>>>>>
>>>>>>>>>> For example, you said "...despite having Contact Inactive
>>>>>>>>>> exception error handling..."
>>>>>>>>>>
>>>>>>>>>> Yeah, they setup an exception handler at the top for
>>>>>>>>>> ContactInactiveException, but then they never clear it, or reset it, and so
>>>>>>>>>> if and when the caller disconnects while recording their message or
>>>>>>>>>> listening to the "success" prompt, the whole thing falls a part and fails,
>>>>>>>>>> sending script execution down to the ExceptionCIE label.
>>>>>>>>>>
>>>>>>>>>> Another thing wrong with it is that the waiting mechanism for the
>>>>>>>>>> Agent is such that it plays a relatively short prompt, waits 3 seconds for
>>>>>>>>>> input from the Agent, then repeats.
>>>>>>>>>>
>>>>>>>>>> If you consider every application has a max 1,000 steps it can
>>>>>>>>>> execute, and you subtract off the overhead of just getting the call to this
>>>>>>>>>> point (say 21 steps in the most streamlined of scenarios), that leaves you
>>>>>>>>>> with 32 minutes to queue a call, otherwise the call will be aborted.  Since
>>>>>>>>>> most people are only interested in callback when they have queue hold time
>>>>>>>>>> problems, this is likely to cause more issues than it solves.
>>>>>>>>>>
>>>>>>>>>> "...I’ve read that the Call Control Group and Dialog Group should
>>>>>>>>>> be different from the trigger on the originating application..."
>>>>>>>>>>
>>>>>>>>>> Can you link the source?
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On Tue, Nov 5, 2019 at 10:59 AM Johnson, Tim <johns10t at cmich.edu>
>>>>>>>>>> wrote:
>>>>>>>>>>
>>>>>>>>>>> Anyone have a callback script that is working flawlessly? We
>>>>>>>>>>> have implemented the solution in Cisco’s Advanced Queueing script and it’s
>>>>>>>>>>> seems to be working, but I’m seeing Contact Inactive Exceptions and Contact
>>>>>>>>>>> Creation errors in syslog each time the callback is used, despite having
>>>>>>>>>>> Contact Inactive exception error handling.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> It seems that the issue may be related to the Place Call step
>>>>>>>>>>> which calls the trigger of the callback application. I’ve read that the
>>>>>>>>>>> Call Control Group and Dialog Group should be different from the trigger on
>>>>>>>>>>> the originating application (which is what we have setup), but I’m curious
>>>>>>>>>>> if those should also be different from what’s used on the callback
>>>>>>>>>>> application. If so, can I use the same CCG and DG from the original
>>>>>>>>>>> trigger, on the callback trigger?
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> For example, I have the following setup:
>>>>>>>>>>>
>>>>>>>>>>> App_A application has a trigger that uses CCG #8 and Dialog
>>>>>>>>>>> Group #0. In its script, it uses the Place Call step with CCG #25 and
>>>>>>>>>>> Dialog Group #3. This places the call to App_Callback application which has
>>>>>>>>>>> a trigger that uses CCG #25 and Dialog Group #3.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Tim Johnson
>>>>>>>>>>>
>>>>>>>>>>> Voice & Video Engineer
>>>>>>>>>>>
>>>>>>>>>>> Central Michigan University
>>>>>>>>>>>
>>>>>>>>>>> Phone: +19897744406 at cmich.edu
>>>>>>>>>>>
>>>>>>>>>>> Fax: +19897795900
>>>>>>>>>>>
>>>>>>>>>>> [image: webexemailsig] <https://cmich.webex.com/meet/johns10t>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> _______________________________________________
>>>>>>>>>>> cisco-voip mailing list
>>>>>>>>>>> cisco-voip at puck.nether.net
>>>>>>>>>>> https://puck.nether.net/mailman/listinfo/cisco-voip
>>>>>>>>>>>
>>>>>>>>>> _______________________________________________
>>>>>>>>>> cisco-voip mailing list
>>>>>>>>>> cisco-voip at puck.nether.net
>>>>>>>>>> https://puck.nether.net/mailman/listinfo/cisco-voip
>>>>>>>>>>
>>>>>>>>> _______________________________________________
>>>>>>>>> cisco-voip mailing list
>>>>>>>>> cisco-voip at puck.nether.net
>>>>>>>>> https://puck.nether.net/mailman/listinfo/cisco-voip
>>>>>>>>>
>>>>>>>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://puck.nether.net/pipermail/cisco-voip/attachments/20191108/c49a71c7/attachment.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image.png
Type: image/png
Size: 62204 bytes
Desc: not available
URL: <https://puck.nether.net/pipermail/cisco-voip/attachments/20191108/c49a71c7/attachment.png>


More information about the cisco-voip mailing list