Agents without agent channel

Here are two examples (one shorter, one long) how to establish queues without using chan_agent.

Example 1

Desgined for Asterisk 1.2

  [agent-login]
  exten => s,1,NoOp(${AgentUser})
  exten => s,2,AddQueueMember(${AgentContext}|${AgentChannel}|${AgentPenalty})
  exten => s,3,Wait(1)
  exten => s,4,Playback(agent-loginok)
  exten => s,5,Hangup
  exten => s,103,RemoveQueueMember(${AgentContext}|${AgentChannel})
  exten => s,104,Wait(1)
  exten => s,105,Playback(agent-loggedoff)
  exten => s,106,Hangup

  [tax-line]
  exten => s,1,Macro(dnv-messagebox-setup)
  exten => s,n,Set(AgentContext=${CONTEXT})
  exten => s,n,Set(AgentChannel=${CHANNEL})
  exten => s,n,Set(AgentChannel=${CUT(AgentChannel,-,-2)})
  exten => s,n,Set(AgentUser=${CUT(AgentChannel,/,2)})
  exten => s,n,NoOp(${AgentUser})
  ; tax-queue agents
  exten => s,n,GotoIf($["${AgentUser}" = "2488-tessmanl"]?:macdonap)
  exten => s,n,Set(AgentPenalty=1)
  exten => s,n,Goto(agent-login,s,1)
  exten => s,n(macdonap),GotoIf($["${AgentUser}" = "2488-macdonap"]?:chengb)
  exten => s,n,Goto(agent-login,s,1)
  exten => s,n(chengb),GotoIf($["${AgentUser}" = "2488-chengb"]?:listhael)
  exten => s,n,Set(AgentPenalty=2)
  exten => s,n,Goto(agent-login,s,1)
  exten => s,n(listhael),GotoIf($["${AgentUser}" = "2488-listhael"]?:nguyent)
  exten => s,n,Set(AgentPenalty=3)
  exten => s,n,Goto(agent-login,s,1)
  exten => s,n(nguyent),GotoIf($["${AgentUser}" = "2488-nguyent"]?:NonAgentStart)
  exten => s,n,Set(AgentPenalty=4)
  exten => s,n,Goto(agent-login,s,1)
  exten => s,n(NonAgentStart),BackGround(call-processors/2488)

Example 2

The chan_agent doesn't behave well in some cases. Here is a large dialplan to emulate agent channels and even more. It uses dynamic members, and requires CVS after about Feb 2005. Under the 'slacker' exten, I have a res_perl sub that notifies the agent of their logoff. You can nuke this or replace it with something to suit you.

Features:
  • Will not try agents already on any call (depends on CVS ChanIsAvail() 's' option)
  • Login will give option to kick off same agent already logged in on another channel
  • Logout/Login auto-detect
  • Auto-logoff of agents not answering calls
  • Agent can request more wrap-up time (accurate wrap-ups depend on CVS app_queue with state thread)
  • Availability toggle (todo: use new PauseQueueMember app)
This does not implement passwords, but that's easy enough to add with some DBget() and another Read();

Create an entry for each agent like so:

/AGENT/valid/n == (colon-separated queues)
e.g.
cli> database put AGENT valid/101 tech:noc:hosting
cli> database put AGENT valid/102 sales:service
cli> database put AGENT valid/103 billing


; magic to circumvent chan_agent's brokenness
; agents are stored in the astdb AGENT tree

[agent_features]
; include this context somewhere, and map buttons to it
exten => 8301,1,Goto(agent_login,s,1);
exten => 8302,1,Goto(agent_avail,s,1);
exten => 8303,1,Goto(agent_moretime,s,1);

