QueueMetrics forum

QueueMetrics => Running QueueMetrics => Topic started by: bhenry on November 10, 2010, 17:14:21

Title: FreePBX(AsteriskNow) transfer
Post by: bhenry on November 10, 2010, 17:14:21
I moved to AsteriskNow(FreePBX) 1.6 recently from a plain Asterisk 1.4 installation.  In 1.4, a transfer showed up in the queue log.  On my new system, FreePBX + 1.6, there is no record of Transfer in Queue Logs. 

Is anyone using FreePBX with Asterisk 1.6 with transfers reporting correctly?

Thanks!
-Brendan
Title: Re: FreePBX(AsteriskNow) transfer
Post by: moa on November 10, 2010, 17:45:14
How interesting, I came in here to ask a similar question. Today must be the day to work on transfer issues.  ;D

I've been running asterisk 1.6(source) for quite some time and techs haven't been able to transfer until I added the stateextension column into the database(I'm using REALTIME for queue_members) and changed a few things in the GUI our agents use to login.  This solved my issue with agents channels being "In Use" after the transfer. Now my problem is the queue stats continue to grow until the transferred call is hung up.  Has anyone ran into this issue and know how to solve it?


P.S. Sorry for hijacking this thread.  Since these issues seem very closely related, I'm hoping someone can provide us both with a little insight on asterisk 1.6 and transfers.
Title: Re: FreePBX(AsteriskNow) transfer
Post by: bhenry on November 10, 2010, 23:07:44
Hmm I don't think your solution will work for me because my endpoints are remote numbers and not actual devices connected to Asterisk. 

This is why I think the DevState doesn't help.  Regarding your issue, do you see a TRANSFER record in your queue_log?

Sigh maybe my solution is upgrading to 1.8?
Title: Re: FreePBX(AsteriskNow) transfer
Post by: bhenry on November 10, 2010, 23:25:35
Also I was under the impression that extension state was patched to 1.4 but that it does not exist in 1.6?
Title: Re: FreePBX(AsteriskNow) transfer
Post by: moa on November 10, 2010, 23:30:16
No, a TRANSFER record never shows up in the queue_log.  It did prior to use extension state but stopped once I enabled it.

AFAIK the extension state was created in 1.6 and they back ported it to 1.4.

I attempted a upgrade to 1.8 a few days ago and IMHO it didn't seem very stable.  I was going to wait until a few minor revisions are released to clear up some of the release bugs.
Title: Re: FreePBX(AsteriskNow) transfer
Post by: bhenry on November 11, 2010, 20:24:20
hmm maybe I just don't understand extension state.  Granted I am not using realtime queues.  Are you using static or dynamic agents?  Is extension state where you are adding a hint to the end of queue membership? like this:
member => Local/3000@default,0,John Smith,HINT:3000@default

Currently with my setup I get no TRANSFER records in queue_log either.  Also I have the issue where agents remain "In Use" after a transfer.
Title: Re: FreePBX(AsteriskNow) transfer
Post by: moa on November 11, 2010, 21:11:40
I'm using dynamic agents, so my queue member association comes out of mysql.  Here's what the table looks like (Sorry I'm not sure how to do it statically in agents.conf):

Code: [Select]

mysql> describe queue_member_table;
+-----------------+------------------+------+-----+---------+----------------+
| Field           | Type             | Null | Key | Default | Extra          |
+-----------------+------------------+------+-----+---------+----------------+
| uniqueid        | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| membername      | varchar(40)      | YES  |     | NULL    |                |
| queue_name      | varchar(128)     | YES  | MUL | NULL    |                |
| interface       | varchar(128)     | YES  |     | NULL    |                |
| penalty         | int(11)          | YES  |     | NULL    |                |
| paused          | int(11)          | YES  |     | NULL    |                |
| state_interface | varchar(128)     | YES  |     | NULL    |                |
+-----------------+------------------+------+-----+---------+----------------+
7 rows in set (0.01 sec)

When an agent logs in, I'm putting a row like this into the table:
Code: [Select]
+----------+--------------------+------------+--------------------+---------+--------+-----------------+
| uniqueid | membername         | queue_name | interface          | penalty | paused | state_interface |
+----------+--------------------+------------+--------------------+---------+--------+-----------------+
|   223008 | Agent/106         | TEST        | local/106@agents/n |       1 |   NULL | SIP/157         |
+----------+--------------------+------------+--------------------+---------+--------+-----------------+

My @agents context does a database lookup to find what sip extension agent 106 is sitting at and dials their phone.

By adding the state interface it tells asterisk to check the state of the sip extension rather than looking at the local channel for agent availability.  This solved my "In Use" issue after the agent transferred a call.

What I've found out about the TRANSFER event not showing up in the queue_log is that since I'm using local channels, asterisk doesn't complete the queue_log entry for the call until the transferred call is completed.

For example:
Caller comes into QueueA : ENTERQUEUE is put in the queue_log
QueueA rings Agent/106 : CONNECT is put in the queue_log
Agent/106 transfers to Agent/107 : Nothing is put in the queue_log, asterisk changes state of Agent/106 from "In use" to "Available"
Agent/107 completes call with Caller : COMPLETEDBYAGENT(Agent/106) is entered in queue_log.

This all seems like an asterisk bug to me (or maybe a feature??).

One solution I've come up with but not implemented is creating my own transfer dialplan.  A dialplan where I inserted the needed TRANSFER event into the queue_log. If I do this though, asterisk will still place into the database it's COMPLETEDBYAGENT row with the same callid.  
How would Queuemetrics handle that? ??? ???

I was hoping I could get some answers on this,  we are currently billing one of our customers per minute. Long untracked transferred call times is causing their bill to go through the roof.  Good for us, not so god for them..
Title: Re: FreePBX(AsteriskNow) transfer
Post by: QueueMetrics on November 15, 2010, 10:28:41
You should be checking whether a TRANSFER record gets created or not,. If it does not, QM has no way of knowing that a transfer was made. This usually works reliably only for unattended transfers that are run by the queue() app; some say they got it with telephones as well, but it is not reliable.
Title: Re: FreePBX(AsteriskNow) transfer
Post by: bhenry on November 15, 2010, 21:22:59
Is there any way to force or fake a TRANSFER record?
Title: Re: FreePBX(AsteriskNow) transfer
Post by: moa on November 15, 2010, 23:21:28
Is there any way to force or fake a TRANSFER record?

Since QueueMetrics didn't answer me. ;)  I'm going to write up some dialplan and test this very thing.  I'll let everyone know of my findings.

Title: Re: FreePBX(AsteriskNow) transfer
Post by: QueueMetrics on November 16, 2010, 17:12:23
QM would happily process that correctly :)
Title: Re: FreePBX(AsteriskNow) transfer
Post by: moa on November 16, 2010, 19:36:49
 ;D

It can be done!

Since it is close to impossible to find any decent information on this.  I'm going to explain how I solved it here.
*Warning* This may be a lengthy post, so to keep it short I've taken out anything that doesn't pertain to this issue in my dialplan. Also, all dialplan will be in AEL syntax.

First off, in order to successfully accomplish this we need a few channel variables that aren't in the new transferred channel.  We need the AgentID, the asterisk Call ID, and our Queue the call is coming from.

In my setup, when a call comes in, I'm setting two inherent channel variable:
Code: [Select]
context queues-inbound{
XXXX =>{
Set(_CALLID=${UNIQUEID});
Set(_QUEUENAME=test);
Queue(test,t);
}
}

Now my agents are logged into the queues via local channels:
Code: [Select]
queues*CLI> queue show test
test has 0 calls (max unlimited) in 'leastrecent' strategy (3s holdtime, 96s talktime), W:0, C:12, A:4, SL:100.0% within 120s
   Members:
      local/1234@agents/n with penalty 1 (realtime) (Not in use) has taken no calls yet

When the agent is dialed another inherent variable is set:
Code: [Select]
context agents {
_. => {
Set(_AGENTTHATTRANSFERED=${EXTEN});
...
// doing a mysql database lookup to get Agents SIP Extension
...
Dial(SIP/${AGENT_EXTENSION});
}
}

Hope everyone is following thus far. Just a few more steps  ;)

