Author Topic: AgentCallBackLogin-replacement  (Read 5339 times)

perlmaster

  • Newbie
  • *
  • Posts: 18
  • Karma: 0
    • View Profile
AgentCallBackLogin-replacement
« on: February 17, 2010, 16:03:49 »
I've been communicating with Lorenzo at Loway about this, but he appears to be tied up working on a new release, so I thought I'd see if anyone else is having the same issue and has come up with a solution.

We need to use dynamic logins where the agents hot desk and are able to choose which queues to login to.

I've posted previous questions regarding this and was directed to a solution that mimicked AgentCallBackLogin.  I can't find this QM anoucment in this forum, but it can be found here: http://groups.google.com/group/agentcallbacklogin-replacement/browse_thread/thread/f41defc702ab991b/e2446f0f679f85de#e2446f0f679f85de

[edit] I found the forum post. http://forum.queuemetrics.com/index.php?topic=728.0[/edit]

The following is the contents on an email I sent Lorenzo.

I've tested the proposed solution that you provided which
I found to have the following issues.

1)  Instead of allowing the agent to choose which queue to
login to, it logs them into all queues that they are
statically assigned to, which defeats the main purpose of
dynamic logins.

2)  It hard codes the agents in the extensions file which
duplicates what's already in agents.conf.

3)  Hard coding the agent id's in the extensions file for
each queue is cumbersome because we have over 100 agents
and at least 4 queues.

4)  The pause feature did not work in my tests.

5)  The realtime monitor listed the call in “Calls being
processed:”, but never indicated that the call was
answered and did not remove the entry after the call
ended.  It remained until the queue timeout period was
reached.

I also tested and am still using the solution provided here:
http://etel.wiki.oreilly.com/wiki/index.php/Asterisk_Queues_using_AddQueueMember

This solution also had a few issues in the realtime monitor.
1)  It paced 2 entries in “Agents currently logged in:”, one
showing the agent id and the other showing the agent name
in the “Agent” field (once they received their first
call).

2)  The second entry, showing their name, was not removed
when they logged out.

3)  It did not show the extension the user was logged into.

I am now testing a solution that merges these 2 approaches
so that our agents can authenticate against the
agents.conf file and choose which queue(s) to login to,
but this still has the #5 problem I listed for your
proposed solution.

Here is the relevant portion of the dialplan that I'm testing.
Code: [Select]
[utilities]

; Login
exten => 54,1,Set(QUEUEDST=test1\,test2)
exten => 54,n,Goto(agent-login,s,1)

; logout
exten => 55,1,Set(QUEUEDST=test1\,test2)
exten => 55,n,Goto(agent-logout,s,1)


[xagents]
exten => _X.,1,Set(realchan=${DB(agent/${EXTEN})})
exten => _X.,n,NoOP("Trying agent/${EXTEN} as ${realchan}")
exten => _X.,n,Dial(${realchan},60,tT)
exten => h,1,NoOp


[agent-login]
exten => s,1,Answer

; Give the user 2 tries to enter their agent ID
exten => s,n,Set(COUNTER=0)
exten => s,n(agent),Set(COUNTER=$[${COUNTER}+1])
exten => s,n,Read(agent,agent-user);
exten => s,n,GotoIf($["${AGENT(${agent}:password)}"!=""]?auth)
exten => s,n,ExecIf($[${COUNTER}<2],playback,agent-incorrect)
exten => s,n,ExecIf($[${COUNTER}<2],Goto,agent)
; Entered an invalid agentid 2 times, Playback an error beep and hangup.
exten => s,n,Playback(beeperr)
exten => s,n,Playback(sorry)
exten => s,n,Hangup

; Authenticate password against the agents.conf
exten => s,n(auth),Authenticate(${AGENT(${agent}:password)})

