login | register
Fri 04 of Jul, 2008 [01:26 UTC]

voip-info.org

Search with Google
Search this site with Google. Results may not include recent changes.
 
Google Ads
Shoutbox
  • Samuel, Thu 03 of Jul, 2008 [13:41 UTC]: ok thank you
  • Mats Karlsson, Thu 03 of Jul, 2008 [13:37 UTC]: Nice Samuel, will look forward to rad it.
  • bwl_fernstudent, Thu 03 of Jul, 2008 [09:08 UTC]: Your blog shows some usefull code
  • Samuel, Thu 03 of Jul, 2008 [08:04 UTC]: I'll translate it, for sure
  • Mats Karlsson, Wed 02 of Jul, 2008 [20:46 UTC]: LOL, in french! Translate it to English and I will read it.
  • Samuel, Wed 02 of Jul, 2008 [08:07 UTC]: Hello, i wrote a blog about Asterisk, speaking about installation,programming and more http://sambranche.blogspot.com/
  • Nick Barnes, Tue 01 of Jul, 2008 [17:46 UTC]: Steve - Asterisk doesn't 'fit into linux' - it's an application which runs on top of Linux.
  • Steve, Mon 30 of Jun, 2008 [18:07 UTC]: anyone know where I can find a block diagram of how asterisk fits into linux. my f'ing bosses want me to draw something up.. ugh.
  • akbar, Fri 27 of Jun, 2008 [10:37 UTC]: marley_boyz@yahoo.com how to configure call forward, call back, call pick up using TDM and asterisk 1.2.13... please help me.. thx...
  • Matthew Williams, Tue 24 of Jun, 2008 [22:37 UTC]: We are looking for Tier II VoIP Support Technicians in St Louis. Send resumes to mwilliams AT voxitas DOT com.
Server Stats
  • Execution time: 0.27s
  • Memory usage: 2.20MB
  • Database queries: 29
  • GZIP: Disabled
  • Server load: 0.72

Agents without agent channel Asterisk 1.4 AEL

Motivated from Agents without agent channel I build a script to make agents available without agent channels working in Asterisk > 1.4.

Features:
  • agent login / logout
  • agent pause /unpause
  • answering a call sets agent in wrapuptime
  • agent can manuell exit wrapuptime when calling context agent_stats
  • automatic agent logoff after bouncing or rejecting calls
  • support for Flash Operation Panel (op_astdb.cfg)


put agents in queues like this on Asterisk CLI:
CLI> database put AGENT queues/111 consumer-pc:consumer-nb:akku
CLI> database put AGENT queues/222 consumer-pc:consumer-nb:akku 

setting up some global variables

globals {
// how often a gent trys to login with wrong agentnumber
   LoginAttempts = 2; 
   // how long a agent phone is ringing befor jump to the other agent (set timeout in queues.conf to 0)
   CallSeconds = 10;  
   // how often a agent can bounce a call bevor he gets kicked of the queue
   AllowedBounces = 3;
   // how often a agent can reject a call bevor he gets kicked of the queue
   AllowedRejects = 3;
   
}

sample extensions for agents to login/logout or set status of agent (pause unpause avail)
change extensionsto what ever you want

context agent_stuff {

 **1 => { goto agent_loginout|s|1; }
 **2 => { goto agent_stat|s|1; } 

}

context for agents to login or logout if they already logged in

context agent_loginout {

 s => {
 Wait(1);
Answer();
Set(TIMEOUT(response)=5);
Set(mychan=${CUT(CHANNEL,-,1)});


// if on this extension a agent already logged in -> logout
 if( ${DB_EXISTS(AGENT/channelHasAgent/${mychan})} ) 
{
Set(agent=${DB(AGENT/channelHasAgent/${mychan})});
NoOp(Agent schon angemeldet);
&AgentLogout(${agent});

}
  // if not go ahead with login
 else  
{
   NoOp(Kein Agent an Nebenstelle angemeldet);
   SET(LOOPCOUNT=1);
   SET(soundfile="agent-user"); 
begin: Read(agent,${soundfile});

// when agent is already logged in on other extensions -> logout
if( ${DB_EXISTS(AGENT/${agent}/onChannel)})
{
NoOp(Agent ist an Nebenstelle ${alreadyon} angemeldet);
Playback(custom/agent-alreadyon-getoff);
&AgentLogout(${agent});
}
// go ahead with agent login
else
{
// if agent is member of queue
if( ${DB_EXISTS(AGENT/queues/${agent})})
{
&AgentLogin(${mychan},${agent});
}
// if agent is not member of queue (give him ${LoginAttemps})
else
{
NoOp(Agent ist kein Agent);
while (${LOOPCOUNT} < ${LoginAttempts}) {
           LOOPCOUNT=${LOOPCOUNT}+1;
           SET(soundfile="agent-incorrect"); 
           goto begin;       
        } 
        Playback(pbx-invalid);
      }
}
goto t|1;
}
 }
 t => Hangup;
 i => Playback(pbx-invalid);
}