[agent_call]
; Local/${agent}@agent_call are dynamic members
; added to semicolon-separated queues in AGENT/valid tree
exten => _XXX,1,SetVar(agent=${EXTEN});
exten => _XXX,2,ResponseTimeout(1);
exten => _XXX,3,DBget(mychan=AGENT/${agent}/onChannel);
exten => _XXX,4,Goto(check,1);
exten => _XXX,104,Congestion(); oops, we shouldn't be calling this agent
; check if channel in use
exten => check,1,ChanIsAvail(${mychan},s,);
exten => check,102,Goto(busy,1);
exten => check,2,DBget(wrapUpAt=AGENT/${agent}/wrapUpAt);
exten => check,3,GotoIf($[ $[${EPOCH} - ${wrapUpAt}] < 0]?busy,1);
exten => check,4,DBdel(AGENT/${agent}/wrapUpAt); expired, nuke it
exten => check,103,NoOp(agent ${agent} has no wrapUpAt in astdb == call);
exten => check,104,Goto(5);
; check availability
exten => check,5,DBget(avail=AGENT/${agent}/avail);
exten => check,6,GotoIf(${avail}?call,1:busy,1);
exten => check,106,NoOp(agent ${agent} has no avail in astdb == call);
exten => check,107,Goto(call,1);
; call agent
exten => call,1,SetVar(_ALERT_INFO=queue);
exten => call,2,UserEvent(QueueCall|Queue: ${queue});
exten => call,3,Dial(${mychan},15,M(agent_answered^${agent}));
exten => call,4,Goto(call-${DIALSTATUS},1);
; handle dial results, auto-logout agent under two conditions
exten => call-BUSY,1,DBget(rejects=AGENT/${agent}/rejects);
exten => call-BUSY,102,SetVar(rejects=0);
exten => call-BUSY,103,Goto(2);
exten => call-BUSY,2,SetVar(rejects=$[${rejects} + 1]);
exten => call-BUSY,3,DBput(AGENT/${agent}/rejects=${rejects});
exten => call-BUSY,4,UserEvent(AgentReject,Agent: ${agent});
exten => call-BUSY,5,GotoIf($[${rejects} > 2]?slacker-rejects,1); 3 strikes you're out (on DND?)
exten => call-BUSY,6,Hangup; keep their position
exten => call-NOANSWER,1,DBget(bounces=AGENT/${agent}/bounces);
exten => call-NOANSWER,102,SetVar(bounces=0);
exten => call-NOANSWER,103,Goto(2);
exten => call-NOANSWER,2,SetVar(bounces=$[${bounces} + 1]);
exten => call-NOANSWER,3,DBput(AGENT/${agent}/bounces=${bounces});
exten => call-NOANSWER,4,UserEvent(AgentBounce,Agent: ${agent});
exten => call-NOANSWER,5,GotoIf($[${bounces} > 2]?slacker-bounces,1); 3 strikes you're out (bouncing)
exten => call-NOANSWER,6,Hangup; keep their position
;
exten => slacker-bounces,1,SetVar(reason=bounced 3 calls);
exten => slacker-bounces,2,Goto(slacker,1);
exten => slacker-rejects,1,SetVar(reason=rejected 3 calls);
exten => slacker-rejects,2,Goto(slacker,1);
exten => slacker,1,UserEvent(AgentSlacker,Agent: ${agent});
exten => slacker,n,NoOp(agent ${agent} is a slacker: ${reason});
; res_perl required. this notifies the phone (sip message) and an IRC bot
exten => slacker,n,Perl(notify_slacker:${agent}:${reason});
exten => slacker,n,Goto(agent_login,logout,1); log them off
;
exten => busy,1,Busy();
exten => t,1,Hangup();
exten => i,1,Congestion();

[macro-agent_answered]
exten => s,1,DBdel(AGENT/${ARG1}/bounces);
exten => s,2,DBdel(AGENT/${ARG1}/rejects);

[agent_avail]
; toggle available status
exten => s,1,Answer;
exten => s,2,ResponseTimeout(1);
exten => s,3,Wait(1);
exten => s,4,ResponseTimeout(1);
exten => s,5,Cut(mychan=CHANNEL,-,1);
exten => s,6,DBget(agent=AGENT/channelHasAgent/${mychan});
exten => s,107,Goto(login,1);
exten => s,7,DBget(stat=AGENT/${agent}/avail);
exten => s,8,GotoIf(${stat}?unavail,1:avail,1);
; set unavailable, you slacker
exten => unavail,1,DBput(AGENT/${agent}/avail=0);
exten => unavail,2,Playback(xm/agent-avail-no);
exten => unavail,3,UserEvent(AgentUnavailable,Agent: ${agent});
; set available
exten => avail,1,DBput(AGENT/${agent}/avail=1);
exten => avail,2,Playback(xm/agent-avail-yes);
exten => avail,3,UserEvent(AgentAvailable,Agent: ${agent});
; not logged in
exten => login,1,Playback(xm/agent-avail-login);
exten => login,2,Goto(agent_login,s,1)
;
exten => t,1,Hangup();
exten => i,1,Playback(xm/agent-avail-error);