Here is what the queue_log looks like at this point:

Code: [Select]
+---------+------------+------------------+-----------+-------------------+---------------+------------------------------+
| id      | time       | callid           | queuename | agent             | event         | data                         |
+---------+------------+------------------+-----------+-------------------+---------------+------------------------------+
| 1194627 | 1289929044 | 1289929028.30773 | test      | NONE              | ENTERQUEUE    | |XXXXXXXXXX_1289929028.30773 |
| 1194629 | 1289929048 | 1289929028.30773 | test      | local/1234@agents/n| CONNECT       | 4|1289929045.30777|3       |


I've instructed our agents to use a specific line extension when transferring.  For this example, I'm going to use line 6.

Code: [Select]
context agents-transferred {
_6. => {
NoOp("Current UniqueID: ${UNIQUEID}");
NoOp("inherited callid: ${CALLID}");
NoOp("inherited agendid: ${AGENTTHATTRANSFERED}");
NoOp("inherited queuename: ${QUEUENAME}");
MYSQL(Connect connid localhost UN PW asterisk_database);
if(${connid} = ""){
Playback(tt-error);
Hangup();
}else{
// make the query to track it
MYSQL(Query resultid ${connid} INSERT into transferred_calls(callid,full_extension) values('${CALLID}','${EXTEN}'));
// disconnect
MYSQL(Disconnect ${connid});
// now enter in our queue log
QueueLog(${QUEUENAME},${CALLID},local/${AGENTTHATTRANSFERED}@agents/n,TRANSFER,${EXTEN:1});
// dial the transferred extesion
Dial(SIP/${EXTEN:1});
};
if(${connid}){
MYSQL(Disconnect ${connid});
};
Hangup();
};
}