context to set Status of agent (pause or avail)

context agent_stat {

s => {
   Wait(1);
Answer();
Set(TIMEOUT(response)=5);
Set(mychan=${CUT(CHANNEL,-,1)});

// if valid agent is on extension logged in
if( ${DB_EXISTS(AGENT/channelHasAgent/${mychan})} )
{
Set(agent=${DB(AGENT/channelHasAgent/${mychan})});
     &AgentStat(${agent});
   }
// if no agent is logged in on extension
else
{
NoOp (Error);
goto i|1;
}
goto t|1;
 }
 t => Hangup;
 i => Playback(pbx-invalid);
}

context to call agent

context agent_call {

 _X. => {
 
  Set(agent=${EXTEN});
  Set(mychan=${DB(AGENT/${agent}/onChannel)});
  if(${DB(AGENT/${agent}/stat)} = avail )
   {
     Set(_ALERT_INFO=queue);
     UserEvent(QueueCall|Queue: ${queue});
     Dial(${mychan}|${CallSeconds}|M(AgentAnswered^${agent}));
     &AgentSlacker(${agent},${DIALSTATUS});
   }
   else
   {
    Busy();
    goto t|1;
   }

 
 }
 
 t => Hangup();
 i => Congestion();

}


macro for agents to login

macro AgentLogin(mychan,agent) {

  Set(queues=${DB(AGENT/queues/${agent})});
  Set(DB(AGENT/channelHasAgent/${mychan})=${agent});
  Set(DB(AGENT/${agent}/onChannel)=${mychan});
  Set(DB(AGENT/${agent}/bounces)=0);
  Set(DB(AGENT/${agent}/rejects)=0);
  Set(DB(AGENT/${agent}/stat)=avail);
  Set(i=1);
  Set(j=${CUT(queues,:,${i})});
  NoOP(Start);
  
  while ( ${LEN(${j})} > 0 ) {
    AddQueueMember(${j},Local/${agent}@agent_call);
    Set(i=$${i} + 1);
Set(j=${CUT(queues,:,${i})});
  }
  
  
  // UserEvent for Flash Operation Panel 
  UserEvent(ASTDB|Channel: ${mychan}^Family: AgentAvail^Value: ${agent} avail);
  Playback(agent-loginok);

}

macro for agents to logout

macro AgentLogout(agent) {
  Set(queues=${DB(AGENT/queues/${agent})});

  Set(i=1);
  Set(j=${CUT(queues,:,${i})});
  
  while ( ${LEN(${j})} > 0 ) {
     RemoveQueueMember(${j},Local/${agent}@agent_call);
     Set(i=$${i} + 1);
Set(j=${CUT(queues,:,${i})});
  } 
  
  Set(agentchan=${DB(AGENT/${agent}/onChannel)});
  Set(oldval=${DB_DELETE(AGENT/channelHasAgent/${agentchan})});
  DBdeltree(AGENT/${agent}); 
  Set(number=${CUT(agentchan,/,2)});
  UserEvent(ASTDB|Channel: ${agentchan}^Family: AgentLogout^Value: ${number});
  Playback(agent-loggedoff);
  Hangup;
}

macro to put agent in stat pause and avail

