Appendix B: The [queuemetrics] context

QueueMetrics is able to trigger a number of advanced functionalities, like audio monitoring, clients logging in, going on pause, etc. right from the Asterisk dialplan.

You can check the current dialplan of a working Asterisk system from the Using the DbTest Diagnostic Tools page.

In order to make this portable and easy to understand, we suggest to create a special context named queuemetrics in your dialplan where QueueMetrics will trigger functions through a callfile. An example file that is ready-to-use for most call centres can be found under WEB-INF/mysql-utils/extensions-examples - see the included README file for more details.

Whenever an action is invoked by a logged-on user, the following variables are set at the channel level:

  • QM_LOGIN is the login of the current Qm user asking for the action to be performed

  • QM_CLASS is the current class the requesting user is in.

This makes it possible to perform addirtional security checks or auditing at the Asterisk level, but is not used by the supplied dialplan.

We therefore define a number of functions in the terms of extension relative to the context queuemetrics, as follows:

  • 10: Dummy extension
    Used only because a call-file requires two end-points in any case. Define as:

    exten => 10,1,Answer
    exten => 10,2,Wait(10)
    exten => 10,3,Hangup
  • 11: Remote monitoring
    This extension makes unattended monitoring of inbound traffic possible through the command ChanSpy(). The variables QM_AGENT_CODE, QM_EXT_MONITOR, QM_AGENT_EXT are set, as well as QM_CALLERID, QM_QUEUE and QM_QUEUE_URL. The following example explains how the feature works:

    exten => 11,1,Answer
    exten => 11,2,NoOp( "QM_AGENT_CODE: ${QM_AGENT_CODE}" )
    exten => 11,3,NoOp( "QM_EXT_MONITOR: ${QM_EXT_MONITOR}" )
    exten => 11,4,NoOp( "QM_AGENT_EXT: ${QM_AGENT_EXT}" )
    exten => 11,5,NoOp( "QM_LOGIN: ${QM_LOGIN}" )
    exten => 11,6,ChanSpy(${QM_AGENT_CODE})
    exten => 11,7,Hangup
this may have important security implications - see Listening to live calls: Unattended Call Monitoring.
  • 12: Call status code
    This extension logs a calls status code. The variables CALLSTATUS, CALLID, QM_LOGIN and AGENTCODE are defined. The following example explains how the feature works:

    exten => 12,1,Answer
    exten => 12,2,NoOp( "QM: Setting call status '${CALLSTATUS}' \
        on call '${CALLID}' for agent '${AGENTCODE}' made by '${QM_LOGIN}'" )
    exten => 12,3,System( echo "${EPOCH}|${CALLID}|NONE|Agent/${AGENTCODE} \
                 |CALLSTATUS|${CALLSTATUS}" >> /var/log/asterisk/queue_log )
    exten => 12,4,Hangup
  • 14: Remote monitoring of outgoing calls
    This extension makes unattended monitoring of outbound traffic possible through the command ChanSpy(). The variables QM_AGENT_CODE, QM_EXT_MONITOR and QM_AGENT_EXT are set, as well as QM_CALLERID, QM_QUEUE and QM_QUEUE_URL. The following example explains how the feature works:

    ; 14: Remote monitoring of outgoing calls - like SIP/callednumber
    exten => 14,1,Answer
    exten => 14,2,NoOp( "QM_AGENT_CODE: ${QM_AGENT_CODE}" )
    exten => 14,3,NoOp( "QM_EXT_MONITOR: ${QM_EXT_MONITOR}" )
    exten => 14,4,NoOp( "QM_AGENT_EXT: ${QM_AGENT_EXT}" )
    exten => 14,5,NoOp( "QM_CALLERID: ${QM_CALLERID}" )
    exten => 14,6,ChanSpy(SIP/${QM_CALLERID}|q)
    exten => 14,7,Hangup

    Please note that you should set the channels SIP/xxxx to the names of your local outgoing channel or the name of the local SIP leg of the call.

