AgentCallBackLogin Alternative
Compared to my other articles, this one is a bit more indepth. I’m sorry for that. I just finally found a workaround to a world of pain. If you are a user of the AgentCallBackLogin dialplan application, then you are probably aware that it’s set to be depreciated come version 1.6 of Asterisk. This is a major shame, as it’s a useful application especially to call centers. The guys are Digium said that everything can be done from the dialplan. And while that is true, they fail to give us any “guidance” in getting this setup. There was a doc located in /doc/queues-with-callback-members.txt – But in order to use this guide, you basically have to move to a new way of writing your extensions, that is via extensions.ael. AEL is great, and makes things easy to keep organized. But let’s face it, we hate too much change at once. So I’ve done ALOT of research into the alternative for AgentCallBackLogin, and how to do it, with very little pain.
The major advantage of AgentCallBackLogin, is that each agent logs in to the system, set what phone they are sitting at, and start receiving calls from the queue. My method makes use of AstDB, the voicemail.conf and a few dialplan applications. I make use of the voicemail.conf to setup each agent, and with a PIN or password. So here’s my voicemail.conf:
[agent]
1050 => 1234,Robert,agents@hostseries.com,attach=yes|saycid=yes|envelope=yes|delete=yes|nextaftercmd=no
Within my extensions.conf I created the agent login and logout script and call back:
[internal]
exten => 701,1,VMAuthenticate(@agent|)
exten => 701,n,AddQueueMember(SALES|local/${AUTH_MAILBOX}@agents/n)
exten => 701,n,AddQueueMember(SUPPORT|local/${AUTH_MAILBOX}@agents/n)
exten => 701,n,Read(AGENT_SIP|agent-newlocation)
exten => 701,n,Set(DB(agent_sip/${AUTH_MAILBOX})=${AGENT_SIP})
exten => 701,n,Playback(agent-loginok)
exten => 701,n,Playback(goodbye)
exten => 701,n,Hangup
exten => 702,1,VMAuthenticate(@agent|)
exten => 702,n,RemoveQueueMember(SALES|local/${AUTH_MAILBOX}@agents/n)
exten => 702,n,RemoveQueueMember(SUPPORT|local/${AUTH_MAILBOX}@agents/n)
exten => 702,n,Set(oldvar=${DB_DELETE(agent_sip/${AUTH_MAILBOX})})
exten => 702,n,Playback(agent-loggedoff)
exten => 702,n,Playback(goodbye)
exten => 702,n,Hangup
[agents]
exten => 1050,1,Set(AGENT_SIP=${DB(agent_sip/1050)})
exten => 1050,n,Dial(SIP/${AGENT_SIP})
Extension 701 is what logs the agent in. VMAuthenticate prompts them for their agent number, and then their PIN or password, which is from the voicemail.conf. Then they are added to the Queue, with the callback being an extension within another context (local/1050@agents/n). We then READ the new “location”, which we enter into the AstDB for agent 1050. You will notice when the queue dials 1050@agents it pulls the data from AstDB, to know which SIP extension the agent is sitting at. Extension 702 is how the agent logs out of course. It will remove the agent from the Queues, and delete the AstDB entry.
So there we have it, a seemingly easy AgentCallBackLogin Alternative. Why couldn’t the guys at Digium give us some enlightenment on this? Or why couldn’t they make a replacement for AgentCallBackLogin? We’ll never know. Maybe we’ll see something in the future. In the meantime, I hope I created something that is useful.