macro AgentStat(agent) {

set(stat=${DB(AGENT/${agent}/stat)});
switch (${stat})
{
case pause: // if agent is in pause set him to avail
set(DB(AGENT/${agent}/stat)=avail);
        UnPauseQueueMember(|Local/${agent}@agent_call);
        UserEvent(ASTDB|Channel: ${mychan}^Family: AgentAvail^Value: ${agent} avail);
        Playback(custom/online);
   break;
   case avail:  // if agent is avail set him in pause
        set(DB(AGENT/${agent}/stat)=pause);
        PauseQueueMember(|Local/${agent}@agent_call);
        UserEvent(ASTDB|Channel: ${mychan}^Family: AgentPause^Value: ${agent} pause);
        Playback(custom/offline);
break;
case wrapup: // if agent is in wrapup set him to avail
        set(DB(AGENT/${agent}/stat)=avail);
        UserEvent(ASTDB|Channel: ${mychan}^Family: AgentAvail^Value: ${agent} avail);
        Playback(custom/online);
break;
}
}


this macro is called from context agent_call
it handle agents who are not answering calls or reject calls
after ${AllowedBounce} times, a agent get kicked of the queues
after ${AllowedRejects} times, a agent get kicked of the queues

macro AgentSlacker(agent,dialstatus) {

switch (${dialstatus})
{
case BUSY: // agent rejects a call
set(rejects=${DB(AGENT/${agent}/rejects)});
        set(rejects=$${rejects} + 1);
        set(DB(AGENT/${agent}/rejects)=${rejects});
        if(${rejects} >= ${AllowedRejects}) {
          set(reason= 3 Rufe abgewiesen ); 
          break;
        }  
        else Hangup;
       
break;
case NOANSWER: // agent bounced a call
        set(bounces=${DB(AGENT/${agent}/bounces)});
        set(bounces=$${bounces} + 1);
        set(DB(AGENT/${agent}/bounces)=${bounces});
        if(${bounces} >= ${AllowedBounces}) { 
          set(reason= 3 Rufe nicht beantwortet);
          break;
        }
        else Hangup;
break;
}
 UserEvent(AgentSlacker,Agent: ${agent});
 NoOp(agent ${agent} is a slacker: ${reason});
 Set(queues=${DB(AGENT/queues/${agent})});
 Set(i=1);
 Set(j=${CUT(queues,:,${i})});
 
 while ( ${LEN(${j})} > 0 ) {
    RemoveQueueMember(${j},Local/${agent}@agent_call);
    Set(i=$${i} + 1);
Set(j=${CUT(queues,:,${i})});
 }
 
 Set(agentchan=${DB(AGENT/${agent}/onChannel)});
 Set(oldval=${DB_DELETE(AGENT/channelHasAgent/${agentchan})});
 DBdeltree(AGENT/${agent}); 
 
}

this macro is called when a agent is answering a call
it sets ${AllowedBounces} and ${AllowedRejects} back to 0
the agent is set to stat wrapup and can not be called even he has finish the called
to get stat avail again call macro AgentStat 

macro AgentAnswered(agent) {
 set(DB(AGENT/${ARG1}/bounces)=0);
 set(DB(AGENT/${ARG1}/rejects)=0);
 set(DB(AGENT/${ARG1}/stat)=wrapup);
 set(mychan=${DB(AGENT/${ARG1}/onChannel)});
 UserEvent(AgentUnavailable|Agent: ${ARG1});
 UserEvent(ASTDB|Channel: ${mychan}^Family: AgentWrapup^Value: ${agent} Nacharbeit);
}



the following file sets up the Flash Operation Panel to shpw status of Agents

op_astdb.cfg:


[AgentAvail]
settext= ${value}
flip=1
fopledcolor=0xD0d020
setlabel=Agent

[AgentLogout]
settext= ${value}
flip=1
fopledcolor=0x00A000
setlabel= ${value}

[AgentWrapup]
settext= ${value}
fopledcolor=0xA01020

[AgentPause]
settext= ${value}
flip=1
fopledcolor=0x0000c0

[AgentSlacker]
settext= ${value}
flip=1
fopledcolor=0x000000







Created by Sven, Last modification by Sven on Tue 13 of May, 2008 [11:42 UTC]

Please update this page with new information, just login and click on the "Edit" or "Add Comment" button above. Get a free login here: Register Thanks! - support@voip-info.org

Page Changes | Comments

Sponsored by:

Terms of Service Privacy Policy
© 2003-2008 VOIP-Info.org LLC

Powered by bitweaver