this may have important security implications - see Listening to live calls: Unattended Call Monitoring.
  • 16 and 17: Add/Remove call feature codes
    This extension pair adds or removes a call feature code. The variables FEATCODE, CALLID, AGENTCODE, QM_LOGIN and FEATTEXT are defined. The following example explains how the feature works:

    ; extension 16: set call status code
    exten => 16,1,Answer
    exten => 16,2,NoOp( "QM: Setting call feature '${FEATCODE}' on call '${CALLID}' for agent '${AGENTCODE}' made by '${QM_LOGIN}' with freetext ${FEATTEXT}" )
    exten => 16,3,System( echo "${EPOCH}|${CALLID}|NONE|Agent/${AGENTCODE}|INFO|FTR|${FEATCODE}|${FEATTEXT}" >> /var/log/asterisk/queue_log )
    exten => 16,4,Hangup
    
    ; extension 17: unset call status code
    exten => 17,1,Answer
    exten => 17,2,NoOp( "QM: Removing call feature '${FEATCODE}' on call '${CALLID}' for agent '${AGENTCODE}' made by '${QM_LOGIN}' with freetext ${FEATTEXT}" )
    exten => 17,3,System( echo "${EPOCH}|${CALLID}|NONE|Agent/${AGENTCODE}|INFO|NOFTR|${FEATCODE}|${FEATTEXT}" >> /var/log/asterisk/queue_log )
    exten => 17,4,Hangup
  • 20: Agent login
    This extension logs in a call-back agent. The variables AGENTCODE and AGENT_EXT are defined. Please note that for this to work properly, there must be no password set on the Asterisk agent. The following example explains how the feature works:

    exten => 20,1,Answer
    exten => 20,2,NoOp( "QM: Logging on Agent/${AGENTCODE} to \
                extension ${AGENT_EXT}@sip made by '${QM_LOGIN}'" )
    exten => 20,3,AgentCallBackLogin(${AGENTCODE}||${AGENT_EXT}@sip)
    exten => 20,4,Hangup
  • 21: Agent logoff
    This extension logs off an agent. The variable AGENTCODE is defined. The following example explains how the feature works:

    exten => 21,1,Answer
    exten => 21,2,NoOp( "QM: Logging off Agent/${AGENTCODE} \
                         made by '${QM_LOGIN}'")
    exten => 21,3,System(asterisk -rx "agent logoff Agent/${AGENTCODE}")
    exten => 21,4,Hangup
  • 22: Agent pause (with pause code)
    This extension pauses an agent and sets the pause code. The variables AGENTCODE and PAUSEREASON are defined. The following example explains how the feature works:

    exten => 22,1,Answer
    exten => 22,2,NoOp( "QM: Pausing Agent/${AGENTCODE} with pause \
                  reason '${PAUSEREASON}' made by '${QM_LOGIN}'" )
    exten => 22,3,PauseQueueMember(|Agent/${AGENTCODE})
    exten => 22,4,System( echo "${EPOCH}|${UNIQUEID}|NONE|Agent/${AGENTCODE} \
                 |PAUSEREASON|${PAUSEREASON}" >> /var/log/asterisk/queue_log )
    exten => 22,5,Hangup
  • 23: Agent unpause
    This extension unpauses an agent. The variable AGENTCODEis defined. The following example explains how the feature works:

    exten => 23,1,Answer
    exten => 23,2,NoOp( "QM: Unpausing Agent/${AGENTCODE} made by '${QM_LOGIN}' " )
    exten => 23,3,UnpauseQueueMember(|Agent/${AGENTCODE})
    exten => 23,4,Hangup
  • 24 and 25: Agent AddQueueMember
    These extensions (targeted to asterisk 1.2 the first, for asterisk 1.4 the second) dynamically add an agent to the specified queue. The variable AGENTCODE and QUEUENAME is defined. Only for the extension 25, the variables QM_AGENT_PRIOLBL and QM_AGENT_PRIONUM are set with the information related to agent priority in the queue: QM_AGENT_PRIOLBL could have the values U, M, W, S, respectively for agents not assigned in the queue, assigned as main, assigned as wrap, assigned as spill in the queue. The variable QM_AGENT_PRIONUM has the value 0 for agent not assigned in the queue or assigned as main in the queue, 1 for agents assigned as wrap, 2 for agents assigned as spill in the queue. The following example explains how the feature works:

    exten => 24,1,Answer
    exten => 24,2,NoOp( "QM: AddQueueMember (v1.2) Agent/${AGENTCODE} \
      on queue ${QUEUENAME} made by '${QM_LOGIN}'" )
    exten => 24,3,System( echo "${EPOCH}|${UNIQUEID}|${QUEUENAME} \
      |Local/${AGENTCODE}@from-internal|ADDMEMBER|" >> /var/log/asterisk/queue_log )
    exten => 24,4,Hangup
    
    exten => 25,1,Answer
    exten => 25,2,NoOp( "QM: AddQueueMember (v1.4+) Agent/${AGENTCODE} \
      on queue ${QUEUENAME} made by '${QM_LOGIN}' \
      with prioritylabel '${QM_AGENT_PRIOLBL}' and prioritynum '${QM_AGENT_PRIONUM}'" )
    exten => 25,3,AddQueueMember(${QUEUENAME}|Local/${AGENTCODE}@from-internal)
    exten => 25,4,Hangup
  • 26 and 27: Agent RemoveMember
    These extensions (targeted to asterisk 1.2 the first, for asterisk 1.4 the second) dynamically remove an agent to the specified queue. The variable AGENTCODE and QUEUENAME is defined. The following example explains how the feature works:

    exten => 26,1,Answer
    exten => 26,2,NoOp( "QM: RemoveQueueMember (v1.2) Agent/${AGENTCODE} \
      on queue ${QUEUENAME} made by '${QM_LOGIN}'" )
    exten => 26,3,System( echo "${EPOCH}|${UNIQUEID}|${QUEUENAME} \
      |Local/${AGENTCODE}@from-internal|REMOVEMEMBER|"  \
        >> /var/log/asterisk/queue_log )
    exten => 26,4,Hangup
    
    exten => 27,1,Answer
    exten => 27,2,NoOp( "QM: RemoveQueueMember (v1.4+) Agent/${AGENTCODE} \
      on queue ${QUEUENAME} made by '${QM_LOGIN}'" )
    exten => 27,3,RemoveQueueMember(${QUEUENAME}|Local/${AGENTCODE}@from-internal)
    exten => 27,4,Hangup
  • 28: Agent custom dial
    This extension lets able the agent to dial extensions through outbound queues from the agent’s live page. The variable AGENTCODE, EXTTODIAL, and OUTQUEUE is defined. Is possible to force a specific caller ID uncommenting the queue where the Set function is called and, obviously, changing the caller ID information to your needs. The following example explains how the feature works:

    exten => 28,1,Answer
    exten => 28,n,NoOp( "QM: Agent Custom Dial. Dialing ${EXTTODIAL} \
      on queue ${OUTQUEUE}  made by '${QM_LOGIN}'" )
    exten => 28,n,Set(QDIALER_QUEUE=${OUTQUEUE})
    exten => 28,n,Set(QDIALER_NUMBER=${EXTTODIAL})
    exten => 28,n,Set(QDIALER_AGENT=Agent/${AGENTCODE})
    exten => 28,n,Set(QDIALER_CHANNEL=SIP/${QDIALER_NUMBER})
    exten => 28,n,Set(QueueName=${QDIALER_QUEUE})
    exten => 28,n,MixMonitor(Q-${QDIALER_QUEUE}-${UNIQUEID}.WAV|b|)
    ;exten => 28,n,Set(CALLERID(all)="1234567890" <1234567890>) ; Uncomment and change this if you need to set your own caller ID
    exten => 28,n,Goto(qm-queuedial,s,1)
    exten => 28,n,Hangup
  • 29: Send SMS to agent’s phones
    This extension allows the users holding the proper key to send a short message to the agent’s phone from the realtime page. This feature is supported by Asterisk revision 10 and later versions and is disabled by default. Please note that this feature should be supported by the agent’s phone.

    exten => 29,1,NoOp( "QM: Send Text from Live Page. Sending text to ${EXTTODIAL} made by '${QM_LOGIN}' " )
    exten => 29,n,Set(MESSAGE(body)=From: ${QM_LOGIN} - ${MESSAGEBODY})
    exten => 29,n,MessageSend(sip:${EXTTODIAL})
    exten => 29,n,Hangup
  • 30: Hangup a live call
    This extension allows the users holding the proper key to send an hangup message to the PBX in order to hangup a live call from the realtime page.

    exten => 30,1,NoOp( "QM: Call Hangup made by ${QM_LOGIN} for callID: ${CALLID} with agent code ${AGENTCODE} from extension ${QM_AGENT_LOGEXT}")
    exten => 30,n,ChannelRedirect(${CALLID},queuemetrics,10,3)
    exten => 30,n,Hangup
  • 31: Redirect a live call
    This extension allows the users holind the proper key to send a transfer event to the PBX from the realtime page. This forces the live call to be transferred to a specified extension.

    exten => 31,1,NoOp( " QM: Call redirect ,ade by ${QM_LOGIN} for callID: ${CALLID} to extension ${REDIR_EXT}")
    exten => 31,n,ChannelRedirect(${CALLID},from-internal,${REDIR_EXT},1)
    exten => 31,n,Hangup
When using AddQueueMember/RemoveQueueMember to dynamically login/out to a queue is mandatory to match the agent code with their extension; eg. Agent/303 must be sitting at extension 303.
When using AddQueueMember/RemoveQueueMember to dynamically login/out to a queue the agent pause/unpause dialplan given must be changed to fit the current agent channels; eg. if Agent/303 is added to the queue as Local/\303@agents, the pause code specified in the dialplan must be changed to PauseQueueMember(|Local/\${AGENTCODE}@agents)

In order to trigger these functions, QueueMetrics need to be able to access the Asterisk callfile spool, as defined by the callfile.dir property.. If your Asterisk system is remote, you’ll have to arrange a periodic file transfer or use a disk share in order to make the above features work.

As an alternative, QueueMetrics may connect to a working Asterisk server over the Manager interface. See the description of the callfile.dir property for more information.