[agent_moretime]
exten => s,1,Answer;
exten => s,2,ResponseTimeout(1);
exten => s,3,Wait(1);
exten => s,4,NoOp(agent needs more wrap up time);
exten => s,5,ResponseTimeout(1);
exten => s,6,Cut(mychan=CHANNEL,-,1);
exten => s,7,DBget(agent=AGENT/channelHasAgent/${mychan});
exten => s,108,Goto(login,1);
exten => s,8,DBput(AGENT/${agent}/wrapUpAt=$[${EPOCH} + ${WRAPUPTIME}]);
exten => s,9,Playback(xm/agent-moretime-ok);
exten => s,10,UserEvent(AgentMoreTime,Agent: ${agent}, Until: $[${EPOCH} + ${WRAPUPTIME}]);
;
exten => login,1,Playback(xm/agent-moretime-login);
exten => login,2,Goto(agent_login,s,1)
;
exten => t,1,Hangup();
exten => i,1,Playback(xm/agent-moretime-error);

[agent_login]
exten => s,1,Answer();
exten => s,2,Wait(1);
exten => s,3,ResponseTimeout(5);
exten => s,4,Cut(mychan=CHANNEL,-,1);
exten => s,5,DBget(agent=AGENT/channelHasAgent/${mychan});
exten => s,106,Goto(start,1);
exten => s,6,Goto(logout,1);
; a couple of read routines to get agent id
exten => start,1,Read(agent,xm/agent-login-user);
exten => start,2,Goto(verify,1);
exten => dupe,1,Read(continue,xm/agent-login-already-continue,1);
exten => dupe,2,GotoIf($["${continue}" = "1"]?3:4);
exten => dupe,3,Goto(logout,1);
exten => dupe,4,Read(agent,xm/agent-login-user);
exten => dupe,5,Goto(verify,1);
exten => bad,1,Read(agent,xm/agent-login-incorrect);
exten => bad,2,Goto(verify,1);
; verification
exten => verify,1,DBget(onchan=AGENT/${agent}/onChannel);
exten => verify,102,Goto(3);
exten => verify,2,GotoIf($["${onchan}" = "{mychan}"]?logout,1:dupe,1);
exten => verify,3,DBget(queues=AGENT/valid/${agent});
exten => verify,104,Goto(bad,1);
exten => verify,4,Goto(login,1);
; login routine
exten => login,1,DBput(AGENT/channelHasAgent/${mychan}=${agent});
exten => login,2,DBput(AGENT/${agent}/onChannel=${mychan});
exten => login,3,DBput(AGENT/${agent}/avail=1);
exten => login,4,SetVar(i=1);
exten => login,5,Cut(j=queues,:,${i});
exten => login,6,While($[${LEN(${j})} > 0]);
exten => login,7,AddQueueMember(${j},Local/${agent}@agent_call);
exten => login,8,SetVar(i=$[${i} + 1]);
exten => login,9,Cut(j=queues,:,${i});
exten => login,10,EndWhile;
exten => login,11,Playback(xm/agent-login-ok);
exten => login,12,Goto(t,1);
; logout, leave configured queues
exten => logout,1,DBget(queues=AGENT/valid/${agent});
exten => logout,2,SetVar(i=1);
exten => logout,3,Cut(j=queues,:,${i});
exten => logout,4,While($[${LEN(${j})} > 0]);exten => logout,5,RemoveQueueMember(${j},Local/${agent}@agent_call);
exten => logout,6,SetVar(i=$[${i} + 1]);
exten => logout,7,Cut(j=queues,:,${i});
exten => logout,8,EndWhile;
exten => logout,9,DBget(agentchan=AGENT/${agent}/onChannel);
;exten => logout,n,DBdel(AGENT/channelHasAgent/${mychan});
exten => logout,10,DBdel(AGENT/channelHasAgent/${agentchan});
exten => logout,11,DBdeltree(AGENT/${agent});
exten => logout,12,Playback(xm/agent-login-off,skip);
exten => logout,13,GotoIf($["${continue}" = "1"]?login,1); logging off a dupe, go back
exten => logout,14,Goto(t,1);
;
exten => t,1,Hangup;
exten => i,1,Playback(xm/agent-login-error);


You'll need these sound files (allison edits):
http://orbit.xmission.com/~kevin/agent-sounds.tar.gz
Here are two examples (one shorter, one long) how to establish queues without using chan_agent.

Example 1