Now once the call gets to here.  Here is what the queue_log looks like (agent transferred to sip extension 299):
Code: [Select]
+---------+------------+------------------+-----------+-------------------+---------------+------------------------------+
| id      | time       | callid           | queuename | agent             | event         | data                         |
+---------+------------+------------------+-----------+-------------------+---------------+------------------------------+
| 1194627 | 1289929044 | 1289929028.30773 | test      | NONE              | ENTERQUEUE    | |XXXXXXXXXX_1289929028.30773 |
| 1194629 | 1289929048 | 1289929028.30773 | test      | local/1234@agents/n| CONNECT       | 4|1289929045.30777|3       |
| 1194642 | 1289929161 | 1289929028.30773 | test      | local/1234@agents/n | TRANSFER      | 299                     |


QueueMetrics is happy at this point.  Transferred calls are calculated correctly. 

But wait
Here's what the queue_log looks like AFTER the transferred call is completed:

Code: [Select]
+---------+------------+------------------+-----------+-------------------+---------------+------------------------------+
| id      | time       | callid           | queuename | agent             | event         | data                         |
+---------+------------+------------------+-----------+-------------------+---------------+------------------------------+
| 1194627 | 1289929044 | 1289929028.30773 | test      | NONE              | ENTERQUEUE    | |XXXXXXXXXX_1289929028.30773 |
| 1194629 | 1289929048 | 1289929028.30773 | test      | local/1234@agents/n| CONNECT       | 4|1289929045.30777|3       |
| 1194642 | 1289929161 | 1289929028.30773 | test      | local/1234@agents/n | TRANSFER      | 299                     |
| 1194650 | 1289929253 | 1289929028.30773 | test      | local/1234@agents/n | COMPLETEAGENT | 5|204|1                      |

QueueMetrics doesn't like this because of the last entry(COMPLETEAGENT).  So if you see above where I created my own database table called transferred_calls and placed the transfer information into it(agents-transferred context).  I have a cronjob running every 5 minutes to check this table for anything new, if there is a new transferred call.  It grabs the callid and deletes the offending row out of the queue_log.

QueueMetrics is happy, boss is happy, customers are happy!

This is currently working in my lab and I'm about to push it all into production.

Please comment and let me know what everyone thinks.  Suggestions, bug fixes, and typo's are all welcome.
Title: Re: FreePBX(AsteriskNow) transfer
Post by: QueueMetrics on November 17, 2010, 09:46:02
It can be done!

