Since QueueMetrics 1.4.7, the retrieval of audio recordings uses a different paradigm called Pluggable Modules. This makes it feasible to set up different modules to match the configuration of the existing system and to use them natively.
Pluggable modules are used in two areas:
In order to control which module is called, two configuration properties are set:
Each configuration property is set to the complete name of a Java class that implements the required server. Such names must be set exactly as described, or an exception will be raised. Each module can then have its own configuration properties to control its own behaviour.
These PMs are used to find audio recordings.
| Module name: | LocalFiles |
|---|---|
Full Java Path: | it.loway.app.queuemetrics.callListen.listeners.LocalFiles |
Properties used: | default.monitored_calls in a single-server environment, or cluster.SERVER.monitored_calls in a cluster |
Available since: | 1.4.7 |
This is the standard search method that comes with QueueMetrics. Basically, all directories under default.monitored_calls are explored recursively, and all audio files matching the Asterisk ID of the main call that was queued are retrieved. Therefore the call files found can be zero or more.
This PM is sub-optimal for very large call centres, where the cost of scanning through all recordings (maybe on remotely mounted disks) could take a significant time. If you are in such an environment, see the LocalFilesByDay entry.
This PM is used by default if no other server is specified in the configuration.properties file.
| Module name: | LocalFilesByDay |
|---|---|
Full Java Path: | it.loway.app.queuemetrics.callListen.listeners.LocalFilesByDay |
Properties used: | default.monitored_calls in a single-server environment, or cluster.SERVER.monitored_calls in a cluster audio.lookBack for how many hours before or after midnight is a call considered a borderline case (default 4). |
Available since: | 1.4.7 |
This PM works exactly like the LocalFiles one, but allows using placeholders in the file path; this way, you can set the default recordings directory to handle only a subset of all recordings.
For example, if you set default.monitored_calls to /var/myrecordings/%YY-%MM/ when trying to listen to a call that was made on Jan 9, 2007 will expand to /var/myrecordings/2007-01/ therefore making the directory scanning much more manageable.
Valid placeholders include:
Though this is unlikely, it is possible that a call gets recorded on a given day and then gets queued on a different day, e.g. for calls that happen around midnight. QM handles this case by double-checking all calls within a boundary of n hours from the midnight in both the days that are divided by that midnight. This behaviour can be set using the audio.lookBack property.
Asterisk can easily adapt to recording files in a way that is compatible with this storage model, like e.g.:
. . . .
exten => 999,n,Set(MONITOR_FILENAME=/audio-nas/${STRFTIME(${EPOCH},,%Y-%m/%d)}/call-${UNIQUEID}.wav)
exten => 999,n,Queue(778,t,,)
. . . .Will store audio files as:
/audio-nas/2011-03/10/call-123456.7890.wav
The nice part is that Asterisk will automatically create missing directories, as needed.
| Module name: | ClassicXmlRpcRecordings |
|---|---|
Full Java Path: | it.loway.app.queuemetrics.callListen.listeners.ClassicXmlRpcRecordings |
Properties used: | default.audioRpcServer (non-clustered) or cluster.SERVER. audioRpcServer The address of the XML-RPC server implementing the QMAudio.findStoredFile interface. |
Available since: | 1.4.7 |
This is the standard XML-RPC implementation and makes it easy to create a completely custom scheme to handle recordings. The output of this function must be a single URL that can either stream the audio file or launch a player to stream that call. This is completely user-configurable.
The details of how to write an XML-RPC server for the QMAudio.findStoredFile interface can be found on the XML-RPC guide for QueueMetrics. We ship a sample implementation of such a server in the xmlrpc_audio_server.php server that comes with QueueMetrics.
See also section Section 23.11, “Enabling XML-RPC call listening and streaming”.
| Module name: | OrekaWeb |
|---|---|
Full Java Path: | it.loway.app.queuemetrics.callListen.listeners.OrekaWeb |
Properties used: | * oreka.jdbcUrl points to the server where the OrekaWeb database is stored. Firewalls and MySQL user setup must allow a JDBC connection coming from the QueueMetrics server. * oreka.sipHeader is the name of the tag to be tracked in the Oreka system. If missing, it’s X-Unique-ID. * oreka.web is the URL of an OrekaWeb application - QM uses Oreka’s applets for video playback. * oreka.playersize lets you set the size of the player, e.g. "1024x780" |
Available since: | 1.5.1 |
This PM lets you offline all the audio recording to an Oreka system - see http://oreka.sourceforge.net/
This PM lets you playback audio (and optionally video) of recorder calls stored in Oreka. In order to listen to live calls, it is possible tp use either some Asterisk-based method, e.g. ClassicQMListenerRT below, or an Oreka-based methos like OrekaWebRT below.
It needs the JDBC URI to point to the Oreka database; the database must contain the following tables: orktag, orksegment, orktape, orkservice, orktagtype.
| Warning | |
|---|---|
In order to have QueueMetrics associate the Asterisk call-ids correctly, you must configure Asterisk and Oreka to store the call-id of the main leg of the call, the one upon which the Queue() command is called. |
As Oreka is a passive recording solution based on SIP, and the call’s UniqueId is used to match a call in QueueMetrics, it is necessary for you to add the UniqueId information to the SIP headers.
If/how this can be done depends on the kind of channels you have as members of the queue.
If you have static or dynamic SIP phones as members of the queue, e.g.
[myQueue] .... member => SIP/1234 member => SIP/1235
you can simply use the following piece of dialplan:
....
exten => s,n,SIPAddHeader(X-Unique-ID: ${UNIQUEID})
exten => s,n,Queue(myQueue|t|30)
....If instead you have other types of channels as members of the queue, e.g.
[myQueue] .... member => Agent/101 member => Local/102@agents
then you need to store the UniqueID in an inherited variable, e.g.
...
exten => 411,2,Set(__MASTERID=${UNIQUEID})
exten => 411,3,Queue(myQueue|t|30)
[agents]
exten => _XXX,1,SipAddHeader(X-Unique-ID: ${MASTERID})
exten => _XXX,2,Dial(SIP/${EXTEN}|300)This makes it possible to use Oreka in all common usage scenarios.
You need to modify OrkAudio’s config.xml, under the <VoIpPlugin> section:
<SipExtractFields>X-Unique-ID</SipExtractFields>
And restart OrkAudio.
The minimal software you can use seems to be the commercial version (Orecx TR). This includes G729 Codec and Live Monitoring.
Orecx is able to capture and store along with the audio recording of the call a screen capture of the agent’s workstation while the call was made. The importance of such a feature is obvious.
If a video recording is present for a given call, then the audio file will be followed by the string "[vid]" to show that it’s a joint audio and video recording.
In order to play it back, QM will not stream it through a browser but will open up the VNC player that ships with OrkWeb; therefore you must configure the oreka.web property. The applet is not used in case of audio-only recordings.
| Module name: | MultiListener |
|---|---|
Full Java Path: | it.loway.app.queuemetrics.callListen.listeners.MultiListener |
Properties used: | ’audio.multi’ lets you define a set of PMs to be queried for files (enter their names, separated by pipe) ’audio.multi.*’ specifies the properties of each listener. |
Available since: | 1.7.0 |
This PM lets you query multiple PMs in the order you specify to look for the call you are looking for. A common scenario may be the following one:
In order to retrieve calls, we want QM to first check in /queues/audio; if nothing is found, then we will look under /mnt/nas/2010-11-23. This can be implemented with the following configuration:
# define the PM and the search order audio.server=it.loway.app.queuemetrics.callListen.listeners.MultiListener audio.multi=loc|nas # first PM: local calls audio.multi.loc=it.loway.app.queuemetrics.callListen.listeners.LocalFiles audio.multi.loc.default.monitored_calls=/queues/audio # second PM: NAS storage audio.multi.nas=it.loway.app.queuemetrics.callListen.listeners.LocalFilesByDay audio.multi.nas.default.monitored_calls=/mnt/nas/%YY-%MM-%DD
What we do here is the following:
These PMs are used to listen to live calls.
| Module name: | ClassicQMListenerRT |
|---|---|
Full Java Path: | it.loway.app.queuemetrics.callListen.RTlisteners.ClassicQMListenerRT |
Properties used: | For listening to inbound calls: callfile.monitoring.channel, callfile.monitoring.extension, callfile.monitoring.context; For listening to outbound calls: callfile.outmonitoring.channel, callfile.outmonitoring.extension, callfile.outmonitoring.context; In a single-server environment: callfile.dir (points to a local call-file directory or a manager interface port); In a clustered environment: cluster.SERVER.manager (points to each Asterisk servers manager interface port) |
Available since: | 1.4.7 |
This is the standard QM behaviour: when listening to inbound or outbound calls, a popup appears and asks for a local extension. That local extension is connected to the live channel so that the local user can listen to the ongoing call.
In order for this to work, the dial-plan on each Asterisk server must implement the correct logic - an example is given in the [queuemetrics] context that comes with QueueMetrics.
This PM is used by default if no other server is specified in the configuration.properties file.
| Module name: | ClassicXmlRpcListenerRT |
|---|---|
Full Java Path: | it.loway.app.queuemetrics.callListen.RTlisteners.ClassicXmlRpcListenerRT |
Properties used: | default.audioRpcServer (non-clustered) or cluster.SERVER. audioRpcServer The address of the XML-RPC server implementing the QMAudio.listenOngoingCalls interface. |
Available since: | 1.4.7 |
This is the standard XML-RPC implementation and makes it easy to create a completely custom scheme to handle live monitoring. The output of this function must be a single URL that will launch a player to stream that call. This is completely user-configurable.
The details of how to write an XML-RPC server for the QMAudio. listenOngoingCalls interface can be found on the XML-RPC guide for QueueMetrics. We ship a sample implementation of such a server in the xmlrpc_audio_server.php server that comes with QueueMetrics.
See also section Section 23.11, “Enabling XML-RPC call listening and streaming”
| Module name: | OrekaWebRT |
|---|---|
Full Java Path: | it.loway.app.queuemetrics.callListen.RTlisteners.OrekaWebRT |
Properties used: | oreka.rtserver is the master property that tells QM if Oreka is clustered or not oreka.web is the URL of an OrekaWeb application - QM uses Oreka’s applets for playback. oreka.rtserver.xxx is used for clustered configurations. |
Available since: | 1.5.2 |
This PM lets your supervisors monitor agents using a web-based interface provided by Oreka. The supervisors will simply click on a live call and it will be streamed to them through their browser (note: a window will open and will close immediately before the popup opens. This is expected behaviour).
In order for this PM to work, your system configuration must matche these criteria:
Do not forget to set the oreka.web property in any case in order to download the playback applet.
If you are deploying only one Oreka server, you should set the address of the live listening port by setting oreka.rtserver to fixed and then entering the live streaming port as follows:
oreka.rtserver=fixed oreka.rtserver.address=http://hostname:59120/?type=stream&localparty=#AGENTEXT#
This will work even on a clustered system, as long as there is only one Oreka server. Note how the agent extension is expanded in the string (see below for the full list of expansion tokens).
If you have a set of Oreka servers (likely because you have a cluster of Asterisk servers), you can associate a separate Oreka server to each box in the cluster. You do so by setting oreka.rtserver to cluster and then entering the live streaming port for each member of the cluster, as follows:
oreka.rtserver=cluster oreka.rtserver.aleph=http://ork_aleph:59120/?type=stream&localparty=#AGENTEXT# oreka.rtserver.beth=http://ork_beth:59120/?type=stream&localparty=#AGENTEXT#
In this example, all calls processed on server "aleph" will be searched on server "ork_aleph", while all calls processed on server "beth" will be processed on server "ork_beth".
If you have a set of Oreka servers that are not linked one-by-one to a set of Asterisk boxes, you can associate a separate Oreka server to each call in the cluster, by prepending a digit to the call’s UniqueID that will be used to know on which server each call is being handled. You do so by setting oreka.rtserver to chandigit and then entering the live streaming port for each member of the cluster, as follows:
oreka.rtserver=chandigit oreka.rtserver.1=http://ork_aleph:59120/?type=stream&localparty=#AGENTEXT# oreka.rtserver.2=http://ork_beth:59120/?type=stream&localparty=#AGENTEXT#
In this example, all calls which UniqueID starts wilth "1" will be handled by the "ork_aleph" server, and all calls which UniqueID start with "2" will be queries on the "ork_beth" server.