Desgined for Asterisk 1.2

  [agent-login]
  exten => s,1,NoOp(${AgentUser})
  exten => s,2,AddQueueMember(${AgentContext}|${AgentChannel}|${AgentPenalty})
  exten => s,3,Wait(1)
  exten => s,4,Playback(agent-loginok)
  exten => s,5,Hangup
  exten => s,103,RemoveQueueMember(${AgentContext}|${AgentChannel})
  exten => s,104,Wait(1)
  exten => s,105,Playback(agent-loggedoff)
  exten => s,106,Hangup

  [tax-line]
  exten => s,1,Macro(dnv-messagebox-setup)
  exten => s,n,Set(AgentContext=${CONTEXT})
  exten => s,n,Set(AgentChannel=${CHANNEL})
  exten => s,n,Set(AgentChannel=${CUT(AgentChannel,-,-2)})
  exten => s,n,Set(AgentUser=${CUT(AgentChannel,/,2)})
  exten => s,n,NoOp(${AgentUser})
  ; tax-queue agents
  exten => s,n,GotoIf($["${AgentUser}" = "2488-tessmanl"]?:macdonap)
  exten => s,n,Set(AgentPenalty=1)
  exten => s,n,Goto(agent-login,s,1)
  exten => s,n(macdonap),GotoIf($["${AgentUser}" = "2488-macdonap"]?:chengb)
  exten => s,n,Goto(agent-login,s,1)
  exten => s,n(chengb),GotoIf($["${AgentUser}" = "2488-chengb"]?:listhael)
  exten => s,n,Set(AgentPenalty=2)
  exten => s,n,Goto(agent-login,s,1)
  exten => s,n(listhael),GotoIf($["${AgentUser}" = "2488-listhael"]?:nguyent)
  exten => s,n,Set(AgentPenalty=3)
  exten => s,n,Goto(agent-login,s,1)
  exten => s,n(nguyent),GotoIf($["${AgentUser}" = "2488-nguyent"]?:NonAgentStart)
  exten => s,n,Set(AgentPenalty=4)
  exten => s,n,Goto(agent-login,s,1)
  exten => s,n(NonAgentStart),BackGround(call-processors/2488)

Example 2

The chan_agent doesn't behave well in some cases. Here is a large dialplan to emulate agent channels and even more. It uses dynamic members, and requires CVS after about Feb 2005. Under the 'slacker' exten, I have a res_perl sub that notifies the agent of their logoff. You can nuke this or replace it with something to suit you.

Features:
  • Will not try agents already on any call (depends on CVS ChanIsAvail() 's' option)
  • Login will give option to kick off same agent already logged in on another channel
  • Logout/Login auto-detect
  • Auto-logoff of agents not answering calls
  • Agent can request more wrap-up time (accurate wrap-ups depend on CVS app_queue with state thread)
  • Availability toggle (todo: use new PauseQueueMember app)
This does not implement passwords, but that's easy enough to add with some DBget() and another Read();

Create an entry for each agent like so:

/AGENT/valid/n == (colon-separated queues)
e.g.
cli> database put AGENT valid/101 tech:noc:hosting
cli> database put AGENT valid/102 sales:service
cli> database put AGENT valid/103 billing


; magic to circumvent chan_agent's brokenness
; agents are stored in the astdb AGENT tree

[agent_features]
; include this context somewhere, and map buttons to it
exten => 8301,1,Goto(agent_login,s,1);
exten => 8302,1,Goto(agent_avail,s,1);
exten => 8303,1,Goto(agent_moretime,s,1);