; Set vars to hold the agent2phone mapping
exten => s,n,Set(phone=${CUT(CUT(CHANNEL,-,1),/,2)})
exten => s,n,Set(DB(agent/${agent})=SIP/${phone})
exten => s,n,Set(DB(agent_byphone/${phone})=${agent})

; Add a queue_log entry simulating the AgentCallbackLogin application
exten => s,n,QueueLog(NONE,${UNIQUEID},Local/${agent}@xagents,AGENTCALLBACKLOGIN,${phone})

; Begin the loop for the queues, FIELDQTY will find how many queues we are passing in QUEUEDST delimited by a comma
exten => s,n,Set(i=1)
exten => s,n,While($[${i}<=${FIELDQTY(QUEUEDST,\,)}])
; For each Queue Record, split the name and penalty on a dash and set the variables.
exten => s,n,Set(ARRAY(CURRENT_QUEUE,PENALTY)=${CUT(CUT(QUEUEDST,\,,${i}),,1)},${CUT(CUT(QUEUEDST,\,,${i}),,2)})
exten => s,n,AddQueueMember(${CURRENT_QUEUE},Local/${agent}@xagents,${PENALTY},,${AGENT(${agent}:name)},SIP/${phone})
exten => s,n,Set(i=$[${i}+1])
exten => s,n,EndWhile

; We're only catching the last AddQueueMember status here.
exten => s,n,ExecIf($["${AQMSTATUS}"="NOSUCHQUEUE"],Playback,sorry&an-error-has-occured)
; If we are either ADDED or MEMBERALREADY playback the agent-loginok message..
exten => s,n,ExecIf($["${AQMSTATUS}"!="NOSUCHQUEUE"],Playback,agent-loginok)
exten => s,n,Hangup


[agent-logout]
exten => s,1,Answer
exten => s,n,Read(agent,agent-user)
exten => s,n,Set(chan=${DB(agent/${agent})})
exten => s,n,Set(DB(agent/${agent})=)

exten => s,n,Set(i=1)
exten => s,n,Set(SIP_EXTEN=${CUT(CUT(CHANNEL,-,1),/,2)})
exten => s,n,While($[${i}<=${FIELDQTY(QUEUEDST,\,)}])
exten => s,n,Set(CURRENT_QUEUE=${CUT(QUEUEDST,\,,${i})})
exten => s,n,RemoveQueueMember(${CURRENT_QUEUE},Local/${agent}@xagents)
exten => s,n,Set(i=$[${i}+1])
exten => s,n,EndWhile
exten => s,n,QueueLog(NONE,${UNIQUEID},Local/${agent}@xagents,AGENTCALLBACKLOGOFF)
exten => s,n,Playback(agent-loggedoff)
exten => s,n,Hangup


[agent-pause]
;-- pause: Pause the queue member from all queues. --;
exten => pause,1,Answer
exten => pause,n,PauseQueueMember(|Local/${CUT(CUT(CHANNEL,-,1),/,2)}@${AGENT_CONTEXT}/n)
exten => pause,n,NoOp(${PQMSTATUS})
; Play stutter tones.  There is currently no stock voice file for this
exten => pause,n,PlayTones(!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440)
exten => pause,n,Wait(1.5)
exten => pause,n,Hangup


[agent-unpause]
;-- unpause: Unpase the queue member from all queues. --;
exten => unpause,1,Answer
exten => unpause,n,UnPauseQueueMember(|Local/${CUT(CUT(CHANNEL,-,1),/,2)}@${AGENT_CONTEXT}/n)
exten => unpause,n,NoOp(${UPQMSTATUS})
; Play short stutter tones, no stock voice file for this.
exten => unpause,n,PlayTones(!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440)
exten => unpause,n,Wait(1.0)
exten => unpause,n,Hangup

« Last Edit: February 17, 2010, 16:11:41 by perlmaster »

mudslide567

  • Newbie
  • *
  • Posts: 28
  • Karma: 2
    • View Profile