This sounds a bit like Frankenstein Jr. :-) but.... chapeau!

Excellent work!

I would do the following changes:
1. write to the queue_log file, so that it is uploaded by qloaderd and it is easy to restore.
2. In QM , TRANSFER is a call-closure record. But you could do:

Code: [Select]
ENTERQUEUE on queue A
CONNECT on queue A
TRANSFER on queue A
ENTERQUEUE on queue "A-transfers"
CONNECT on queue "A-transfers"
AGENTCOMPLETE on queue "A-transfers"

When you output the TRANSFER you output both other records. In QM these are two queue "legs" that can be analyzed together or separately.








QueueMetrics
Title: Re: FreePBX(AsteriskNow) transfer
Post by: QueueMetrics on November 18, 2010, 14:31:32
It can be done!

Do you mind if we add this to the Advanced Configuration manual? with proper credits, of course! :)
Title: Re: FreePBX(AsteriskNow) transfer
Post by: moa on November 19, 2010, 18:16:59
This sounds a bit like Frankenstein Jr. :-) but.... chapeau!

It's what I do best :)

Do you mind if we add this to the Advanced Configuration manual? with proper credits, of course! :)

I don't mind at all.  I'm just glad that I got it all working  ;D ;D
Title: Re: FreePBX(AsteriskNow) transfer
Post by: moa on November 19, 2010, 20:04:57
This sounds a bit like Frankenstein Jr. :-) but.... chapeau!

Does this mean that my forum member status can change from "Newbie" to "Frankenstein Jr." ?
Title: Re: FreePBX(AsteriskNow) transfer
Post by: QueueMetrics on November 22, 2010, 12:35:54
I can just add some karma to your profile. You'll have to provide your own Frau Blücher....  ;D
Title: Re: FreePBX(AsteriskNow) transfer
Post by: bhenry on November 22, 2010, 17:30:36
Just to note, I believe I fixed my issue as well.  I am passing device state with queuemetrics login context.  So it looks something like this:


; extension 25: agent addqueuemember (for asterisk v1.4+)
exten => 25,1,Answer
exten => 25,2,NoOp( "QM: AddQueueMember (asterisk v1.4+) Agent/${AGENTCODE} on queue ${QUEUENAME} made by '${QM_LOGIN}'" )
exten => 25,3,Macro(queuelog,${EPOCH},${UNIQUEID},NONE,Agent/${AGENTCODE},HOTDESK,SIP/${AGENTCODE}@pbx01)
exten => 25,4,AddQueueMember(${QUEUENAME},Local/${AGENTCODE}@from-queue/n,,,SIP/${AGENTCODE}@pbx01)
exten => 25,5,Hangup

This fixed my issue with transfers not being shown in queue_log and also fixes the device state issue of agents remaining in use after a transfer.  I have not put it into production yet but in the labs it is working succesfully.
Title: Re: FreePBX(AsteriskNow) transfer
Post by: QueueMetrics on November 23, 2010, 16:58:54
Applause! :)
Title: Re: FreePBX(AsteriskNow) transfer
Post by: trymes on October 15, 2012, 15:32:51
I am now struggling with this exact problem. As you all have pointed out, it's a side-effect of the fact that FreePBX uses local channels for the queues, which is generally a Good Thing®. However, I am a little uncomfortable with just deleting the "COMPLETEDAGENT" entry from the queue_log, as it leaves a portion of the call leg "lost", and if the call was transferred to another agent, wouldn't you like to be able to see that call and report on it?

I wonder if it wouldn't make sense to modify the way this is currently being done. When we add the "TRANSFER" line, we create the problem that one call has two termination reasons. There are two ways to resolve this:

1.) Delete the second termination reason.
2.) Add entries that "begin" a second call that will be terminated by the eventual "COMPLETEDAGENT" entry.

Your original solution implements #1, but I think it might be better and simpler to implement #2. This would eliminate the cron job and also have the side benefit of allowing us to see the transferred portion of the call and report on it. If the transfer was to another agent, the agent's information could be used, and if it was transferred to an outside person, it could be shown as a call to an agent named "Outside Number" or similar.

Thoughts?

Tom