[agent_call]
; Local/${agent}@agent_call are dynamic members
; added to semicolon-separated queues in AGENT/valid tree
exten => _XXX,1,SetVar(agent=${EXTEN});
exten => _XXX,2,ResponseTimeout(1);
exten => _XXX,3,DBget(mychan=AGENT/${agent}/onChannel);
exten => _XXX,4,Goto(check,1);
exten => _XXX,104,Congestion(); oops, we shouldn't be calling this agent
; check if channel in use
exten => check,1,ChanIsAvail(${mychan},s,);
exten => check,102,Goto(busy,1);
exten => check,2,DBget(wrapUpAt=AGENT/${agent}/wrapUpAt);
exten => check,3,GotoIf($[ $[${EPOCH} - ${wrapUpAt}] < 0]?busy,1);
exten => check,4,DBdel(AGENT/${agent}/wrapUpAt); expired, nuke it
exten => check,103,NoOp(agent ${agent} has no wrapUpAt in astdb == call);
exten => check,104,Goto(5);
; check availability
exten => check,5,DBget(avail=AGENT/${agent}/avail);
exten => check,6,GotoIf(${avail}?call,1:busy,1);
exten => check,106,NoOp(agent ${agent} has no avail in astdb == call);
exten => check,107,Goto(call,1);
; call agent
exten => call,1,SetVar(_ALERT_INFO=queue);
exten => call,2,UserEvent(QueueCall|Queue: ${queue});
exten => call,3,Dial(${mychan},15,M(agent_answered^${agent}));
exten => call,4,Goto(call-${DIALSTATUS},1);
; handle dial results, auto-logout agent under two conditions
exten => call-BUSY,1,DBget(rejects=AGENT/${agent}/rejects);
exten => call-BUSY,102,SetVar(rejects=0);
exten => call-BUSY,103,Goto(2);
exten => call-BUSY,2,SetVar(rejects=$[${rejects} + 1]);
exten => call-BUSY,3,DBput(AGENT/${agent}/rejects=${rejects});
exten => call-BUSY,4,UserEvent(AgentReject,Agent: ${agent});
exten => call-BUSY,5,GotoIf($[${rejects} > 2]?slacker-rejects,1); 3 strikes you're out (on DND?)
exten => call-BUSY,6,Hangup; keep their position
exten => call-NOANSWER,1,DBget(bounces=AGENT/${agent}/bounces);
exten => call-NOANSWER,102,SetVar(bounces=0);
exten => call-NOANSWER,103,Goto(2);
exten => call-NOANSWER,2,SetVar(bounces=$[${bounces} + 1]);
exten => call-NOANSWER,3,DBput(AGENT/${agent}/bounces=${bounces});
exten => call-NOANSWER,4,UserEvent(AgentBounce,Agent: ${agent});
exten => call-NOANSWER,5,GotoIf($[${bounces} > 2]?slacker-bounces,1); 3 strikes you're out (bouncing)
exten => call-NOANSWER,6,Hangup; keep their position
;
exten => slacker-bounces,1,SetVar(reason=bounced 3 calls);
exten => slacker-bounces,2,Goto(slacker,1);
exten => slacker-rejects,1,SetVar(reason=rejected 3 calls);
exten => slacker-rejects,2,Goto(slacker,1);
exten => slacker,1,UserEvent(AgentSlacker,Agent: ${agent});
exten => slacker,n,NoOp(agent ${agent} is a slacker: ${reason});
; res_perl required. this notifies the phone (sip message) and an IRC bot
exten => slacker,n,Perl(notify_slacker:${agent}:${reason});
exten => slacker,n,Goto(agent_login,logout,1); log them off
;
exten => busy,1,Busy();
exten => t,1,Hangup();
exten => i,1,Congestion();

[macro-agent_answered]
exten => s,1,DBdel(AGENT/${ARG1}/bounces);
exten => s,2,DBdel(AGENT/${ARG1}/rejects);

[agent_avail]
; toggle available status
exten => s,1,Answer;
exten => s,2,ResponseTimeout(1);
exten => s,3,Wait(1);
exten => s,4,ResponseTimeout(1);
exten => s,5,Cut(mychan=CHANNEL,-,1);
exten => s,6,DBget(agent=AGENT/channelHasAgent/${mychan});
exten => s,107,Goto(login,1);
exten => s,7,DBget(stat=AGENT/${agent}/avail);
exten => s,8,GotoIf(${stat}?unavail,1:avail,1);
; set unavailable, you slacker
exten => unavail,1,DBput(AGENT/${agent}/avail=0);
exten => unavail,2,Playback(xm/agent-avail-no);
exten => unavail,3,UserEvent(AgentUnavailable,Agent: ${agent});
; set available
exten => avail,1,DBput(AGENT/${agent}/avail=1);
exten => avail,2,Playback(xm/agent-avail-yes);
exten => avail,3,UserEvent(AgentAvailable,Agent: ${agent});
; not logged in
exten => login,1,Playback(xm/agent-avail-login);
exten => login,2,Goto(agent_login,s,1)
;
exten => t,1,Hangup();
exten => i,1,Playback(xm/agent-avail-error);