How difficult specially for the beginner………………
Hi John,
I actually think you will find it rather easy. All you have to do it copy and past my extensions.conf and voicemail.conf entries into yours.
Your extension mentioned in the voicemail.conf will need to be created in the [agents] context within your extensions.conf so it can ring that extension.
Voicemail.conf is used strictly for the password and login authentication when dialing “701″ from your phone.
How about the queue.conf file what is my configuration
Hi John,
That’s a good question. For your queues.conf you would only setup your standard queue settings. There’s no need to add any members or agents. However, because of recent changed with Asterisk 1.4, new callers can’t join the queue if there’s no agents present, so I add a “SIP Member” (even though there’s no device registered to that extension) and add it as a static member. This will allow callers to join the queue, even if none of my “agents” are logged in. See my example below:
In the example above, the queue context is “SALES” … You will notice with the login extension you set which queue the agent is logged into. Here’s the line that was created to log the agent into the above example queue:
It can seem confusing. It might be good to have a basic knowledge of how asterisk configuration files are laid out, and some basic understanding of the different options with the Asterisk Commands.
ok thank you very much I will Bookmark your blog…………
You sir, are a genius!
Thanks for posting this; I’m currently setting up Asterisk in production for the first time and using the “AgentCallbackLogin() feature that I know will be deprecated in the future. For my next site (800 users, DUNDi cluster – I hope), I will give this plan a try and see how it goes. Thanks!
Hi All,
To keep the Asterisk CLi clear from ‘busy’ phone returns, you can add the following to your queues.conf:
It will help with that. Enjoy!
To make management of the voicemail.conf agents easier, you can port voicemail.conf to MySQL, using Asterisk Realtime. Check out my article on Asterisk Realtime here: http://hostseries.com/asterisk-realtime-installation-guide/
In addition, you can make your login script authenticate against MySQL instead of voicemail.conf. I’ll see about writing a script up for this shortly.
[...] a previous article, I showed an alternative method of AgentCallBackLogin. In that example, the agents were [...]
how is the queue itself dial. Or how do you get customers into the queue?
Michael,
To get the customers in the queue, you set that up in your dialplan.
Let’s say for example, you incoming phone number or DID is: 18001231234 …
I might have a section in my extensions.conf like this:
Let me know if you have anymore questions.
Thanks – cool stuff. Can I just add a penalty to the AddQueueMember(SALES|local/${AUTH_MAILBOX}@agents/n) line such as
AddQueueMember(SALES|local/${AUTH_MAILBOX}@agents/n|2)
which would, I hope, add the queue member with a penalty of 2 ?
Hi,
You can add the penalty into the AddQueueMember command, just as you mentioned. That will work just fine.
Thanks a lot for this!
My only question is, seems like your AQM routine will add that agent to both the SALES and SUPPORT queues. Is that right?
Keeping that in mind, if I want Bob Smith to log in to SALES only, and Jane Smith to login to SUPPORT only, I’ll have to create different login extensions logging into specific queues. Correct?
Also, how would agents.conf look in there?
Thanks! I’m RSSing you.
Thanks for the comment Mark.
You are correct. You would need another extension to make this work. This
is just a very basic, simple example. You could easily use a database to
note which queues an agent is assigned to. Then when the agent logins,
there’s a query to the database to add him to those queues.
You might want to do a search for: ‘asterisk func_odbc’
This would be a good place to start, for making multi queries, etc within
Asterisk. I haven’t used func_odbc much. Perhaps I can play around with it
more, and post some example works soon.
Another way to do it is a bit more messy, but you could have a bunch of
‘gotoif’ statements in your dialplan. This would allow you say ‘if agent
id = 1000′ login to these queues. And ‘if agent id = 1500′ login to these
queues. Of course, the more agents and queues that you have, the longer
and messier the dialplan will be.
Thanks for the response!
Alright that’s great. The only thing is, you know how you don’t like to use AEL because well, it’s change.. I hate doing anything that’d have to use an external component. Someone pointed me to func_odbc as well, but I thought it’s way too complicated to do something so simple.
Asterisk has gone from being simple to really complicated to do one thing. Back in the day, one application handled something.. but now, to do the same, you need to have 4-5 exten lines, and a lot of dialplan hacking. I don’t know how they are going to become market leaders this way.
Mark, I understand your frustration with the Asterisk community making things increasingly complex. However, that’s the direction that it must go in, in order to deliver the features that people want.
Yes before there was a single Application to do a task. But that single Application limited what you could do. By depreciating it and providing alternative ways of doing something, you open yourself up to a whole new world.
Personally, I appreciate that some applications have been depreciated. At first I was mad. But now I feel more connected to Asterisk and the community. I can share my ideas, and my way of doing something. Perhaps I’ve done it better than before, or someone else has improved that I’ve done. That’s the whole purpose of opensource. And while it might not be ‘marketable’ I think Asterisk will continue to take more market share, because of the flexibility that you gain with being opensource.
[...] (I’m assuming that you have your agents context created based on my article discussed here.) We also have a ‘remote’ context which is what makes the connection to ServerB if we [...]
[...] ??:http://hostseries.com/agentcallbacklogin-alternative/ [...]
In the above approach is there a way I can see which agents are logged in?
The “show agents” command does not refelect the login status.
Also what about the events like Agentcallbacklogin event and Agentcallbacklogoff event.
We use these events to generate reports on when the agent logged in and logged off.
You can use ’show queue’ to see which agents are logged into which queue.
In terms of finding out when the agent logins and logs out, you can simply add a couple of lines to your dialplan, to insert to a database the times the agent logged in or out. For example, here’s what you could create for logging the login/logout actions to a database.
Database Structure:
Dialplan additions:
I\’m unable to authenticate to with the VMAuthenticate command. The only thing I can think of is that I\’m using the voicemail configuration from within a mysql database. Is there a seperate command or something that I need make this form of authentication work?
Great writeup otherwise!
-Erik
Silly me I had the wrong authentication context defined in the VMAuthenticate() command. Thanks for the great writeup
Great to hear Erik.
Very useful stuff! Now I do have a question
After an “Agent” has logged in, and they make an outbound call, is there a way (easy one preferably!) to have Asterisk use the “Agent” Number as the source for the CDR?
Also, is there a way of getting VMAuthenticate to play different audio prompts? (I’ve still got the “Comedian Mail” prompts!)
Think I’ll bookmark your blog for future reference!
Thanks & Regards
Hi there, Me again!
I was looking at the login/out MySQL entry, for some strange reason it isn’t actually updating (or Inserting) the data into the table…
I’m reasonably sure I’ve created the table correctly, it just doesn’t seem to update the table…
Any ideas?
Hi Paul,
Sorry for the delay.
The important thing to remember when using MYSQL queries within your dialplan is that you have to make sure you have the same number of columns in the dialplan as the table has. You have to still mention all columns in your dialplan, even if it’s blank. Otherwise, it won’t insert the data.
By the way, you can using find the error from the Asterisk CLi.
Hi Paul,
This system is for allowing agents to login and logout of the queue and receive calls. To force the “Agent” Number as the source for the CDR on outbound calls – I’m not sure that’s easily possible. However, for outbound calls, you can always write your outbound dialplans to input that details for the outbound call to a database. I like the CDR, but there’s alot of data that I would like to have that isn’t there. Here’s a quick outbound dialplan:
The above example is very rough. Consider the key elements:
1) Agent Authentication on all outbound calls. It’s requiring the same details that the agent enters when they login to the phones. This is added protection to prevent people from abusing the outbound service. At the sametime, you can capture the “Agent Number”.
2) Dialplan collects a start time of the call, and end time of the call. It also collects the phone number the Agent dialed.
3) All information is saved to a database. You can easily query that database for calls made by a certain agent, made during a certain time period, etc.
I hope that helps. Again, it’s very rough.
To get VMAuthenticate to play different audio prompts you can record the following file:
/var/lib/asterisk/sounds/vm-login.alaw (or .gsm)
And there are other vm-* sounds as well. You might want to record those to change behaviors. However, if you are overwriting these files, please keep in mind that if you upgrade Asterisk, it will overwrite these.
The above option will change the behavior or audio for the voicemail application. If you don’t want to do that, another option is simply not playing “Comedian Mail.” You can disable this within the VMAuthenticate application. The option is: ’s’ ….. so:
You might want to play your custom prompt for agent ID before that:
I hope all of this helps.
[...] it is… basically you have agents (whether you are using AgentCallBackLogin, or a setup like my alternative.) The problem was that if the Agent transferred the call to another agent, Asterisk qould still [...]
Running asterisk 1.4.24
This approach to working around AgentCallbackLogin has one very serious issue: AgentCallbackLogin not only handles the agent login functionality but includes the needed code to detect the device state. Therefore when you remove it from the equation, you can add members to the queue and use alternatives [whether a VM workaround or a robust database solution] only to find that the extensions on the queue always show up \”not in use\” even when agents are talking on them. This has profound consequences since the queue sees all extensions as available and only when it rings the extension does it realize the queue is busy. From the agents point of view, this generally means that while they are talking to a customer, the \”second line\” on the phone is ringing all the time with new calls. From the system point of view, it is wasting huge amounts of time and resources ringing extensions that it should know are already in use.
I have found that the best workaround using a database lookup for agent authentication is to then perform the AddQueueMember and then follow that with a call to AgentCallBackLogin with a dummy agent but the correct extension. This then allows the extension to be accurately montored for its device state, stopping the \”second line ring\” and wasted motion by the queue itself.
Hi Jacques,
You’re incorrect in your statement. The “\n” at the end of the Local extension causes the agent to report to the queue as busy or ‘in use’ when it’s on a call. Yes, you will still get the error that the agent was ‘not in use’ – but it quickly will report them as busy. However, this causes other issues. For example, with the “\n” at the end, the caller can’t do an attended transfer. Blind transfers work just fine. Even so, with v1.6.x (and via a backport in 1.4.x) there is a state_interface that will allow you to bypass this. I’ve explained the state_interface here: http://hostseries.com/solvingtransferring-calls-from-queues-agents-stay-busy/ — However I have had some issues with getting it to function 100% of the time on v1.4.26.x
I’m glad that you have found a solution that works for you. However, you’re solution still has one major problem. You are still using AgentCallBackLogin, which has been removed in v1.6.x, so you are only causing yourself more headache down the road when you go to upgrade.
I hope that helps.