Re: AgentCallBackLogin-replacement
« Reply #1 on: February 17, 2010, 16:46:20 »
As far as I can tell based on experience across a dozen or so installations, none of the replacements for AgentCallBackLogin() really work in a hot seating environment, especially on versions of asterisk 1.4.x and each of the suggested methods I have seen write ups for have one or more problems such as the one you are seeing when you try to adapt QM for hot seating.

I have a really brute force [inelegant] workaround that goes back to basics for the time being until these is a true solution for the hot seating environment: implement a modified version of hot seating.  I use softphones [I chose Zoiper since our agents love it] and set each one to have several registrations on it reflecting all the agents who might use that particular work station.  When an agent comes to work at that desk, they register Zoiper only on the extension that matches their agent number.  Since all agents are registered on extensions that match their agent number, I can use the QM "rewrite" option again and operate the center as if it were not in hot seating mode.  I still add agents to queues dynamically etc.  Crude but it works. In a high employee turnover call center, it is relatively high maintenance but I have tried the other solutions [workarounds] without success so far.


perlmaster

  • Newbie
  • *
  • Posts: 18
  • Karma: 0
    • View Profile
Re: AgentCallBackLogin-replacement
« Reply #2 on: February 17, 2010, 17:34:32 »
Our setup is different.  We have analog phones that connect to ATA sip adapters and use 5 digit extensions which specifies their location.  The agent numbers are the employee numbers and don't correlate to the extensions.  We currently have 4 queues and may add more.  We have a little over 100 agents in a high turnover environment.

Based on those differences, your solution won't meet our needs.

mudslide567

  • Newbie
  • *
  • Posts: 28
  • Karma: 2
    • View Profile
Re: AgentCallBackLogin-replacement
« Reply #3 on: February 17, 2010, 18:01:14 »
We have a similar setup in that agent numbers are employee numbers and similar scale [300 active agents at any given time, 10 queues], but the analog phones definitely rules out any ability to spoof hot seating.  We had already tried the solution that you are currently trying but after much head banging, could never really get it to work properly [for the same reasons you are finding].

We are currently testing another approach that should be more robust which is to track agent login/logouts with an AGI script that writes to separate table and then use that data source to overwrite the entries in queue_log table in QM [we have found that it is too much stress on the asterisk server to try to overwrite directly in the queue_log file].  This looks like it will solve the problem but we are probably a couple of weeks out from being able to roll that into production.

perlmaster

  • Newbie
  • *
  • Posts: 18
  • Karma: 0
    • View Profile
Re: AgentCallBackLogin-replacement
« Reply #4 on: February 17, 2010, 18:13:32 »
Once you get that rolled out, I'd love to get more details and how well it ends up working.

QueueMetrics

  • Loway
  • Hero Member
  • *
  • Posts: 2999
  • Karma: 39
    • View Profile
    • QueueMetrics
Re: AgentCallBackLogin-replacement
« Reply #5 on: February 18, 2010, 15:05:35 »
We have been working on a solution for hotdesking, but it is really tied to 1.6's because older Asterisks are too buggy to use chan Local extensively under load.
A few of uor clients use "blank" softphones, so that the agent has to log in every time with their credentials; this is a sad form of hotdesking.


perlmaster

  • Newbie
  • *
  • Posts: 18
  • Karma: 0
    • View Profile
Re: AgentCallBackLogin-replacement
« Reply #6 on: February 18, 2010, 15:29:04 »
How close are you with the hotdesking solution?

I've been told we can't go to 1.6 until we have a working solution.  I also can't go back to using AgentCallBackLogin due to the (new) requirement of having the agents choose which queue(s) to login to.

QueueMetrics

  • Loway
  • Hero Member
  • *
  • Posts: 2999
  • Karma: 39
    • View Profile
    • QueueMetrics
Re: AgentCallBackLogin-replacement
« Reply #7 on: February 19, 2010, 09:38:20 »
The thing is far from being trivial, unfortunately.