[agent_moretime]
exten => s,1,Answer;
exten => s,2,ResponseTimeout(1);
exten => s,3,Wait(1);
exten => s,4,NoOp(agent needs more wrap up time);
exten => s,5,ResponseTimeout(1);
exten => s,6,Cut(mychan=CHANNEL,-,1);
exten => s,7,DBget(agent=AGENT/channelHasAgent/${mychan});
exten => s,108,Goto(login,1);
exten => s,8,DBput(AGENT/${agent}/wrapUpAt=$[${EPOCH} + ${WRAPUPTIME}]);
exten => s,9,Playback(xm/agent-moretime-ok);
exten => s,10,UserEvent(AgentMoreTime,Agent: ${agent}, Until: $[${EPOCH} + ${WRAPUPTIME}]);
;
exten => login,1,Playback(xm/agent-moretime-login);
exten => login,2,Goto(agent_login,s,1)
;
exten => t,1,Hangup();
exten => i,1,Playback(xm/agent-moretime-error);

[agent_login]
exten => s,1,Answer();
exten => s,2,Wait(1);
exten => s,3,ResponseTimeout(5);
exten => s,4,Cut(mychan=CHANNEL,-,1);
exten => s,5,DBget(agent=AGENT/channelHasAgent/${mychan});
exten => s,106,Goto(start,1);
exten => s,6,Goto(logout,1);
; a couple of read routines to get agent id
exten => start,1,Read(agent,xm/agent-login-user);
exten => start,2,Goto(verify,1);
exten => dupe,1,Read(continue,xm/agent-login-already-continue,1);
exten => dupe,2,GotoIf($["${continue}" = "1"]?3:4);
exten => dupe,3,Goto(logout,1);
exten => dupe,4,Read(agent,xm/agent-login-user);
exten => dupe,5,Goto(verify,1);
exten => bad,1,Read(agent,xm/agent-login-incorrect);
exten => bad,2,Goto(verify,1);
; verification
exten => verify,1,DBget(onchan=AGENT/${agent}/onChannel);
exten => verify,102,Goto(3);
exten => verify,2,GotoIf($["${onchan}" = "{mychan}"]?logout,1:dupe,1);
exten => verify,3,DBget(queues=AGENT/valid/${agent});
exten => verify,104,Goto(bad,1);
exten => verify,4,Goto(login,1);
; login routine
exten => login,1,DBput(AGENT/channelHasAgent/${mychan}=${agent});
exten => login,2,DBput(AGENT/${agent}/onChannel=${mychan});
exten => login,3,DBput(AGENT/${agent}/avail=1);
exten => login,4,SetVar(i=1);
exten => login,5,Cut(j=queues,:,${i});
exten => login,6,While($[${LEN(${j})} > 0]);
exten => login,7,AddQueueMember(${j},Local/${agent}@agent_call);
exten => login,8,SetVar(i=$[${i} + 1]);
exten => login,9,Cut(j=queues,:,${i});
exten => login,10,EndWhile;
exten => login,11,Playback(xm/agent-login-ok);
exten => login,12,Goto(t,1);
; logout, leave configured queues
exten => logout,1,DBget(queues=AGENT/valid/${agent});
exten => logout,2,SetVar(i=1);
exten => logout,3,Cut(j=queues,:,${i});
exten => logout,4,While($[${LEN(${j})} > 0]);exten => logout,5,RemoveQueueMember(${j},Local/${agent}@agent_call);
exten => logout,6,SetVar(i=$[${i} + 1]);
exten => logout,7,Cut(j=queues,:,${i});
exten => logout,8,EndWhile;
exten => logout,9,DBget(agentchan=AGENT/${agent}/onChannel);
;exten => logout,n,DBdel(AGENT/channelHasAgent/${mychan});
exten => logout,10,DBdel(AGENT/channelHasAgent/${agentchan});
exten => logout,11,DBdeltree(AGENT/${agent});
exten => logout,12,Playback(xm/agent-login-off,skip);
exten => logout,13,GotoIf($["${continue}" = "1"]?login,1); logging off a dupe, go back
exten => logout,14,Goto(t,1);
;
exten => t,1,Hangup;
exten => i,1,Playback(xm/agent-login-error);


You'll need these sound files (allison edits):
http://orbit.xmission.com/~kevin/agent-sounds.tar.gz
Created by: xkev, Last modification: Tue 11 of Sep, 2012 (00:36 UTC) by admin
Please update this page with new information, just login and click on the "Edit" or "Discussion" tab. Get a free login here: Register Thanks! - Find us on Google+