Improved on agent-add, agent-del plus logging with queue_log

I posted this information in the TRAC first which I probably should have posted here first.

My objective was to make a simpler solution for Queue management. Since it is now only a single macro it can be assigned a function key on a phone and allow simple removal and addition of members to the queue.

Please share your concerns and recommendations.

http://freepbx.org/trac/ticket/1949

I would like to have this reviewed and critiqued.

Queue Log Function

QueueLog?(queuename,uniqueid,agent,event,params):

Allows you to write your own events into the queue log

[list]QueueLog?(101,${UNIQUEID},${AGENT},WENTONBREAK,600)[/list:u]
http://bugs.digium.com/view.php?id=7368

Dynamic Members Extension

Add the following line to enable the agent-manage macro for a queue into your extensions configuration file.

[list]exten => 1234*,1,Macro(agent-manage,1234,)[/list:u]
Dynamic Members Macros

Add the appropriate macro for your needs and version of asterisk into your macros configuration file.

Dynamically Manage Agents/Members and log Time-In-Queue (Asterisk 1.4)

Adds or removes a dynamic member to the queue and logs the time in queue in seconds to /var/log/asterisk/queue_log.

[code:1]
; Adds or removes a dynamic agent/member for a queue and logs Time-In-Queue
; arg1 = queue number, arg2 = number
[macro-agent-manage]
exten => s,1,Wait(1)
exten => s,2,Macro(user-callerid)
exten => s,3,Set(CALLBACKNUM=${CALLERID(number)})
exten => s,4,GotoIf($["${CALLBACKNUM}" = “”]?116)) ; if no number, jump to fail.
exten => s,5,AddQueueMember(${ARG1}|Local/${CALLBACKNUM}@from-internal/n||j) ; using chan_local allows us to have agents over trunks
exten => s,6,QueueLog(${UNIQUEID},${ARG1},${CALLBACKNUM},AGENTLOGIN,0)
exten => s,7,Set(DB(agentlogin/q_${ARG1}a${CALLBACKNUM})=${EPOCH})
exten => s,8,UserEvent(Agentlogin|Agent: ${CALLBACKNUM})
exten => s,9,Wait(1)
exten => s,10,Playback(agent-loginok)
exten => s,11,Hangup()
exten => s,106,RemoveQueueMember(${ARG1}|Local/${CALLBACKNUM}@from-internal/n)
exten => s,107,UserEvent(RefreshQueue)
exten => s,108,Set(ORGEPOCH=${DB(agentlogin/q_${ARG1}a${CALLBACKNUM})})
exten => s,109,Set(LGNT=$[${EPOCH} - ${ORGEPOCH}])
exten => s,110,GotoIf($["${LGNT}" = “0”]?116:111)
exten => s,111,QueueLog(${UNIQUEID},${ARG1},${CALLBACKNUM},AGENTLOGOFF,${LGNT})
exten => s,112,DBdel(agentlogin/q_${ARG1}a${CALLBACKNUM})
exten => s,113,Wait(1)
exten => s,114,Playback(agent-loggedoff)
exten => s,115,Hangup()
exten => s,116,Playback(sorry-cant-let-you-do-that) ; Catch error and give simple notification.
exten => s,117,Hangup()
[/code:1]

Dynamically Manage Agents/Members and log Time-In-Queue (Asterisk 1.2)

Adds or removes a dynamic member to the queue and logs the time in queue in seconds to /var/log/asterisk/queue_log.

[code:1]
; Adds or removes a dynamic agent/member for a queue and logs Time-In-Queue
; arg1 = queue number, arg2 = number
[macro-agent-manage]
exten => s,1,Wait(1)
exten => s,2,Macro(user-callerid)
exten => s,3,Set(CALLBACKNUM=${CALLERID(number)})
exten => s,4,GotoIf($["${CALLBACKNUM}" = “”]?116)) ; if no number, jump to fail.
exten => s,5,AddQueueMember(${ARG1}|Local/${CALLBACKNUM}@from-internal/n) ; using chan_local allows us to have agents over trunks
exten => s,6,QueueLog(${UNIQUEID},${ARG1},${CALLBACKNUM},AGENTLOGIN,0)
exten => s,7,Set(DB(agentlogin/q_${ARG1}a${CALLBACKNUM})=${EPOCH})
exten => s,8,UserEvent(Agentlogin|Agent: ${CALLBACKNUM})
exten => s,9,Wait(1)
exten => s,10,Playback(agent-loginok)
exten => s,11,Hangup()
exten => s,106,RemoveQueueMember(${ARG1}|Local/${CALLBACKNUM}@from-internal/n)
exten => s,107,UserEvent(RefreshQueue)
exten => s,108,Set(ORGEPOCH=${DB(agentlogin/q_${ARG1}a${CALLBACKNUM})})
exten => s,109,Set(LGNT=$[${EPOCH} - ${ORGEPOCH}])
exten => s,110,GotoIf($["${LGNT}" = “0”]?116:111)
exten => s,111,QueueLog(${UNIQUEID},${ARG1},${CALLBACKNUM},AGENTLOGOFF,${LGNT})
exten => s,112,DBdel(agentlogin/q_${ARG1}a${CALLBACKNUM})
exten => s,113,Wait(1)
exten => s,114,Playback(agent-loggedoff)
exten => s,115,Hangup()
exten => s,116,Playback(sorry-cant-let-you-do-that) ; Catch error and give simple notification.
exten => s,117,Hangup()
[/code:1]

Dynamically Manage Agents/Members (Asterisk 1.4)

Adds or removes a dynamic member to the queue.

[code:1]
; Adds or removes a dynamic agent/member for a queue
; arg1 = queue number, arg2 = number
[macro-agent-manage]
exten => s,1,Wait(1)
exten => s,2,Macro(user-callerid)
exten => s,3,Set(CALLBACKNUM=${CALLERID(number)})
exten => s,4,GotoIf($["${CALLBACKNUM}" = “”]?111)) ; if no number, jump to fail.
exten => s,5,AddQueueMember(${ARG1}|Local/${CALLBACKNUM}@from-internal/n||j) ; using chan_local allows us to have agents over trunks
exten => s,6,UserEvent(Agentlogin|Agent: ${CALLBACKNUM})
exten => s,7,Wait(1)
exten => s,8,Playback(agent-loginok)
exten => s,9,Hangup()
exten => s,106,RemoveQueueMember(${ARG1}|Local/${CALLBACKNUM}@from-internal/n)
exten => s,107,UserEvent(RefreshQueue)
exten => s,108,Wait(1)
exten => s,109,Playback(agent-loggedoff)
exten => s,110,Hangup()
exten => s,111,Playback(sorry-cant-let-you-do-that) ; Catch error and give simple notification.
exten => s,112,Hangup()
[/code:1]
Dynamically Manage Agents/Members (Asterisk 1.2)

Adds or removes a dynamic member to the queue.

[code:1]
; Adds or removes a dynamic agent/member for a queue
; arg1 = queue number, arg2 = number
[macro-agent-manage]
exten => s,1,Wait(1)
exten => s,2,Macro(user-callerid)
exten => s,3,Set(CALLBACKNUM=${CALLERID(number)})
exten => s,4,GotoIf($["${CALLBACKNUM}" = “”]?111)) ; if no number, jump to fail.
exten => s,5,AddQueueMember(${ARG1}|Local/${CALLBACKNUM}@from-internal/n) ; using chan_local allows us to have agents over trunks
exten => s,6,UserEvent(Agentlogin|Agent: ${CALLBACKNUM})
exten => s,7,Wait(1)
exten => s,8,Playback(agent-loginok)
exten => s,9,Hangup()
exten => s,106,RemoveQueueMember(${ARG1}|Local/${CALLBACKNUM}@from-internal/n)
exten => s,107,UserEvent(RefreshQueue)
exten => s,108,Wait(1)
exten => s,109,Playback(agent-loggedoff)
exten => s,110,Hangup()
exten => s,111,Playback(sorry-cant-let-you-do-that) ; Catch error and give simple notification.
exten => s,112,Hangup()
[/code:1]
FreePBX

The above macros are based on macros from the FreePBX front-end to Asterisk. If you choose to implement any of the above macros and are using FreePBX I recommend doing some additional cleanup.

  • Remove all references to agent-add and agent-del in extensions_additional.conf as agent-manage will now facilitate this.

[code:1]
exten => 1234*,1,Macro(agent-add,1234,)
exten => 1234**,1,Macro(agent-del,1234,1234)
[/code:1]

  • Remove agent-add and agent-del from extension.conf as agent-manage will now facilitate this.

    [macro-agent-add] [macro-agent-del]

Fixed 116 to 111

I have that in the macro for 1.2 because there is a patch available.

But you are correct the macro with the logging will most likely be to customized for a freepbx distribution. What it actually logs though is Time in Queue and this is not currently recorded by 1.2 or 1.4.

also - unless I am mistaken, Queuelog() is not a 1.2 feature (I just checked on a 1.2.18 system and it is not present.) With few exceptions we avoid the use of anything that requires a patch. And … I thought the Agent login/logoff’s were already logged to the queue log.

I’ll have to take a closer look but as mentioned in the ticket, what about when there is no callerid available?

If there is no caller id available it will fail to this line of code

exten => s,116,Playback(sorry-cant-let-you-do-that) ; Catch error and give simple notification.

I would assume we could insert the old code from add-agent here instead.

Which I just realized there is an error on the macros without logging the gotoif needs to be changed to 111 rather than 116

P.S thanks for coping over my content.